原来做项目时用到了滑轮选择器,也是借鉴了别人的,但当时时间紧也就没自己怎么优化与巩固,最近时间充足就重新巩固了一下,在这里记下自己的心得与实现方法以免以后生疏,有不足的地方欢迎指教。
首先自定义了一个 PickerView 继承 android 原生的 View
实现滑动点击监听事件,通过一系列触摸判断实现滑动效果
其次 TextPicker 继承 PopupWindow 装载这个 PickerView 实现展示
原理还是很简单的,主要的就是自定义的PickerView
其中主要的实现方法是 onDrawView() 与 drawOtherView 绘制滑轮选择器的文本显示,然后就是触摸事件 onTouchEvent() 的事件处理。
滑轮的文本效果是要中间的文本显示正常而上面与下面的文本要相应的缩小字体大小达到远离的感觉,所用首先绘制好中间的文本,再以中间的文本为中心绘制上下的文本,下面是部分源码
private void onDrawView(Canvas canvas) { float scal = getParabola((screenHeight / 4.0f), moveLength); //字体居中显示 float x = screenWidth / 2.0f; float y = screenHeight / 2.0f + moveLength; float size = (maxTextSize - minTextSize) * scal + minTextSize; //获得Paint的属性参数 Paint.FontMetricsInt pfm = mPaint.getFontMetricsInt(); //得到居中y float baseLine = y - (pfm.top + pfm.bottom) / 2; mPaint.setTextSize(size); mPaint.setAlpha((int) ((maxAlpha - minAlpha) * scal + minAlpha)); //画中间位置 canvas.drawText(dataList.get(position), x, baseLine, mPaint); //画上面位置 for (int i = 1; position - i >= 0; i++) { drawOtherView(canvas, i, -1); } //画下面的位置 for (int i = 1; position + i < dataList.size(); i++) { drawOtherView(canvas, i, 1); } } private void drawOtherView(Canvas canvas, int i, int direction) { float offsetY = (MARGIN * minTextSize * i + moveLength * direction); float scal = getParabola(screenHeight / 4.0f, offsetY); float x = screenWidth / 2.0f; float y = screenHeight / 2.0f + direction * offsetY; float size = (maxTextSize - minTextSize) * scal + minTextSize; float alpha = (maxAlpha - minAlpha) * scal + minAlpha; Paint.FontMetricsInt pfm = mPaint.getFontMetricsInt(); float baseLine = (float) (y - (pfm.top + pfm.bottom) / 2.0); mPaint.setTextSize(size); mPaint.setAlpha((int) alpha); canvas.drawText(dataList.get(position + direction * i), x, baseLine, mPaint); }
然后就是触摸滑动效果,通过 doDown() , doMove() 与 doUp() 来操作
private void doMove(MotionEvent event) { moveLength += event.getY() - eventY; if (moveLength > MARGIN * minTextSize / 2) { //手指向下滑动滑出边界 moveFootTOHead(); moveLength = moveLength - MARGIN * minTextSize; } else if (moveLength < -MARGIN * minTextSize / 2) { //手指向上滑动滑出边界 moveHeadToFoot(); moveLength = moveLength + MARGIN * minTextSize; } eventY = event.getY(); invalidate(); }
PickerView的主意方法就这些了,是不是很简单
实现了 PickerView 就可以在单独的一个xml中布局,xml的代码就不贴了
对于xml中 PickerView 进行了封装,因为可以项目中要用到多次,所用写个封装类还是必须的
setPickerTitle(String text) 设置标题
setData(List<String> dataList, int i) 填充数据
setMiddleText(int position, int i) 设置居中文本
getText(int i) 获取文本
getOK() 获取确定控件
setPrepare() 开启
最后就是实例化中 TextPicker 调用其方法实现
tp = new TextPicker(this); //初始化数据 initData(); //加载数据 tp.setData(leftList, 1); tp.setData(middleList, 2); tp.setData(rightList, 3); //设置标题 tp.setPickerTitle("标题"); //设置默认居中文本 tp.setMiddleText(5, 1); tp.setMiddleText(2, 2); tp.setMiddleText(25, 3); //准备完毕 tp.setPrepare(); ok = tp.getOK(); ok.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v) { leftText = tp.getText(1); middleText = tp.getText(2); rightText = tp.getText(3); tv.setText(leftText+"-"+middleText+"-"+rightText); tp.dismiss(); } }); //展示 tp.showAtLocation(this.findViewById(R.id.main), Gravity.CENTER, 0, 0);
更多源代码: https://github.com/idisfkj/idisfkj.picker
个人博客: http://idisfkj.github.io/