android 扁平风格按钮以及弹出窗口(popupwindow)来模拟标准下拉窗口(spinner)

最近项目需要做一个扁平风格的下拉框,并且在下拉框按钮的最右边添加一个最新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漂亮和炫酷的代价,现在人对于手机界面的要求就像穿衣一样追求时尚个性。


水平有限,欢迎批评指正交流


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值