先上效果圖:
這個工程並不難,但是零碎的知識點還是挺多的,下面來講講思路:
首先從 NumberPicker 開始:
public class CustomNumberPicker extends NumberPicker {
public CustomNumberPicker(Context context) {
super(context);
}
public CustomNumberPicker(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomNumberPicker(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void addView(View child) {
super.addView(child);
updateView(child);
}
@Override
public void addView(View child, int index, android.view.ViewGroup.LayoutParams params) {
super.addView(child, index, params);
updateView(child);
}
@Override
public void addView(View child, android.view.ViewGroup.LayoutParams params) {
super.addView(child, params);
updateView(child);
}
public void updateView(View view) {
if (view instanceof EditText) {
// 文字顏色、大小
((EditText) view).setTextColor(ContextCompat.getColor(getContext(), R.color.numberpicker_text));
((EditText) view).setTextSize(20f);
}
}
}
這裏是對原生 NumberPicker 的修改,所以直接繼承 NumberPicker 並獲取它的視圖 view ,並利用 instanceof 篩選出 EditText ,修
改 EditText 的文字顏色和文字大小,即可改變 NumberPicker 文字的顏色和大小。
接下來是修改分割線顏色,這裏先需要對 NumberPicker 進行初始化,然後利用反射獲取到分割線的屬性,再對其修改顏色:
/**
* 初始化滾動框佈局
*/
private void initNumberPicker() {
workingAge_view = LayoutInflater.from(this).inflate(R.layout.popupwindow, null);
submit_workingAge = (Button) workingAge_view.findViewById(R.id.submit_workingAge);
numberPicker = (NumberPicker) workingAge_view.findViewById(R.id.numberPicker);
numberPicker.setMaxValue(50);
numberPicker.setMinValue(0);
numberPicker.setFocusable(false);
numberPicker.setFocusableInTouchMode(false);
numberPicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS); // 關閉編輯模式
setNumberPickerDividerColor(numberPicker);
}
/**
* 自定義滾動框分隔線顏色
*/
private void setNumberPickerDividerColor(NumberPicker number) {
Field[] pickerFields = NumberPicker.class.getDeclaredFields();
for (Field pf : pickerFields) {
if (pf.getName().equals("mSelectionDivider")) {
pf.setAccessible(true);
try {
//設置分割線的顏色值
pf.set(number, new ColorDrawable(ContextCompat.getColor(this, R.color.numberpicker_line)));
} catch (Exception e) {
e.printStackTrace();
}
break;
}
}
}
DatePicker 也可以按照這種方法修改顯示效果,這裏再稍微提一下多個 NumberPicker 的聯動效果的實現思路,比如省市區的選
擇,假設數據來自服務器,在視圖加載的時候,先獲取到省的數據,通過 setDisplayedValues 顯示數據,然後給省設置監聽
setValueChangedListener ,當省的值發生變化時,獲取到當前值並向服務器請求相應省裏面市的數據,獲得返回的市的數據後再加
載市的視圖,接下來區的顯示也是同理。
到這一步,對原生 NumberPicker 的修改就結束了,在這裏我們用到了 PopupWindow 的佈局文件,接下來就開始說一說
PopupWindow 和補間動畫,首先看看佈局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/popupwindow_style"
android:orientation="vertical">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.liuwan.numberpicker.widget.CustomNumberPicker
android:id="@+id/numberPicker"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginStart="15dp"
android:layout_toEndOf="@+id/numberPicker"
android:text="年"
android:textColor="@color/year"
android:textSize="18sp" />
</RelativeLayout>
<Button
android:id="@+id/submit_workingAge"
style="?android:attr/borderlessButtonStyle"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:background="@color/button_background"
android:gravity="center"
android:text="確定"
android:textColor="@color/button_text"
android:textSize="17sp" />
</LinearLayout>
在 PopupWindow 的佈局文件中,我們使用了修改後的 NumberPicker,這裏沒有什麼難點,就不多說了,其中還涉及到一個
PopupWindow 的樣式文件:
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<!-- 設置背景透明度和顏色 -->
<solid android:color="@color/popupwindow_background" />
<!-- 設置圓角 -->
<corners
android:topLeftRadius="5dp"
android:topRightRadius="5dp" />
</shape>
這裏就設置了背景顏色和透明度,以及頂部圓角。
PopupWindow 的佈局到這裏就完成了,接下來是代碼調用,因爲在這裏需要設置補間動畫,所以先說一下補間動畫的編寫。
關於補間動畫,可以參考我的另一篇博文《Android 補間動畫的簡單介紹及使用》,這裏有兩個動畫,一個是彈出動畫:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="400"
android:fromYDelta="100%p"
android:toYDelta="0" />
<alpha
android:duration="400"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
</set>
一個是退出動畫:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="400"
android:fromYDelta="0"
android:toYDelta="50%p" />
<alpha
android:duration="400"
android:fromAlpha="1.0"
android:toAlpha="0.0" />
</set>
在代碼中設置通過點擊相應控件彈出 PopupWindow ,並設置相關屬性:
// 選擇服務年限
edWorkingAge.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 設置初始值
numberPicker.setValue(workingAge);
// 強制隱藏鍵盤
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
// 填充佈局並設置彈出窗體的寬,高
popupWindow = new PopupWindow(workingAge_view,
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
// 設置彈出窗體可點擊
popupWindow.setFocusable(true);
// 設置彈出窗體動畫效果
popupWindow.setAnimationStyle(R.style.AnimBottom);
// 觸屏位置如果在選擇框外面則銷燬彈出框
popupWindow.setOutsideTouchable(true);
// 設置彈出窗體的背景
popupWindow.setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
popupWindow.showAtLocation(workingAge_view,
Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0);
// 設置背景透明度
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.alpha = 0.5f;
getWindow().setAttributes(lp);
// 添加窗口關閉事件
popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
WindowManager.LayoutParams lp = getWindow().getAttributes();
lp.alpha = 1f;
getWindow().setAttributes(lp);
}
});
}
});
這裏對動畫效果的設置是通過 style 屬性控制的,在 res/values/styles.xml 中定義:
<!-- 自定義popupWindow_WorkingAge -->
<style name="AnimBottom" parent="android:Animation">
<item name="android:windowEnterAnimation">@anim/popupwindow_enter_anim</item>
<item name="android:windowExitAnimation">@anim/popupwindow_exit_anim</item>
</style>
到這裏,基本上就完成了想要達到的效果,一些顏色的設置都定義在 colors.xml 文件中。