项目中总会遇到这样蛋疼的事情,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使用我这里就不多说了,不是很难懂。