一、定义WheelView

融合网友的杰作,实现滑动选择效果。


二、WheelView的使用

public class MainActivity extends Activity {private Button mainBt;private static final String TAG = MainActivity.class.getSimpleName();private static final String[] PLANETS = new String[] { "赵云", "关羽", "张飞","吕布", "典韦", "马超", "黄忠", "诸葛亮" };@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mainBt = (Button) findViewById(R.id.main_bt);mainBt.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// 构建弹出框ViewView outerView = LayoutInflater.from(MainActivity.this).inflate(R.layout.wheel_view, null);WheelView wv = (WheelView) outerView.findViewById(R.id.wheel_view_wv);// wv.setOffset(0);// 偏移量wv.setOffset(2);wv.setItems(Arrays.asList(PLANETS));// 实际内容wv.setSeletion(0);// 设置默认被选中的项目// wv.setSeletion(3);wv.setOnWheelViewListener(new WheelView.OnWheelViewListener() {@Overridepublic void onSelected(int selectedIndex, String item) {// 选中后的处理事件Log.d(TAG, "[Dialog]selectedIndex: " + selectedIndex+ ", item: " + item);}});// 展示弹出框new AlertDialog.Builder(MainActivity.this).setTitle("WheelView in Dialog").setView(outerView).setPositiveButton("OK", null).show();}});}}
展示最终效果:


三、自定义控件源码【复制可直接使用】

是的,自定义控件源码才是最宝贝的。重走Android路,希望以后的自己,能够构造出来更多炫酷的控件。

public class WheelView extends ScrollView {    public static final String TAG = WheelView.class.getSimpleName();    public static class OnWheelViewListener {        public void onSelected(int selectedIndex, String item) {        }    }    private Context context;    private LinearLayout views;    public WheelView(Context context) {        super(context);        init(context);    }    public WheelView(Context context, AttributeSet attrs) {        super(context, attrs);        init(context);    }    public WheelView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        init(context);    }    List<String> items;    private List<String> getItems() {        return items;    }    public void setItems(List<String> list) {        if (null == items) {            items = new ArrayList<String>();        }        items.clear();        items.addAll(list);        // 前面和后面补全        for (int i = 0; i < offset; i++) {            items.add(0, "");            items.add("");        }        initData();    }    public static final int OFF_SET_DEFAULT = 1;    int offset = OFF_SET_DEFAULT; // 偏移量(需要在最前面和最后面补全)    public int getOffset() {        return offset;    }    public void setOffset(int offset) {        this.offset = offset;    }    int displayItemCount; // 每页显示的数量    int selectedIndex = 1;    private void init(Context context) {        this.context = context;        Log.d(TAG, "parent: " + this.getParent());        this.setVerticalScrollBarEnabled(false);        views = new LinearLayout(context);        views.setOrientation(LinearLayout.VERTICAL);        this.addView(views);        scrollerTask = new Runnable() {            public void run() {                int newY = getScrollY();                if (initialY - newY == 0) { // stopped                    final int remainder = initialY % itemHeight;                    final int divided = initialY / itemHeight;                    if (remainder == 0) {                        selectedIndex = divided + offset;                        onSeletedCallBack();                    } else {                        if (remainder > itemHeight / 2) {                            WheelView.this.post(new Runnable() {                                @Override                                public void run() {                                    WheelView.this.smoothScrollTo(0, initialY - remainder + itemHeight);                                    selectedIndex = divided + offset + 1;                                    onSeletedCallBack();                                }                            });                        } else {                            WheelView.this.post(new Runnable() {                                @Override                                public void run() {                                    WheelView.this.smoothScrollTo(0, initialY - remainder);                                    selectedIndex = divided + offset;                                    onSeletedCallBack();                                }                            });                        }                    }                } else {                    initialY = getScrollY();                    WheelView.this.postDelayed(scrollerTask, newCheck);                }            }        };    }    int initialY;    Runnable scrollerTask;    int newCheck = 50;    public void startScrollerTask() {        initialY = getScrollY();        this.postDelayed(scrollerTask, newCheck);    }    private void initData() {        displayItemCount = offset * 2 + 1;        for (String item : items) {            views.addView(createView(item));        }        refreshItemView(0);    }    int itemHeight = 0;    private TextView createView(String item) {        TextView tv = new TextView(context);        tv.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));        tv.setSingleLine(true);        tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);        tv.setText(item);        tv.setGravity(Gravity.CENTER);        int padding = dip2px(15);        tv.setPadding(padding, padding, padding, padding);        if (0 == itemHeight) {            itemHeight = getViewMeasuredHeight(tv);            Log.d(TAG, "itemHeight: " + itemHeight);            views.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, itemHeight * displayItemCount));            LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) this.getLayoutParams();            this.setLayoutParams(new LinearLayout.LayoutParams(lp.width, itemHeight * displayItemCount));        }        return tv;    }    @Override    protected void onScrollChanged(int l, int t, int oldl, int oldt) {        super.onScrollChanged(l, t, oldl, oldt);        refreshItemView(t);        if (t > oldt) {            scrollDirection = SCROLL_DIRECTION_DOWN;        } else {            scrollDirection = SCROLL_DIRECTION_UP;        }    }    private void refreshItemView(int y) {        int position = y / itemHeight + offset;        int remainder = y % itemHeight;        int divided = y / itemHeight;        if (remainder == 0) {            position = divided + offset;        } else {            if (remainder > itemHeight / 2) {                position = divided + offset + 1;            }        }        int childSize = views.getChildCount();        for (int i = 0; i < childSize; i++) {            TextView itemView = (TextView) views.getChildAt(i);            if (null == itemView) {                return;            }            if (position == i) {                itemView.setTextColor(Color.parseColor("#0288ce"));            } else {                itemView.setTextColor(Color.parseColor("#bbbbbb"));            }        }    }    /**     * 获取选中区域的边界     */    int[] selectedAreaBorder;    private int[] obtainSelectedAreaBorder() {        if (null == selectedAreaBorder) {            selectedAreaBorder = new int[2];            selectedAreaBorder[0] = itemHeight * offset;            selectedAreaBorder[1] = itemHeight * (offset + 1);        }        return selectedAreaBorder;    }    private int scrollDirection = -1;    private static final int SCROLL_DIRECTION_UP = 0;    private static final int SCROLL_DIRECTION_DOWN = 1;    Paint paint;    int viewWidth;    @Override    public void setBackgroundDrawable(Drawable background) {        if (viewWidth == 0) {            viewWidth = ((Activity) context).getWindowManager().getDefaultDisplay().getWidth();            Log.d(TAG, "viewWidth: " + viewWidth);        }        if (null == paint) {            paint = new Paint();            paint.setColor(Color.parseColor("#83cde6"));            paint.setStrokeWidth(dip2px(1f));        }        background = new Drawable() {            @Override            public void draw(Canvas canvas) {                canvas.drawLine(viewWidth * 1 / 6, obtainSelectedAreaBorder()[0], viewWidth * 5 / 6, obtainSelectedAreaBorder()[0], paint);                canvas.drawLine(viewWidth * 1 / 6, obtainSelectedAreaBorder()[1], viewWidth * 5 / 6, obtainSelectedAreaBorder()[1], paint);            }            @Override            public void setAlpha(int alpha) {            }            @Override            public void setColorFilter(ColorFilter cf) {            }            @Override            public int getOpacity() {                return 0;            }        };        super.setBackgroundDrawable(background);    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        Log.d(TAG, "w: " + w + ", h: " + h + ", oldw: " + oldw + ", oldh: " + oldh);        viewWidth = w;        setBackgroundDrawable(null);    }    /**     * 选中回调     */    private void onSeletedCallBack() {        if (null != onWheelViewListener) {            onWheelViewListener.onSelected(selectedIndex, items.get(selectedIndex));        }    }    public void setSeletion(int position) {        final int p = position;        selectedIndex = p + offset;        this.post(new Runnable() {            @Override            public void run() {                WheelView.this.smoothScrollTo(0, p * itemHeight);            }        });    }    public String getSeletedItem() {        return items.get(selectedIndex);    }    public int getSeletedIndex() {        return selectedIndex - offset;    }    @Override    public void fling(int velocityY) {        super.fling(velocityY / 3);    }    @Override    public boolean onTouchEvent(MotionEvent ev) {        if (ev.getAction() == MotionEvent.ACTION_UP) {            startScrollerTask();        }        return super.onTouchEvent(ev);    }    private OnWheelViewListener onWheelViewListener;    public OnWheelViewListener getOnWheelViewListener() {        return onWheelViewListener;    }    public void setOnWheelViewListener(OnWheelViewListener onWheelViewListener) {        this.onWheelViewListener = onWheelViewListener;    }    private int dip2px(float dpValue) {        final float scale = context.getResources().getDisplayMetrics().density;        return (int) (dpValue * scale + 0.5f);    }    private int getViewMeasuredHeight(View view) {        int width = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);        int expandSpec = View.MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, View.MeasureSpec.AT_MOST);        view.measure(width, expandSpec);        return view.getMeasuredHeight();    }}
若是你发现了代码中的bug,请不吝赐教 ~_~


这里是源码Demo


经历 + 总结 = 人生
没有最好的选择,只有最适合的选择!


更多相关文章

  1. 三、安卓UI学习(1)
  2. android用户界面之按钮(Button)教程实例汇
  3. 2014.01.21 ——— android 关联android-support源码
  4. 在Fragment中设置控件点击方法,执行失败。
  5. TabHost与RadioGroup结合完成的菜单【带效果图】5个Activity
  6. 细数Android(安卓)Studio中使用junit4测试框架中的坑
  7. Android常用控件
  8. android用户界面-组件Widget-画廊视图Gallery
  9. Android内容提供者源码

随机推荐

  1. 在Android中使用Curl
  2. Glide 加载图片时大时小
  3. Android(安卓)属性
  4. android通用JSON解析
  5. Android 设置铃声
  6. android之网络请求框架OKhttp、原生http
  7. android升级数据库(Sqlite)简单示例
  8. Android library projects cannot be lau
  9. Android dialog设置无背景
  10. android 圆角布局