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);
}
}
//欢迎提出宝贵意见




浙公网安备 33010602011771号