最近项目需要做一个扁平风格的下拉框,并且在下拉框按钮的最右边添加一个最新android风格的斜三角,见下图:
最初直接想到用标准控件下拉框(spinner)来实现这个功能,但后来发现标准下拉框实现需求有很多问题很难完全满足要求,例如android旧版本并不支持这个风格控件,控件文本显示布局的问题等等,后来参考网上例子决定用一个按钮加弹出窗口(popup window)来实现这个功能。
下面是控件按钮的布局文件:
<Button
android:id="@+id/spinnerSize"
android:layout_width="@dimen/btn_size_width"
android:layout_height="@dimen/btn_size_height"
android:layout_marginRight="@dimen/btn_size_margin_right"
android:background="@drawable/btn_background_light"
android:gravity="center_vertical|left"
android:paddingLeft="@dimen/btn_dropbox_padding_left"
android:singleLine="true"
android:textColor="@android:color/black"
android:textSize="15sp" />
其中的btn_background_light定义在drawable下,内容如下:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_enabled="false" android:drawable="@drawable/btn_disabled" />
<item android:state_pressed="true" android:drawable="@drawable/btn_pressed" />
<item android:state_focused="true" android:drawable="@drawable/btn_focused" />
<item android:drawable="@drawable/btn_normal" />
</selector>
很多人对于android布局很感头疼,各种样式、布局风格、参数等等,稍微不小心就会造成意想不到的结果。这个地方也折腾了我很久,总是不能尽善尽美达到扁平风格(上面还有文字和图形三角),最后总算弄了个差不多的。现在明白了一些,但感觉离彻底掌握还有不少距离。
相比复杂的UI,代码就简单很多了:
第一步,建立button的view和点击事件:
private Button btnSizeList = null;
建立弹出窗口
private PopupWindow popupSizeList = null;
private ListView popListView = null;
事件关联:
btnSizeList= (Button)findViewById(R.id.spinnerSize);
btnSizeAdapter = new ArrayAdapter<String>(this.getContext(), R.layout.spinneritemstyle, SizeIntList); //spinneritemstyle就是个textview的布局, SizeIntList是个整形数组
btnSizeList.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
showSizeListPopWindow(v);
}
});
...
最后是弹出窗口实现函数
public void showSizeListPopWindow(View v){
layout = (LinearLayout) LayoutInflater.from(mCtx).inflate(R.layout.spinnerdropdown, null); //spinnerdropdown是一个linearlayout包含一个listview布局
popListView = (ListView) layout.findViewById(R.id.sizelistView); //sizelistView是上面布局的listView控件id, popListView是ListView
popListView.setAdapter(btnSizeAdapter); //btnSizeAdapter在上面onCreate定义
popupSizeList= new PopupWindow(v);
popupSizeList.setWidth(btnSizeList.getWidth());
popupSizeList.setHeight(LayoutParams.WRAP_CONTENT );
popupSizeList.setBackgroundDrawable(new BitmapDrawable());
popupSizeList.setOutsideTouchable(true); //点击窗口外能够取消该弹出窗口
popupSizeList.setFocusable(true);
//下面这句clipping代码视情况而定,如果没设置或者设为true而这个button是由一个对话框中定义,那么这个popup因为会被对话框边界剪切而显示不完整
//如果popup是直接挂在main view中,就没必要设定了,这时设定也是限定到屏幕(screen)边界
popupSizeList.setClippingEnabled(false);
popupSizeList.setContentView(layout);
popupSizeList.showAsDropDown(v, 0, 0); // v 是弹出窗口依附的对象,以此对象左下角为起点算偏移,此处是按钮左下角,偏移x:0, y:0
popListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int pos,
long arg3) {
// TODO Auto-generated method stub
String item = popListView.getItemAtPosition(pos).toString(); //获取选取项及内容
popupSizeList.dismiss();
popupSizeList= null;
}
});
}
至此,一个基于按钮和popup window的模拟spinner控件就做完了,功能上和标准控件也差不多,虽然没有标准控件那么完善,但原理上是一样的。
做了一段时间android应用和framework,也许是不熟悉的原因,感觉做android UI比做代码逻辑要更繁琐,当然这里也有android ui设计的复杂性的原因。当年做MFC的时候也是很折腾,但是远没有android这么折腾,或许这也是android UI漂亮和炫酷的代价,现在人对于手机界面的要求就像穿衣一样追求时尚个性。
水平有限,欢迎批评指正交流