zoukankan      html  css  js  c++  java
  • 【Android开发:自定义控件系列一】仿android4.0 Spinner下拉效果

        1.自定义控件需求

        自从android4.0发布后,android的桌面效果进一步得到增强以及美化,增加了动画特效,可是这仅仅用于android4.0以上的版本,
    对于很多停留在android2.3或者更低的版本时,很多只有感叹。
        为了获得更好的用户体验,很多软件产品在设计时,已经考虑到在android4.0以下版本加入android4.0以上版本的特效,那么
    自定义控件来达到效果。

        2.效果展示

     3.技术点

       1.自定义控件spinner包含Button和PopupWindow控件;

       2.当点击Button时,展示PopupWindow控件;

       3.点击PopupWindow的布局控件时,隐藏,并设置Button;

    4.代码展示

      1.主界面

     

     1 public class MainActivity extends Activity {
     2 
     3     private SpinnerButton mSpinnerBtn;
     4 
     5     @Override
     6     public void onCreate(Bundle savedInstanceState) {
     7         super.onCreate(savedInstanceState);
     8         setContentView(R.layout.main);
     9 
    10         this.mSpinnerBtn = (SpinnerButton) this
    11                 .findViewById(R.id.spinner_btn);
    12         
    13         // 设置下拉布局资源文件,布局创建监听器,以便实例化控件对象
    14         mSpinnerBtn.setResIdAndViewCreatedListener(R.layout.spinner_dropdown_items,
    15                 new SpinnerButton.ViewCreatedListener(){
    16                     @Override
    17                     public void onViewCreated(View v) {
    18                 
    19                         // TODO Auto-generated method stub
    20                         v.findViewById(R.id.textView1).setOnClickListener(new View.OnClickListener() {
    21                             @Override
    22                             public void onClick(View v) {
    23                                 // TODO Auto-generated method stub
    24                                 handleClick(((TextView)v).getText().toString());
    25                             }
    26                         });
    27                         v.findViewById(R.id.textView2).setOnClickListener(new View.OnClickListener() {
    28                             @Override
    29                             public void onClick(View v) {
    30                                 // TODO Auto-generated method stub
    31                                 handleClick(((TextView)v).getText().toString());
    32                             }
    33                         });
    34                         v.findViewById(R.id.textView3).setOnClickListener(new View.OnClickListener() {
    35                             @Override
    36                             public void onClick(View v) {
    37                                 // TODO Auto-generated method stub
    38                                 handleClick(((TextView)v).getText().toString());
    39                             }
    40                         });
    41                         v.findViewById(R.id.textView4).setOnClickListener(new View.OnClickListener() {
    42                             @Override
    43                             public void onClick(View v) {
    44                                 // TODO Auto-generated method stub
    45                                 handleClick(((TextView)v).getText().toString());
    46                             }
    47                         });
    48                     }
    49             
    50         });
    51     }
    52     
    53     private void handleClick(String text){
    54         mSpinnerBtn.dismiss();
    55         mSpinnerBtn.setText(text);
    56     }
    57 }

      2.自定义控件Spinner

        

      1 /**
      2  * @ClassName SpinnerButton
      3  * @Description TODO 防android4.0 Spinner下拉效果
      4  * @author kenny
      5  * @date 2012-8-14
      6  */
      7 public class SpinnerButton extends Button {
      8     
      9     private Context mContext;
     10     /** 下拉PopupWindow */
     11     private UMSpinnerDropDownItems mPopupWindow;
     12     /** 下拉布局文件ResourceId */
     13     private int mResId;
     14     /** 下拉布局文件创建监听器 */
     15     private ViewCreatedListener mViewCreatedListener;
     16 
     17     public SpinnerButton(Context context, AttributeSet attrs, int defStyle) {
     18         super(context, attrs, defStyle);
     19         initButton(context);
     20     }
     21 
     22     public SpinnerButton(Context context, AttributeSet attrs) {
     23         super(context, attrs);
     24         initButton(context);
     25     }
     26     public SpinnerButton(Context context, final int resourceId,
     27             ViewCreatedListener mViewCreatedListener) {
     28         super(context);
     29         setResIdAndViewCreatedListener(resourceId, mViewCreatedListener);
     30         initButton(context);
     31     }
     32 
     33     private void initButton(Context context) {
     34         this.mContext = context;
     35         // UMSpinnerButton监听事件
     36         setOnClickListener(new UMSpinnerButtonOnClickListener());
     37     }
     38 
     39     public PopupWindow getPopupWindow() {
     40         return mPopupWindow;
     41     }
     42 
     43     public void setPopupWindow(UMSpinnerDropDownItems mPopupWindow) {
     44         this.mPopupWindow = mPopupWindow;
     45     }
     46 
     47     public int getResId() {
     48         return mResId;
     49     }
     50     /**
     51      * @Description: TODO   隐藏下拉布局
     52      */
     53     public void dismiss(){
     54         mPopupWindow.dismiss();
     55     }
     56     /**
     57      * @Description: TODO  设置下拉布局文件,及布局文件创建监听器
     58      * @param @param mResId 下拉布局文件ID
     59      * @param @param mViewCreatedListener  布局文件创建监听器
     60      */
     61     public void setResIdAndViewCreatedListener(int mResId, ViewCreatedListener mViewCreatedListener) {
     62         this.mViewCreatedListener = mViewCreatedListener;
     63         // 下拉布局文件id
     64         this.mResId = mResId;
     65         // 初始化PopupWindow
     66         mPopupWindow = new UMSpinnerDropDownItems(mContext);
     67     }
     68 
     69     /**
     70      * UMSpinnerButton的点击事件
     71      */
     72     class UMSpinnerButtonOnClickListener implements View.OnClickListener {
     73 
     74         @Override
     75         public void onClick(View v) {
     76             if (mPopupWindow != null) {
     77                 if (!mPopupWindow.isShowing()) {
     78                     // 设置PopupWindow弹出,退出样式
     79                     mPopupWindow.setAnimationStyle(R.style.Animation_dropdown);
     80                     // 计算popupWindow下拉x轴的位置
     81                     int lx = (SpinnerButton.this.getWidth()
     82                             - mPopupWindow.getmViewWidth() - 7) / 2;
     83                     // showPopupWindow
     84                     mPopupWindow.showAsDropDown(SpinnerButton.this, lx, -5);
     85                 }
     86             }
     87         }
     88     }
     89 
     90     /**
     91      * @ClassName UMSpinnerDropDownItems
     92      * @Description TODO 下拉界面
     93      * @author kenny
     94      * @date 2012-8-14
     95      */
     96     public class UMSpinnerDropDownItems extends PopupWindow {
     97 
     98         private Context mContext;
     99         /** 下拉视图的宽度 */
    100         private int mViewWidth;
    101         /** 下拉视图的高度 */
    102         private int mViewHeight;
    103 
    104         public UMSpinnerDropDownItems(Context context) {
    105             super(context);
    106             this.mContext = context;
    107             loadViews();
    108         }
    109 
    110         /**
    111          * @Description: TODO 加载布局文件
    112          * @param
    113          * @return void
    114          * @throws
    115          */
    116         private void loadViews() {
    117             // 布局加载器加载布局文件
    118             LayoutInflater inflater = LayoutInflater.from(mContext);
    119             final View v = inflater.inflate(mResId, null);
    120             // 计算view宽高
    121             onMeasured(v);
    122 
    123             // 必须设置
    124             setWidth(LayoutParams.WRAP_CONTENT);
    125             setHeight(LayoutParams.WRAP_CONTENT);
    126             setContentView(v);
    127             setFocusable(true);
    128             
    129             // 设置布局创建监听器,以便在实例化布局控件对象
    130             if (mViewCreatedListener != null) {
    131                 mViewCreatedListener.onViewCreated(v);
    132             }
    133         }
    134 
    135         /**
    136          * @Description: TODO 计算View长宽
    137          * @param @param v
    138          */
    139         private void onMeasured(View v) {
    140             int w = View.MeasureSpec.makeMeasureSpec(0,
    141                     View.MeasureSpec.UNSPECIFIED);
    142             int h = View.MeasureSpec.makeMeasureSpec(0,
    143                     View.MeasureSpec.UNSPECIFIED);
    144             v.measure(w, h);
    145             mViewWidth = v.getMeasuredWidth();
    146             mViewHeight = v.getMeasuredHeight();
    147         }
    148 
    149         public int getmViewWidth() {
    150             return mViewWidth;
    151         }
    152 
    153         public void setmViewWidth(int mViewWidth) {
    154             this.mViewWidth = mViewWidth;
    155         }
    156 
    157         public int getmViewHeight() {
    158             return mViewHeight;
    159         }
    160 
    161         public void setmViewHeight(int mViewHeight) {
    162             this.mViewHeight = mViewHeight;
    163         }
    164 
    165     }
    166     /**
    167      * @ClassName ViewCreatedListener  
    168      * @Description TODO  布局创建监听器,实例化布局控件对象
    169      * @author kenny  
    170      * @date 2012-8-15
    171      */
    172     public interface ViewCreatedListener {
    173         void onViewCreated(View v);
    174     }
    175 }

    注意:在public UMSpinnerDropDownItems(Context context)构造函数里,不能继承super(context);否则会出现下拉框黑边的情况;

    由于时间关系,其他代码就不一一贴出来了,要的话直接去下载工程 源代码下载

    转载请注明出处:http://www.cnblogs.com/hpboy

  • 相关阅读:
    luogu 2478 [SDOI2010]城市规划 仙人掌上dp.
    bzoj 3782 上学路线 卢卡斯定理 容斥 中国剩余定理 dp
    bzoj 3790 神奇项链 回文串 manacher|PAM
    4.4 相交弧 容斥 平衡规划 二维数点
    4.4 省选模拟赛 拉格朗日计数 树状数组+容斥.
    4.4 省选模拟赛 修路 斯坦纳树
    带修改线性基
    CF R 630 div2 1332 F Independent Set
    4.3 省选模拟赛 石子游戏 树上博弈
    机器C盘临时区
  • 原文地址:https://www.cnblogs.com/hpboy/p/2639822.html
Copyright © 2011-2022 走看看