前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >D2-Android自定义拉绳小控件

D2-Android自定义拉绳小控件

作者头像
张风捷特烈
发布2018-09-29 11:20:06
5830
发布2018-09-29 11:20:06
举报
零、前言

1.今天忙了大半天重构LogicCanvas库结果还是很令我满意的,LogicCanvas已经升级到V0.02了 2.以前想过,以后我变厉害了,一定要写个小拉环,一个晚上总算捣哧出来了 3.本控件绘图部分使用我的LogicCanvas绘图库,喜欢的话可以到github上看看,顺便给个star 4.动画使用我的NumGo库,由于绘图经常用,所以已经集成到LogicCanvas中了,单独NumGo的github地址 5.本文主要讲的是绘制以及事件处理,回调处理,自定义属性就不演示了,可以根据前一篇自己写一下 6.注释写得应该很清楚了,我就不废话了。准备瓜子花生米,往下看吧。

先看看效果:

拉环控件.gif


一、准备工作:
1.新建SwitchRopView继承自View:初始化NumGo
代码语言:javascript
复制
public class SwitchRopView extends View {

    public SwitchRopView(Context context) {
        this(context, null, 0);
    }

    public SwitchRopView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SwitchRopView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public void init() {
        mRunNum = new NumGo(false, -1, 2000).setOnUpdate(new NumGo.OnUpdate() {
            @Override
            public void onUpdate(float rate) {
                mRotateRate = rate;
                invalidate();
            }
        });
    }
}
2.dip2px方法
代码语言:javascript
复制
public float dip2px(Float dp) {
    if (dp != null) {
        final Float scale = getContext().getResources().getDisplayMetrics().density;
        return dp * scale + 0.5f;
    }
    return dp;
}

二、成员属性一览

大注释的都可以做成自定义属性,看你们的需要吧

代码语言:javascript
复制
//线的属性---------------------------------
/**
 * 线宽
 */
private float mRopWidth = dip2px(8f);
/**
 * 线高
 */
private float mRopHeight = dip2px(60f);
/**
 * 线的颜色
 */
private int mRopColor = 0xff76C5F5;
//斜线的属性---------------------------------
/**
 * 斜线宽
 */
private float mPieceWidth = dip2px(8.5f);
/**
 * 斜线高
 */
private float mPieceHeight = dip2px(5f);
/**
 * 斜线的个数
 */
private float mPieceCount = 5;
/**
 * 斜线的颜色
 */
private int mPieceColor = 0xffFBF579;
//圆圈的属性---------------------------------
/**
 * 圆圈半径
 */
private float mRingR = dip2px(10f);
/**
 * 圆圈厚度
 */
private float mRingB = dip2px(6f);
/**
 * 圆圈颜色
 */
private int mRingColor = 0xffC4C4BA;
//小圈的属性---------------------------------
/**
 * 小圆圈半径
 */
private float mDorR = dip2px(7f);
/**
 * 小圆圈厚度
 */
private float mDotB = dip2px(2f);
/**
 * 小圆圈颜色
 */
private int mDotColor = 0xffffffff;
private NumGo mRunNum;
private float mRotateRate;//旋转的分度值
Pos lastPos = new Pos(0, 0);//最后一次坐标点
long lastTimestamp = 0L;//最后一次的时间戳
float downHeight = 0;//下拉总量
boolean isMove = false;//是否移动
boolean isDown = false;//是否按下

三、绘制方法:onDraw
代码语言:javascript
复制
@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Painter painter = new Painter(canvas);
        //绘制线
        Shape rop = new ShapeLine().ps(
                new Pos(0, 0),
                new Pos(0, -mRopHeight),
                new Pos(0 + mRopWidth, -mRopHeight),
                new Pos(0 + mRopWidth, 0),
                new Pos(0, 0))
                .fs(mRopColor).p((2 * mRingR - mRopWidth) / 2, 0f);
        painter.draw(rop);
        //绘制斜线
        ShapeLine piece = new ShapeLine();
        piece.fs(mPieceColor);
        Pos p0 = new Pos(0, 0);
        Pos p1 = new Pos(0, -mPieceHeight);
        Pos p2 = new Pos(mPieceWidth, -mPieceWidth - mPieceHeight);
        Pos p3 = new Pos(mPieceWidth, -mPieceWidth);
        for (int i = 0; i < mPieceCount; i++) {
            piece.ps(p0, p1, p2, p3).p((2 * mRingR - mRopWidth) / 2, -mRopHeight / 5 * i);
            painter.draw(piece);
        }
        //绘制圆圈和点
        ShapeArc ring = new ShapeArc();
        ring.r(mRingR).ang(360f).b(mRingB).ss(mRingColor);
        ShapeArc rot = new ShapeArc();
        rot.r(mDorR).ang(45f).b(mDotB).rot(360 * mRotateRate).ss(mDotColor);
        painter.groupMove(mRingR, -mRopHeight - mRingR + 3, ring, rot);
        painter.draw(ring);
        painter.draw(rot);
    }

