• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >Android > Android自定义实现循环滚轮控件WheelView

Android自定义实现循环滚轮控件WheelView

作者:网友 字体:[增加 减小] 来源:互联网 时间:2017-05-26

网友通过本文主要向大家介绍了android滚轮控件,android滚轮选择器,android 仿ios滚轮,android 滚轮,android时间滚轮等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

Android自定义实现循环滚轮控件WheelView


首先呈上效果图

\

现在很多地方都用到了滚轮布局WheelView,比如在选择生日的时候,风格类似系统提供的DatePickerDialog,开源的控件也有很多,不过大部分都是根据当前项目的需求绘制的界面,因此我就自己写了一款比较符合自己项目的WheelView。

首先这个控件有以下的需求:

1、能够循环滚动,当向上或者向下滑动到临界值的时候,则循环开始滚动

2、中间的一块有一块半透明的选择区,滑动结束时,哪一块在这个选择区,就选择这快。

3、继承自View进行绘制

然后进行一些关键点的讲解:

1、整体控件继承自View,在onDraw中进行绘制。整体包含三个模块,整个View、每一块的条目、中间选择区的条目(额外绘制一块灰色区域)。

2、通过动态设置或者默认设置的可显示条目数,在最上和最下再各加入一块,意思就是一共绘制showCount+2个条目。

3、当最上面的条目数滑动超过条目高度的一半时,进行动态条目更新:将最下面的条目删除加入第一个条目、将第一个条目删除加入最下面的条目。

4、外界可设置条目显示数、字体大小、颜色、选择区提示文字(图中那个年字)、默认选择项、padding补白等等。

5、在onTouchEvent中,得到手指滑动的渐变值,动态更新当前所有的条目。

6、在onMeasure中动态计算宽度,所有条目的宽度、高度、起始Y坐标等等。

7、通过当前条目和被选择条目的坐标,超过一半则视为被选择,并且滑动到对应的位置。

下面的是WheelView代码,主要是计算初始值、得到外面设置的值:

package cc.wxf.view.wheel;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by ccwxf on 2016/3/31.
 */
public class WheelView extends View {

    public static final int FONT_COLOR = Color.BLACK;
    public static final int FONT_SIZE = 30;
    public static final int PADDING = 10;
    public static final int SHOW_COUNT = 3;
    public static final int SELECT = 0;
    //总体宽度、高度、Item的高度
    private int width;
    private int height;
    private int itemHeight;
    //需要显示的行数
    private int showCount = SHOW_COUNT;
    //当前默认选择的位置
    private int select = SELECT;
    //字体颜色、大小、补白
    private int fontColor = FONT_COLOR;
    private int fontSize = FONT_SIZE;
    private int padding = PADDING;
    //文本列表
    private List lists;
    //选中项的辅助文本,可为空
    private String selectTip;
    //每一项Item和选中项
    private List wheelItems = new ArrayList();
    private WheelSelect wheelSelect = null;
    //手点击的Y坐标
    private float mTouchY;
    //监听器
    private OnWheelViewItemSelectListener listener;

    public WheelView(Context context) {
        super(context);
    }

    public WheelView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public WheelView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    /**
     * 设置字体的颜色,不设置的话默认为黑色
     * @param fontColor
     * @return
     */
    public WheelView fontColor(int fontColor){
        this.fontColor = fontColor;
        return this;
    }

    /**
     * 设置字体的大小,不设置的话默认为30
     * @param fontSize
     * @return
     */
    public WheelView fontSize(int fontSize){
        this.fontSize = fontSize;
        return this;
    }

    /**
     * 设置文本到上下两边的补白,不合适的话默认为10
     * @param padding
     * @return
     */
    public WheelView padding(int padding){
        this.padding = padding;
        return this;
    }

    /**
     * 设置选中项的复制文本,可以不设置
     * @param selectTip
     * @return
     */
    public WheelView selectTip(String selectTip){
        this.selectTip = selectTip;
        return this;
    }

    /**
     * 设置文本列表,必须且必须在build方法之前设置
     * @param lists
     * @return
     */
    public WheelView lists(List lists){
        this.lists = lists;
        return this;
    }

    /**
     * 设置显示行数,不设置的话默认为3
     * @param showCount
     * @return
     */
    public WheelView showCount(int showCount){
        if(showCount % 2 == 0){
            throw new IllegalStateException("the showCount must be odd");
        }
        this.showCount = showCount;
        return this;
    }

