Android自定义滚动选择器
实现图片的效果

代码如下

package com.linzihui.widget;import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.FontMetricsInt;
import android.graphics.Paint.Style;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;/*** 自定义滚动选择器* * @author cuiran**/
@SuppressLint({ "HandlerLeak", "ClickableViewAccessibility" })
public class PickerScrollView extends View {public static final String TAG = "PickerView";/*** text之间间距和minTextSize之比*/public static final float MARGIN_ALPHA = 2.8f;/*** 自动回滚到中间的速度*/public static final float SPEED = 2;private List<Pickers> mDataList;/*** 选中的位置,这个位置是mDataList的中心位置,一直不变*/private int mCurrentSelected;private Paint mPaint;private float mMaxTextSize = 20;private float mMinTextSize = 10;private float mMaxTextAlpha = 255;private float mMinTextAlpha = 120;private int mColorText = 0x333333;private int mViewHeight;private int mViewWidth;private float mLastDownY;/*** 滑动的距离*/private float mMoveLen = 0;private boolean isInit = false;private onSelectListener mSelectListener;private Timer timer;private MyTimerTask mTask;Handler updateHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {if (Math.abs(mMoveLen) < SPEED) {mMoveLen = 0;if (mTask != null) {mTask.cancel();mTask = null;performSelect();}} else// 这里mMoveLen / Math.abs(mMoveLen)是为了保有mMoveLen的正负号,以实现上滚或下滚mMoveLen = mMoveLen - mMoveLen / Math.abs(mMoveLen) * SPEED;invalidate();}};public PickerScrollView(Context context) {super(context);init();}public PickerScrollView(Context context, AttributeSet attrs) {super(context, attrs);init();}public void setOnSelectListener(onSelectListener listener) {mSelectListener = listener;}private void performSelect() {if (mSelectListener != null)mSelectListener.onSelect(mDataList.get(mCurrentSelected));}public void setData(List<Pickers> datas) {mDataList = datas;mCurrentSelected = datas.size() / 2;invalidate();}/*** 选择选中的item的index* * @param selected*/public void setSelected(int selected) {mCurrentSelected = selected;int distance = mDataList.size() / 2 - mCurrentSelected;if (distance < 0)for (int i = 0; i < -distance; i++) {moveHeadToTail();mCurrentSelected--;}else if (distance > 0)for (int i = 0; i < distance; i++) {moveTailToHead();mCurrentSelected++;}invalidate();}/*** 选择选中的内容* * @param mSelectItem*/public void setSelected(String mSelectItem) {for (int i = 0; i < mDataList.size(); i++)if (mDataList.get(i).equals(mSelectItem)) {setSelected(i);break;}}private void moveHeadToTail() {Pickers head = mDataList.get(0);mDataList.remove(0);mDataList.add(head);}private void moveTailToHead() {Pickers tail = mDataList.get(mDataList.size() - 1);mDataList.remove(mDataList.size() - 1);mDataList.add(0, tail);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);mViewHeight = getMeasuredHeight();mViewWidth = getMeasuredWidth();// 按照View的高度计算字体大小mMaxTextSize = mViewHeight / 8.0f;mMinTextSize = mMaxTextSize / 2f;isInit = true;invalidate();}private void init() {timer = new Timer();mDataList = new ArrayList<Pickers>();mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mPaint.setStyle(Style.FILL);mPaint.setTextAlign(Align.CENTER);mPaint.setColor(mColorText);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);// 根据index绘制viewif (isInit)drawData(canvas);}private void drawData(Canvas canvas) {// 先绘制选中的text再往上往下绘制其余的textfloat scale = parabola(mViewHeight / 4.0f, mMoveLen);float size = (mMaxTextSize - mMinTextSize) * scale + mMinTextSize;mPaint.setTextSize(size);mPaint.setAlpha((int) ((mMaxTextAlpha - mMinTextAlpha) * scale + mMinTextAlpha));// text居中绘制,注意baseline的计算才能达到居中,y值是text中心坐标float x = (float) (mViewWidth / 2.0);float y = (float) (mViewHeight / 2.0 + mMoveLen);FontMetricsInt fmi = mPaint.getFontMetricsInt();float baseline = (float) (y - (fmi.bottom / 2.0 + fmi.top / 2.0));int indexs = mCurrentSelected;String textData = mDataList.get(indexs).getShowConetnt();canvas.drawText(textData, x, baseline, mPaint);// 绘制上方datafor (int i = 1; (mCurrentSelected - i) >= 0; i++) {drawOtherText(canvas, i, -1);}// 绘制下方datafor (int i = 1; (mCurrentSelected + i) < mDataList.size(); i++) {drawOtherText(canvas, i, 1);}}/*** @param canvas* @param position*            距离mCurrentSelected的差值* @param type*            1表示向下绘制,-1表示向上绘制*/private void drawOtherText(Canvas canvas, int position, int type) {float d = (float) (MARGIN_ALPHA * mMinTextSize * position + type* mMoveLen);float scale = parabola(mViewHeight / 4.0f, d);float size = (mMaxTextSize - mMinTextSize) * scale + mMinTextSize;mPaint.setTextSize(size);mPaint.setAlpha((int) ((mMaxTextAlpha - mMinTextAlpha) * scale + mMinTextAlpha));float y = (float) (mViewHeight / 2.0 + type * d);FontMetricsInt fmi = mPaint.getFontMetricsInt();float baseline = (float) (y - (fmi.bottom / 2.0 + fmi.top / 2.0));int indexs = mCurrentSelected + type * position;String textData = mDataList.get(indexs).getShowConetnt();canvas.drawText(textData, (float) (mViewWidth / 2.0), baseline, mPaint);}/*** 抛物线* * @param zero*            零点坐标* @param x*            偏移量* @return scale*/private float parabola(float zero, float x) {float f = (float) (1 - Math.pow(x / zero, 2));return f < 0 ? 0 : f;}@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getActionMasked()) {case MotionEvent.ACTION_DOWN:doDown(event);break;case MotionEvent.ACTION_MOVE:doMove(event);break;case MotionEvent.ACTION_UP:doUp(event);break;}return true;}private void doDown(MotionEvent event) {if (mTask != null) {mTask.cancel();mTask = null;}mLastDownY = event.getY();}private void doMove(MotionEvent event) {mMoveLen += (event.getY() - mLastDownY);if (mMoveLen > MARGIN_ALPHA * mMinTextSize / 2) {// 往下滑超过离开距离moveTailToHead();mMoveLen = mMoveLen - MARGIN_ALPHA * mMinTextSize;} else if (mMoveLen < -MARGIN_ALPHA * mMinTextSize / 2) {// 往上滑超过离开距离moveHeadToTail();mMoveLen = mMoveLen + MARGIN_ALPHA * mMinTextSize;}mLastDownY = event.getY();invalidate();}private void doUp(MotionEvent event) {// 抬起手后mCurrentSelected的位置由当前位置move到中间选中位置if (Math.abs(mMoveLen) < 0.0001) {mMoveLen = 0;return;}if (mTask != null) {mTask.cancel();mTask = null;}mTask = new MyTimerTask(updateHandler);timer.schedule(mTask, 0, 10);}class MyTimerTask extends TimerTask {Handler handler;public MyTimerTask(Handler handler) {this.handler = handler;}@Overridepublic void run() {handler.sendMessage(handler.obtainMessage());}}public interface onSelectListener {void onSelect(Pickers pickers);}
}
package com.linzihui.widget;import java.io.Serializable;public class Pickers implements Serializable {private static final long serialVersionUID = 1L;private String showConetnt;private String showId;public String getShowConetnt() {return showConetnt;}public String getShowId() {return showId;}public Pickers(String showConetnt, String showId) {super();this.showConetnt = showConetnt;this.showId = showId;}public Pickers() {super();}}

使用的时候 新建一个Activity 里面对View进行处理