四、测量
代码语言:javascript
复制
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //测量
        setMeasuredDimension((int) (2 * mRingR), (int) dip2px(600f));
    }

五、事件监听
代码语言:javascript
复制
    /////////////////////////////////////////////拉绳拉下监听

    /**
     * 拉绳拉下监听
     */
    public interface OnRopDownListener {
        /**
         * 拉绳拉下回调函数
         * @param dataY 下移量
         */
        void ropDown(float dataY);
    }

    private OnRopDownListener mOnRopDownListener;

    public void setOnRopDownListener(OnRopDownListener onRopDownListener) {
        mOnRopDownListener = onRopDownListener;
    }

    /////////////////////////////////////////////拉绳松开监听

    /**
     * 拉绳松开监听
     */
    public interface OnRopUPListener {
        /**
         * 拉绳松开回调函数
         */
        void ropUp();
    }

    private OnRopUPListener mOnRopUPListener;

    public void setOnRopUPListener(OnRopUPListener onRopUPListener) {
        mOnRopUPListener = onRopUPListener;
    }
六、事件处理
代码语言:javascript
复制
    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN://按下
                mRunNum.go();//按下触发RunNum,使得小点旋转
                lastPos.x = event.getX();
                lastPos.y = event.getY();
                lastTimestamp = System.currentTimeMillis();
                mRingColor = ColUtils.randomRGB();//环设随机色
                isDown = true;
                break;
            case MotionEvent.ACTION_UP://抬起
                mRopHeight = dip2px(60f);//回复到原始高度
                mRunNum.end();//结束动画
                if (mOnRopUPListener != null && isMove) {//设置抬起监听
                    mOnRopUPListener.ropUp();//回调抬起函数
                    isMove = false;
                }
                downHeight = 0;
                isDown = false;
                invalidate();
                break;
            case MotionEvent.ACTION_MOVE://2

                float x = event.getX();
                float y = event.getY();
                Pos curPos = new Pos(x, y);//最后一次坐标点

                long curTimestamp = new Date().getTime();
                long t = curTimestamp - lastTimestamp;
                float dataY = curPos.y - lastPos.y;
                mRopHeight += dataY;
                downHeight += dataY;
                if (downHeight > 50) {//下拉高度大于50才算移动
                    isMove = true;
                    if (t > 50) {//时间大于50ms才切换颜色
                        mRopColor = ColUtils.randomRGB();
                    }
                }

                if (mOnRopDownListener != null) {//下拉过程中的监听
                    mOnRopDownListener.ropDown(downHeight);
                }
                lastPos = curPos;//更新位置
                lastTimestamp = curTimestamp;//更新时间
                break;
        }
        return true;
    }

七、Activity使用
代码语言:javascript
复制
public class RopActivity extends AppCompatActivity {
    @BindView(R.id.rop)
    SwitchRopView mRop;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rop);
        ButterKnife.bind(this);

        mRop.setOnRopUPListener(new SwitchRopView.OnRopUPListener() {
            @Override
            public void ropUp() {
                ToastUtil.show(RopActivity.this, "已松开手");
            }
        });

    }
}

附录、布局文件:.xml
代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.toly1994.d.view.SwitchRopView
        android:id="@+id/rop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

</android.support.constraint.ConstraintLayout>

后记、
1.声明:

1本文由张风捷特烈原创,转载请注明

2欢迎广大编程爱好者共同交流

3个人能力有限,如有不正之处欢迎大家批评指证,必定虚心改正

4你的喜欢与支持将是我最大的动力

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.09.04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 零、前言
    • 先看看效果:
    • 一、准备工作:
      • 1.新建SwitchRopView继承自View:初始化NumGo
        • 2.dip2px方法
        • 二、成员属性一览
        • 三、绘制方法:onDraw
        • 四、测量
        • 五、事件监听
        • 六、事件处理
        • 七、Activity使用
          • 附录、布局文件:.xml
          • 后记、
            • 1.声明:
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档