package com.as.flypig06;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.TranslateAnimation;
import androidx.annotation.Nullable;
import com.blankj.utilcode.util.SizeUtils;
public class SlidePlusView extends View implements View.OnTouchListener, Runnable {
private static final String TAG = "SlidePlusView";
//线的最小高度的倍数=最大高度 * f
private static final float f = 0.22f;
//画笔
private Paint mPaint;
//当前滑动的位置
private int mPosition;
//所有滑动的数据
private int mLength;
//线的宽度
private int mLineWidth;
//线的最大高度
private int mLineMaxHeight;
//线的最小高度
private int mLineMinHeight;
//滑动的x坐标
private float mSlideX = 0;
//这个控件可以画几条线,同时也是线与线之间的距离
private float range = 0;
//控件的中间
private float center = 0;
//事件监听
private OnMoveListener moveListener;
//记录按下的x坐标
private float downX;
//记录按下是的当前移动的x坐标
private float downSlideX;
private int oldPosition;
private Paint paint;
public SlidePlusView(Context context) {
this(context, null);
}
public SlidePlusView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
mLineWidth = SizeUtils.dp2px(4);
mLineMaxHeight = SizeUtils.dp2px(30);
mLineMinHeight = (int) (mLineMaxHeight * f);
mPaint = new Paint();
//设置抗锯齿
mPaint.setAntiAlias(true);
//设置笔的两端圆角
mPaint.setStrokeCap(Paint.Cap.ROUND);
//设置线的粗细
mPaint.setStrokeWidth(mLineWidth);
paint = new Paint();
paint.setTextSize(20);
//加入滑动事件
setOnTouchListener(this);
}
@Override
public void run() {
//一共显示几条线
range = getMeasuredWidth() / 28f;
//获取中间x坐标
center = getMeasuredWidth() / 2f;
//计算position出现的位置
mSlideX = -mPosition * range;
invalidate();
// initAnimation(0, mSlideX);
}
@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float[] cf;
// //从中间开始画
// mPaint.setAlpha(255);
// cf = getLineHeight(mLineMaxHeight);
// canvas.drawLine(center,cf[0],center,cf[1], mPaint);
// //这个控件可以画几条线,同时也是线与线之间的距离
// range = getMeasuredWidth() / 20f;
// //计算开始画的x左边
// float x = center - (mPosition * range) + (mSlideX % range);
// for (int i = 0; i < mData.size(); i++) {
// if (mPosition == i){
// continue;
// }
// cf = getLineHeight(mLineMinHeight);
// float x2 = x + (i * range);
// canvas.drawLine(x2,cf[0],x2,cf[1], mPaint);
// }
//计算开始画的x左边 从中间开始计算+移动的偏移值
float x = center + mSlideX;
int t;
int alpha;
for (int i = 0; i < mLength; i++) {
//计算透明值
//滑动位置mPosition的左右边透明度使用位移算法计算,最小值为79
//使用位移算法的原因,最高亮到透明是上一条线的透明度的一倍
t = Math.abs(i - mPosition);
alpha = 255 * 10 / (1 << t);
if (alpha < 79) {
alpha = 79;
}
mPaint.setAlpha(alpha);
if (mPosition == i) {
//画选中mPosition的线
cf = getLineHeight(mLineMaxHeight);
mPaint.setColor(Color.BLACK);
// } else if (mPosition == i + 1 || mPosition == i - 1 ||) {
} else if (mPosition == i + 1 || mPosition == i - 1 ) {
//画 mPosition 左右两边的线
cf = getLineHeight(mLineMaxHeight * 0.5f);
mPaint.setColor(Color.BLACK);
} else {
if(mPosition == i + 2 || mPosition == i - 2 ){
mPaint.setColor(Color.BLACK);
}else{
mPaint.setColor(Color.GRAY);
}
//画小线
cf = getLineHeight(mLineMinHeight);
}
float x2 = x + (i * range);
canvas.drawLine(x2, cf[0], x2, cf[1], mPaint);
canvas.drawText(mPosition+"", x2, cf[1]+10,paint);
}
}
/**
* 获取线的高度,通过传入的height,计算出现这个控件中间的位置
* f[0] = 开始画的y坐标
* f[1] = 结束的y坐标
*
* @param height
* @return
*/
private float[] getLineHeight(float height) {
float f[] = new float[2];
float y = (getMeasuredHeight() - height) / 2f;
f[0] = y;
f[1] = y + height;
return f;
}
//设置显示的位置
public void setPosition(int position) {
mPosition = position;
post(this);
}
public int getPosition() {
return mPosition;
}
//设置长度
public void setLength(int length) {
this.mLength = length;
post(this);
}
public void setOnMoveListener(OnMoveListener onSlideListener) {
this.moveListener = onSlideListener;
}
// public OnSlideListener getOnSlideListener() {
// return mOnSlideListener;
// }
//滑动出这个控件的外部,滑动事件依然有效
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_MOVE) {
getParent().requestDisallowInterceptTouchEvent(true);
}
return super.dispatchTouchEvent(event);
}
//滑动事件
@Override
public boolean onTouch(View v, MotionEvent event) {
if (mLength <= 0) {
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//记录上次的数据
downX = event.getX();
downSlideX = mSlideX;
oldPosition = mPosition;
break;
case MotionEvent.ACTION_MOVE:
float x = event.getX() - downX;
mSlideX = x + downSlideX;
//滑动右边是否超出,超过不计算,给最小值
if (mSlideX > 0) {
mSlideX = 0;
mPosition = 0;
} else {
//计算滑动到那个position
mPosition = (int) Math.abs(mSlideX / range);
//计算滑动左边是否超出,超过不计算,给最大值
if (mPosition >= mLength) {
mPosition = mLength - 1;
mSlideX = -mPosition * range;
}
}
if (moveListener != null) {
if (oldPosition != mPosition) {
oldPosition = mPosition;
moveListener.onSlide(this, mPosition,x);
}
}
break;
}
invalidate();
return true;
}
public interface OnMoveListener {
void onSlide(View v, int position, float x);
}
private void initAnimation(float start, float end) {
TranslateAnimation nameAnimator = new TranslateAnimation(start, end, 0f, 0f);
nameAnimator.setDuration(800);
nameAnimator.setInterpolator(new DecelerateInterpolator());
this.startAnimation(nameAnimator);
}
}
public class MainActivity extends BaseActivity<ActivityMainBinding> implements View.OnClickListener {
@Override
protected int getLayoutId() {
return R.layout.activity_main;
}
@Override
protected void initShape() {
}
@Override
protected void initView() {
mViewBinding.spv.setLength(100);
mViewBinding.spv.setOnMoveListener(new SlidePlusView.OnMoveListener() {
@Override
public void onSlide(View v, int position, float x) {
ToastUtils.showShort("position :" + position);
}
});
mViewBinding.but1.setOnClickListener(this);
mViewBinding.but2.setOnClickListener(this);
mViewBinding.but3.setOnClickListener(this);
mViewBinding.but4.setOnClickListener(this);
}
@Override
protected void initData() {
}
@Override
protected void initListener() {
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.but1:
mViewBinding.spv.setPosition(0*10);
break;
case R.id.but2:
mViewBinding.spv.setPosition(1*10);
break;
case R.id.but3:
mViewBinding.spv.setPosition(2*10);
break;
case R.id.but4:
mViewBinding.spv.setPosition(3*10);
break;
default:
break;
}
}