前言
今天计划下班去西昊店里体验人体工学椅,到了发现,店面太小,里面就老板一个人,门边又坐了个看起来近300斤的大胖子,社恐,没敢进去,骑了一个小时单车回家了,冷风吹得脸疼;
手头的项目有音量条、光照条的要求,刚开始自己继承View写,写着写着,以为需求是刚开始是平的,快满的时候要变成圆头,就像手机的音量条一样,觉得自己写的话有点麻烦,就发现了SeekBar,找方法给他改成了竖的,但是UI给了我的图一直是圆头,看着SeekBar复杂的继承方式,改回继承View自己搞吧,原来的就算废案了。
竖向SeekBar
像NestedScrollView一样,我也不知道为什么谷歌只搞一个方向的View
/**
* 直接继承AbsSeekBar,不知道为什么不能像SeekBar一样重写那几个方法,简单写了几个名字一样的
*
* SeekBar里面有 this(context, attrs, com.android.internal.R.attr.seekBarStyle);
* 源码里面是<attr name="seekBarStyle" format="reference" />;
* 嗯,我不懂,后面有空再了解了解
*/
class VerticalSeekBar @JvmOverloads constructor(
context: Context,
attributeSet: AttributeSet? = null,
defStyleAttr: Int = 0,
): AbsSeekBar(context, attributeSet, defStyleAttr) {
// 宽高调换
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(h, w, oldh, oldw)
}
// 宽高调换
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(heightMeasureSpec, widthMeasureSpec)
setMeasuredDimension(measuredHeight, measuredWidth)
}
override fun onDraw(canvas: Canvas?) {
canvas?.rotate(-90f)
canvas?.translate(-height.toFloat(), 0f)
super.onDraw(canvas)
}
// 从SeekBar抄过来,觉得传递seekBar麻烦的话也可以去掉,fromUser不是一直都是true吗
interface OnSeekBarChangeListener {
fun onProgressChanged(seekBar: VerticalSeekBar?, progress: Int, fromUser: Boolean)
fun onStartTrackingTouch(seekBar: VerticalSeekBar?)
fun onStopTrackingTouch(seekBar: VerticalSeekBar?)
}
private var mOnSeekBarChangeListener: OnSeekBarChangeListener? = null
fun setOnSeekBarChangeListener(l: OnSeekBarChangeListener) {
mOnSeekBarChangeListener = l
}
/**
* 参考super.onTouchEvent(event)简单写了点,复杂情况判断参考super.onTouchEvent(event)
*/
override fun onTouchEvent(event: MotionEvent?): Boolean {
if (!isEnabled || event == null) return false
super.onTouchEvent(event)
trackTouchEvent(event)
when (event.action) {
MotionEvent.ACTION_DOWN -> onStartTrackingTouch()
MotionEvent.ACTION_UP -> onStopTrackingTouch()
MotionEvent.ACTION_CANCEL -> onStopTrackingTouch()
}
return true
}
/**
* 旧progress有点问题,自己弄一个变量先存着
*/
private var mProgress: Int = progress
override fun setProgress(progress: Int) {
super.setProgress(progress)
mProgress = progress
}
private fun trackTouchEvent(event: MotionEvent) {
val newProgress = max - ((max * event.y) / height).toInt()
if (progress != newProgress) {
LogUtil.i("TAG", "progress: $progress mProgress: $mProgress newProgress: $newProgress")
val oldProgress = mProgress
progress = newProgress
onSizeChanged(width, height, 0, 0)
if (oldProgress != newProgress) onProgressRefresh()
}
}
private fun onProgressRefresh() {
mOnSeekBarChangeListener?.onProgressChanged(this, progress, true)
}
private fun onStartTrackingTouch() {
mOnSeekBarChangeListener?.onStartTrackingTouch(this)
}
private fun onStopTrackingTouch() {
mOnSeekBarChangeListener?.onStopTrackingTouch(this)
}
}
时间不早了,12点了,今天就这样吧
用法(宽即是高,高即是宽):
<xxx.xxx.VerticalSeekBar
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:maxHeight="100dp"
android:minHeight="100dp"
android:max="100"
android:progressDrawable="@drawable/seekbar_background"/>
从这里copy的进度条样式测试:www.jianshu.com/p/6ca82ceb9…
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!--定义seekbar滑动条的底色-->
<item android:id="@android:id/background">
<shape>
<corners android:radius="5dp" />
<gradient
android:angle="270"
android:centerColor="#eeeff3"
android:centerY="0.75"
android:endColor="#eeeff3"
android:startColor="#eeeff3" />
</shape>
</item>
<!--定义seekbar滑动条进度颜色-->
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="5dp"/>
<solid android:color="#FD5655"/>
</shape>
</clip>
</item>
</layer-list>
java看这个,嗯,就是抄的这个github.com/AndroSelva/…
public class VerticalSeekBar extends androidx.appcompat.widget.AppCompatSeekBar {
public VerticalSeekBar(Context context) {
super(context);
}
public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public VerticalSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(h, w, oldh, oldw);
}
@Override
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(heightMeasureSpec, widthMeasureSpec);
setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
}
protected void onDraw(Canvas c) {
c.rotate(-90);
c.translate(-getHeight(),0);
super.onDraw(c);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!isEnabled()) {
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
int i=0;
i=getMax() - (int) (getMax() * event.getY() / getHeight());
setProgress(i);
Log.i("Progress",getProgress()+"");
onSizeChanged(getWidth(), getHeight(), 0, 0);
break;
case MotionEvent.ACTION_CANCEL:
break;
}
return true;
}
}