  pickerscrlllview=(PickerScrollView)findViewById(R.id.pickerscrlllview);pickerscrlllview.setOnSelectListener(pickerListener);
 PickerScrollView.onSelectListener pickerListener0 = new PickerScrollView.onSelectListener() {@Overridepublic void onSelect(Pickers pickers) {s1=pickers.getShowConetnt();}};

Android自定义滚动选择器相关推荐

  1. Android 仿 iphone 自定义滚动选择器

    转载请标明出处:http://blog.csdn.net/u011546655/article/details/45921025 背景:其实我们都知道,在我们做开发的过程中,会遇到Android 自身 ...

  2. android自定义滚动日期,Android基于wheelView实现自定义日期选择器

    本文实例为大家分享了Android实现自定义日期选择器的具体代码,供大家参考,具体内容如下 项目要求效果图: 要求 "6月20 星期五" 这一项作为一个整体可以滑动,"7 ...

  3. 微信小程序自定义滚动选择器

    最近项目里有个需求要做个滚动选择器,在网上找了半天也没找到合适的demo,没办法只能发挥我的聪明才智创造一个,不哔哔上代码. js: // pages/xuanzeqi/xuanzeqi.js Pag ...

  4. Android:自定义滚动边缘(EdgeEffect)效果

    Android可滚动控件(GridView.ListView.ScrollView等)当用户滚动到头的时候会有个边缘反馈效果,在4.0上默认为Holo蓝色效果. 如果您的App自定义了主题颜色,比如G ...

