零、前言
[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