D2-Android自定义拉绳小控件

mac2022-06-30  122

零、前言

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

先看看效果:
拉环控件.gif

一、准备工作:

1.新建SwitchRopView继承自View:初始化NumGo
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方法
public float dip2px(Float dp) { if (dp != null) { final Float scale = getContext().getResources().getDisplayMetrics().density; return dp * scale + 0.5f; } return dp; }

二、成员属性一览

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

//线的属性--------------------------------- /** * 线宽 */ 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

@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Painter painter = PainterEnum.INSTANCE.getInstance(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); }

四、测量

@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //测量 setMeasuredDimension((int) (2 * mRingR), (int) dip2px(600f)); }

五、事件监听

/拉绳拉下监听 /** * 拉绳拉下监听 */ 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; }

六、事件处理

@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使用

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
<?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]你的喜欢与支持将是我最大的动力

2.连接传送门:

更多安卓技术欢迎访问:安卓技术栈 我的github地址:欢迎star 简书首发,腾讯云+社区同步更新 张风捷特烈个人网站,编程笔记请访问:http://www.toly1994.com

3.联系我

QQ:1981462002 邮箱:1981462002@qq.com 微信:zdl1994328

4.欢迎关注我的微信公众号,最新精彩文章,及时送达:
公众号.jpg

转载于:https://www.cnblogs.com/toly-top/p/9781902.html

最新回复(0)