  5. Android自定义图片选择器

    1.前言 随着APP功能的全面化,越来越多的应用都开发了类似微信朋友圈的功能,随时随地分享自己的心情,图片视频!当需要上传图片.视频的时候,就需要一个图片.视频资源选择器,所以接下来将自己实现一个简单 ...

  6. android 自定义含有滚动选择器的对话框

    最近在写一个项目,需要用到滚动选择器,本人的想法是弹出一个对话框,中间包含滚动选择器,其中滚动选择器的源码参考的这篇文章http://blog.csdn.net/zhongkejingwang/art ...

  7. android自定义滚轴选择器_Android自定义控件实战—滚动选择器PickerView

    手机里设置闹钟需要选择时间,那个选择时间的控件就是滚动选择器,前几天用手机刷了MIUI,发现自带的那个时间选择器效果挺好看的,于是就自己仿写了一个,权当练手.先来看效果: 效果还行吧?实现思路就是自定 ...

  8. 滚动时间选择器recyclerview_Android自定义可循环的滚动选择器CycleWheelView

    最近碰到个项目要使用到滚动选择器,原生的NumberPicker可定制性太差,不大符合UI要求. 网上开源的WheelView是用ScrollView写的,不能循环滚动,而且当数据量很大时要加载的It ...

  9. Android自定义控件实战——滚动选择器PickerView

    转载请声明出处http://blog.csdn.net/zhongkejingwang/article/details/38513301 手机里设置闹钟需要选择时间,那个选择时间的控件就是滚动选择器, ...

最新文章

  1. 前端开发我为什么选择cordova
  2. iOS布局-autoresizingMask
  3. 三个容器倒水_绿茶“最忌讳”先放茶叶再倒水,想要茶味香浓,记住正确泡茶法...
  4. PHP的xdebug安装步骤以及遇到的坑
  5. AWS发布低延迟互动直播服务
  6. bootstrap设置button不显示_电脑便签怎么显示不关闭?电脑云便签敬业签怎么设置显示桌面?...
  7. oracle查询慢怎么优化,Oracle查询优化-怎样建立索引优化下面的查询语句啊
  8. css旋转45度_css 渐变过渡2D
  9. 微信小程序相关项目实例集合
  10. BZOJ 1270 雷涛的小猫 dp
  11. 互联网大佬为什么爱唱歌?
  12. 【DL-CV】正则化,Dropout
  13. win10重装系统后Mysql环境和数据的恢复(无需重装Mysql)
  14. 微软发布了个BT软件
  15. 面试 | 铁憨憨程序员怎么写好简历?先把这个问题改掉先!
  16. 中科大计算机学院潘镇,中科大计算机学院招生导师
  17. windows2003+apache2.2+python2.7配置django mod_wsgi
  18. 人工智能将改变教育的未来:让我们变得更聪明
  19. k8s部署apollo
  20. MATLAB中Simulink的模块封装

热门文章

  1. RTP和RTCP详解
  2. 女人看了是自省,男人看了是激励
  3. [附源码]计算机毕业设计Python基于Web的绿色环保网站(程序+源码+LW文档)
  4. php调用ip 查询接口,IP地址查询接口及调用方法
  5. Web安全测试(文末送电子书)
  6. 自己写linux usb转串口 驱动
  7. java小公司社招面试3则(稍微进阶)
  8. Python学习笔记:rstrip、lstrip、strip的用法!
  9. 三、软件体系结构风格
  10. 易忘知识点整理(持续更新)——VUE使用