Android自定义控件,实现iphone的picker效果
效果图如下:
1.不带有图标的
2.带有图标的
主要有两个类:
1.Picker
2.CustomListView
Picker控件的外部接口:
Picker控件的使用方法:
public class Main extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final Picker picker=new Picker(this); ArrayList<String> data = new ArrayList<String>(); ArrayList<Drawable> icons = new ArrayList<Drawable>(); icons.add(getResources().getDrawable(R.drawable.icon1)); icons.add(getResources().getDrawable(R.drawable.icon2)); icons.add(getResources().getDrawable(R.drawable.icon3)); icons.add(getResources().getDrawable(R.drawable.icon1)); icons.add(getResources().getDrawable(R.drawable.icon2)); icons.add(getResources().getDrawable(R.drawable.icon3)); for (int i = 2000; i < 2006; i++) { data.add("" + i); } picker.setPickerData(data); picker.setPickerSize(100, 200); picker.defaultScrollToPos(4); picker.setOnPickerItemSelectedListener(new OnPickerItemSelectedListener() { @Override public void onItemSelected(View view, int pos, String text) { } }); setContentView(picker); } }
Picker控件的核心代码如下:
public class Picker extends LinearLayout implements CustomScrollView.OnScrollOverListener { private ArrayList<String> data; //字符串数据List private ArrayList<Drawable> iconList; //与data相对应的图标List private int headAndFootHeight = 150; private int cellHeight = 50; private Context mContext; private LinearLayout contentLinear; private CustomScrollView scrollview; private TextView selector; private int indicaterOffset; // 选择条的偏移量 private View ipicker; private int width; private int height; private int defaultPos; private ArrayList<View> viewlist = new ArrayList<View>(); // 每一项中的View(可以是他的子类) private boolean isLayoutOnce; // 只是layout一次的标记 private int destPos; public Picker(Context context) { this(context,null); } public Picker(Context context, AttributeSet attrs) { super(context, attrs); this.mContext = context; defaultPos = headAndFootHeight + cellHeight * 1 - indicaterOffset; FrameLayout frameLayout=new FrameLayout(mContext); frameLayout.setBackgroundResource(R.drawable.while_bg); LayoutParams params=new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); frameLayout.setLayoutParams(params); CustomScrollView myScroll=new CustomScrollView(mContext); myScroll.setVerticalFadingEdgeEnabled(false); myScroll.setVerticalScrollBarEnabled(false); LayoutParams params2=new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); myScroll.setLayoutParams(params2); LinearLayout linear=new LinearLayout(mContext); linear.setLayoutParams(params2); linear.setOrientation(LinearLayout.VERTICAL); myScroll.addView(linear); myScroll.setLayoutParams(params2); TextView selector1=new TextView(mContext); selector1.setBackgroundResource(R.drawable.selector_bg); selector1.setLayoutParams(params2); frameLayout.addView(myScroll); FrameLayout.LayoutParams params3=new FrameLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); params3.gravity=Gravity.CENTER_VERTICAL; frameLayout.addView(selector1, params3); scrollview = myScroll; contentLinear = linear; selector =selector1; ipicker=frameLayout; selector.setHeight(cellHeight); // 将所有设置child宽高,位置的代码在onlayout之前调用 addView(ipicker); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(false, l, t, r, b); Log.e("", "onLayout"); if (isLayoutOnce) { return; } isLayoutOnce = true; int top = selector.getTop()-4; //9 patch 图片的问题,经多次调试偏移四个像素最好 indicaterOffset = top; if (defaultPos == 0) { scrollview.scrollTo(0, headAndFootHeight - indicaterOffset); } else { scrollview.smoothScrollTo(0, defaultPos); } this.handler.sendEmptyMessage(destPos); } private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { scrollToPos(destPos); super.handleMessage(msg); } }; private TextView footText; /**Ipicker显示的时候,默认滚动到pos位置*/ public void defaultScrollToPos(int pos) { this.destPos = pos; // flag = true; // defaultPos = headAndFootHeight + cellHeight * pos - indicaterOffset; } /**滚动到Pos位置*/ public void scrollToPos(int pos) { scrollview.smoothScrollTo(0, headAndFootHeight + cellHeight * pos - indicaterOffset); } /**为控件添加数据 * list StringList * */ public void setPickerData(ArrayList<String> list) { this.data = list; prepare(); } /**为控件添加数据 * list StringList * */ public void setPickerData(ArrayList<String> stringlist,ArrayList<Drawable> iconlist) { if(stringlist.size()!=iconlist.size()){ Log.e("error", "!!error!! the length of stringlist and iconlist is not same!!"); return; } this.data = stringlist; this.iconList=iconlist; prepare(); } /** set the size of the picker */ public void setPickerSize(int width, int height) { this.width = width; this.height = height; } /** * prepare picker view ,prepare the ipcker's children (will call onlayout again) * */ private void prepare() { contentLinear.removeAllViews(); LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); if (width == 0 || height == 0) { params.width = 200; params.height = 200; } else { params.width = width; params.height = height; } ipicker.setLayoutParams(params); scrollview.setOnScrollOverListener(this); TextView headText = new TextView(mContext); headText.setHeight(headAndFootHeight); contentLinear.addView(headText); insertData(); footText = new TextView(mContext); footText.setHeight(headAndFootHeight); contentLinear.addView(footText); } private void insertData() { viewlist.clear(); if (data == null || data.size() == 0) { selector.setVisibility(View.GONE); return; } for (int i = 0; i < data.size(); i++) { LinearLayout itemLayout=new LinearLayout(mContext); itemLayout.setGravity(Gravity.CENTER_VERTICAL); itemLayout.setPadding(20, 0, 0, 0); if(iconList!=null){ ImageView image=new ImageView(mContext); image.setBackgroundDrawable(iconList.get(i)); itemLayout.addView(image); } TextView text = new TextView(mContext); text.setHeight(cellHeight); text.setGravity(Gravity.CENTER); text.setTextSize(25); text.setTypeface(Typeface.DEFAULT_BOLD); text.setTextColor(Color.BLACK); itemLayout.addView(text); LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); text.setLayoutParams(params); text.setText(data.get(i)); contentLinear.addView(itemLayout); viewlist.add(itemLayout); } } @Override public void onScrollOver(final int stopy) { final int num = (stopy - headAndFootHeight + indicaterOffset) / cellHeight; if (stopy + indicaterOffset // to triger onItemSelected only one time - (headAndFootHeight + cellHeight * (num)) == 0) { if(listener!=null){ listener.onItemSelected(viewlist.get(num), num, data.get(num)); } } ((Activity) mContext).runOnUiThread(new Runnable() { @Override public void run() { if (stopy + indicaterOffset < headAndFootHeight) { scrollview.smoothScrollTo(0, headAndFootHeight - indicaterOffset); } else if (stopy + indicaterOffset >= headAndFootHeight + cellHeight * num && stopy + indicaterOffset <= headAndFootHeight + cellHeight * (data.size() - 1)) { if (stopy + indicaterOffset - (headAndFootHeight + cellHeight * (num)) <= cellHeight / 2) { // less scrollview.smoothScrollTo(0, headAndFootHeight + cellHeight * num - indicaterOffset); } else { scrollview.smoothScrollTo(0, headAndFootHeight + cellHeight * (num + 1) - indicaterOffset); } } else if (stopy + indicaterOffset > headAndFootHeight + cellHeight * (data.size() - 1)) { scrollview.smoothScrollTo(0, headAndFootHeight + cellHeight * (data.size() - 1) - indicaterOffset); } else { } } }); } private OnPickerItemSelectedListener listener; public void setOnPickerItemSelectedListener( OnPickerItemSelectedListener listener) { this.listener = listener; } interface OnPickerItemSelectedListener { /** * @param view: view of the a specific item (linearLayout) * @param pos:position * @param text:String of the a specific item * */ void onItemSelected(View view, int pos, String text); } }
//欢迎提出宝贵意见