利用PopupWindow做出仿IOS樣式的選擇器
阿新 • • 發佈:2019-01-01
專案中總會遇到這樣蛋疼的事情,android和ios同樣的功能,都用的同樣自帶的控制元件,做出來的效果就是:android的醜的不行,ios的挺好看。於是,老大一拍屁股,android的改成和ios樣式的一樣就好了。然後,android開發就苦比了,憑空多出若干工作量。好了,話不多說,直接上程式碼吧。下面是我專案遇到的一個仿ios選擇器的一個task,我邊貼程式碼邊說吧。
首先,看下這個選擇器的佈局檔案。
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:orientation="vertical" > <LinearLayout android:id="@+id/pop_layout" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:background="#ffffff" android:gravity="center_horizontal" android:orientation="vertical" > <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content" > <Button android:id="@+id/cancle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@null" android:text="@string/cancel" android:textColor="#999999" /> <Button android:id="@+id/ok" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:background="@null" android:text="@string/ok" android:textColor="@color/TextLightGreen" /> </RelativeLayout> <TextView android:layout_width="fill_parent" android:layout_height="1dp" android:background="#999999" /> <ScrollView android:layout_width="fill_parent" android:layout_height="120dp" > <RadioGroup android:id="@+id/until" android:layout_width="fill_parent" android:layout_height="match_parent" android:orientation="vertical" > </RadioGroup> </ScrollView> </LinearLayout> </RelativeLayout>
可以看出,這要就是由兩個按鈕還有一個RadioGroup組成,這個RadioGRoup上面套了一層ScrollView,這個ScrollView是固定高度的,不難看出,選擇器的選擇項就會由RadioGroup中的RadioButton去實現,RadioButton會在程式碼中動態的去載入。
下面看我我們自定義的PopupWindow的程式碼
public class UnitPopupWindow extends PopupWindow { private Button btn_cancle, btn_ok; private RadioGroup unit; private View mMenuView; private Context context; private RadioButton button; private ColorStateList csl; private boolean statusFlag = true; @SuppressLint("ResourceAsColor") public UnitPopupWindow(Activity context, OnClickListener itemsOnClick, OnCheckedChangeListener checkedChangeListener, ArrayList<String> dataList) { super(context); this.context = context; LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); mMenuView = inflater.inflate(R.layout.alert_dialogs, null); btn_cancle = (Button) mMenuView.findViewById(R.id.cancle); btn_ok = (Button) mMenuView.findViewById(R.id.ok); unit = (RadioGroup) mMenuView.findViewById(R.id.until); for (int i = 0; i < dataList.size(); i++) { button = new RadioButton(context); button.setButtonDrawable(null); button.setText(dataList.get(i)); button.setId(i); button.setTextSize(25); button.setGravity(Gravity.CENTER); button.setHeight(90); button.setButtonDrawable(android.R.color.transparent); button.setPadding(0, 0, 0, 0); csl = context.getResources() .getColorStateList(R.drawable.utilcolor); button.setTextColor(csl); WindowManager wm1 = context.getWindowManager(); button.setWidth(wm1.getDefaultDisplay().getWidth()); button.setFocusable(true); unit.addView(button); } // 取消按鈕 btn_cancle.setOnClickListener(itemsOnClick); // 設定按鈕監聽 unit.setOnCheckedChangeListener(checkedChangeListener); btn_ok.setOnClickListener(itemsOnClick); // 設定SelectPicPopupWindow的View this.setContentView(mMenuView); // 設定SelectPicPopupWindow彈出窗體的寬 this.setWidth(LayoutParams.MATCH_PARENT); // 設定SelectPicPopupWindow彈出窗體的高 this.setHeight(LayoutParams.MATCH_PARENT); // 設定SelectPicPopupWindow彈出窗體可點選 this.setFocusable(true); // 設定SelectPicPopupWindow彈出窗體動畫效果 this.setAnimationStyle(R.style.AnimBottom); ColorDrawable dw = new ColorDrawable(0x00000000); // 設定SelectPicPopupWindow彈出窗體的背景 this.setBackgroundDrawable(dw); // mMenuView新增OnTouchListener監聽判斷獲取觸屏位置如果在選擇框外面則銷燬彈出框 mMenuView.setOnTouchListener(new OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { int height = mMenuView.findViewById(R.id.pop_layout).getTop(); int y = (int) event.getY(); if (event.getAction() == MotionEvent.ACTION_UP) { if (y < height) { backgroundAlpha(1f); dismiss(); } } return true; } }); } public RadioGroup getUnit() { return unit; } public void setStatus(boolean status) { statusFlag = status; unit.postInvalidate(); } private void backgroundAlpha(float bgAlpha) { WindowManager.LayoutParams lp = ((Activity) context).getWindow() .getAttributes(); lp.alpha = bgAlpha; // 0.0-1.0 ((Activity) context).getWindow().setAttributes(lp); } }
注意下里面的兩個監聽事件
OnClickListener:這是監聽確認和取消兩個button的監聽事件
OnCheckedChangeListener:這是監聽RadioButton選中狀態的監聽事件
順便貼下這個選擇器彈出時的動畫效果程式碼,上面程式碼中有設定過這樣的屬性,自己查詢。
<style name="AnimBottom" parent="@android:style/Animation"> <item name="android:windowEnterAnimation">@anim/push_bottom_in</item> <item name="android:windowExitAnimation">@anim/push_bottom_out</item> </style>
<?xml version="1.0" encoding="utf-8"?>
<!-- 上下滑入式 -->
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="200"
android:fromYDelta="100%p"
android:toYDelta="0" />
<alpha
android:duration="100"
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="200"
android:fromYDelta="0"
android:toYDelta="50%p" />
<alpha
android:duration="100"
android:fromAlpha="1.0"
android:toAlpha="0.0" />
</set>
最後就到我們的呼叫了。假設使用者在點選了一個button後會彈出一個單位切換的選擇器,可以在這個button的OnClick事件中做這樣的處理,直接上程式碼
<pre name="code" class="java"> ArrayList mDataList = new ArrayList<String>();
//增加選擇內容的item
mDataList.add("km");
mDataList.add("mile");
menuWindow = new UnitPopupWindow(this, itemsOnClick,checkedChangeListener,mDataList);
menuWindow.setOnDismissListener(new OnDismissListener() {
@Override
public void onDismiss() {
backgroundAlpha(1f);
}
});
menuWindow.showAtLocation(this.findViewById(R.id.main), Gravity.RIGHT|Gravity.BOTTOM, 0, 0);
backgroundAlpha(0.5f);
private OnClickListener itemsOnClick = new OnClickListener(){
public void onClick(View v) {
menuWindow.dismiss();
switch (v.getId()) {
case R.id.ok:
//點選確認的需要做的操作
break;
default:
break;
}
}
};
private OnCheckedChangeListener checkedChangeListener = new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case 0:
mUtil = getString(R.string.km_txt);
mUtilString = "KM";
break;
case 1:
mUtil = getString(R.string.mile);
mUtilString = "Mile";
break;
default:
break;
}
}
};
以上就是仿ios選擇器的全部內容了,關於PopupWindow的一些基本api使用我這裡就不多說了,不是很難懂。