    /**
     * 设置默认选中的文本的索引,不设置默认为0
     * @param select
     * @return
     */
    public WheelView select(int select){
        this.select = select;
        return this;
    }

    /**
     * 最后调用的方法,判断是否有必要函数没有被调用
     * @return
     */
    public WheelView build(){
        if(lists == null){
            throw new IllegalStateException("this method must invoke after the method [lists]");
        }
        return this;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //得到总体宽度
        width = MeasureSpec.getSize(widthMeasureSpec) - getPaddingLeft() - getPaddingRight();
        // 得到每一个Item的高度
        Paint mPaint = new Paint();
        mPaint.setTextSize(fontSize);
        Paint.FontMetrics metrics =  mPaint.getFontMetrics();
        itemHeight = (int) (metrics.bottom - metrics.top) + 2 * padding;
        //初始化每一个WheelItem
        initWheelItems(width, itemHeight);
        //初始化WheelSelect
        wheelSelect = new WheelSelect(showCount / 2 * itemHeight, width, itemHeight, selectTip, fontColor, fontSize, padding);
        //得到所有的高度
        height = itemHeight * showCount;
        super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
    }

    /**
     * 创建显示个数+2个WheelItem
     * @param width
     * @param itemHeight
     */
    private void initWheelItems(int width, int itemHeight) {
        wheelItems.clear();
        for(int i = 0; i < showCount + 2; i++){
            int startY = itemHeight * (i - 1);
            int stringIndex = select - showCount / 2 - 1 + i;
            if(stringIndex < 0){
                stringIndex = lists.size() + stringIndex;
            }
            wheelItems.add(new WheelItem(startY, width, itemHeight, fontColor, fontSize, lists.get(stringIndex)));
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                mTouchY = event.getY();
                return true;
            case MotionEvent.ACTION_MOVE:
                float dy = event.getY() - mTouchY;
                mTouchY = event.getY();
                handleMove(dy);
                break;
            case MotionEvent.ACTION_UP:
                handleUp();
                break;
        }
        return super.onTouchEvent(event);
    }

    /**
     * 处理移动操作
     * @param dy
     */
    private void handleMove(float dy) {
        //调整坐标
        for(WheelItem item : wheelItems){
            item.adjust(dy);
        }
        invalidate();
        //调整
        adjust();
    }

    /**
     * 处理抬起操作
     */
    private void handleUp(){
        int index = -1;
        //得到应该选择的那一项
        for(int i = 0; i < wheelItems.size(); i++){
            WheelItem item = wheelItems.get(i);
            //如果startY在selectItem的中点上面,则将该项作为选择项
            if(item.getStartY() > wheelSelect.getStartY() && item.getStartY() < (wheelSelect.getStartY() + itemHeight / 2)){
                index = i;
                break;
            }
            //如果startY在selectItem的中点下面,则将上一项作为选择项
            if(item.getStartY() >= (wheelSelect.getStartY() + itemHeight / 2) && item.getStartY() < (wheelSelect.getStartY() + itemHeight)){
                index = i - 1;
                break;
            }
        }
        //如果没找到或者其他因素,直接返回
   



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • Android自定义实现循环滚轮控件WheelView

相关文章

  • 2017-07-23从头开始学RecyclerView(六)LayoutManager
  • 2017-05-26测试新建博文,新建博文
  • 2017-05-227.5.6 WebView处理网页返回的错误码信息
  • 2017-05-26Gradle Android客户端程序打包,gradleandroid
  • 2017-05-26android 4.2 系统以后的飞行模式,android4.2
  • 2017-05-26Android之万能播放器解码框架Vitamio的介绍及使用,androidvitamio
  • 2017-05-26Android-Universal-Image-Loader (图片异步加载缓存库)对Bitmap的优化处理
  • 2017-05-26Android:应用宝省流量更新
  • 2017-05-26Apache Cordova开发Android应用程序——番外篇,cordovaandroid
  • 2017-05-26android——从零开始,android从零开始

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 提现,提现英文
    • Android Studio安装指南及genymotion配置
    • git+coding.net记录篇,gitcoding.net记录
    • Dialog 用代码来实现全屏
    • AndroidTV版(乐视超3 X55)root,将自己的软件设置为开机自启、系统软件,卸载系统应用等问题总结,androidtvx55
    • Bottom Sheet
    • 第3章 用C#编写百度地图Android手机应用程序(第5讲),
    • android TCP自动重连
    • Android音频开发之基础知识介绍
    • Android疑难杂症之Theme,android疑难杂症

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有