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