【安卓相关】自定义控件,重写SeekBar类,显示拖动条控件当前
2020-02-06 本文已影响0人
norkm
场景还原:
最近做开发的时候,用到了Seekbar控件,需要显示拖动条当前滑动到的数值。
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="50dp">
<SeekBar
android:layout_gravity="center"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:text="50 %"
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
</LinearLayout>
这好办,旁边加个TextView轻松解决!
完成,收工!
哎,好 Low,实际用起来还麻烦的很,emmmm...
还是试着改改用吧。
ps:第三个和第四个拖动条是 触摸 / 拖动 时的效果,手指抬起或离开则恢复成默认Seekbar的样子。
实现代码:
<com.norkm.diy.NSeekBar
app:unit="%"
app:thumbPosition="center"
app:lucency="true"
android:max="100"
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="50dp" />
<com.norkm.diy.NSeekBar
app:thumbPosition="top"
app:lucency="true"
android:layout_marginTop="100dp"
android:max="500"
android:layout_width="match_parent"
android:layout_height="50dp" />
<com.norkm.diy.NSeekBar
app:thumbPosition="top"
app:unit="px"
android:layout_marginTop="100dp"
android:max="500"
android:layout_width="match_parent"
android:layout_height="50dp" />
<com.norkm.diy.NSeekBar
app:thumbPosition="center"
app:unit="px"
android:layout_marginTop="100dp"
android:max="500"
android:layout_width="match_parent"
android:layout_height="50dp" />
其中几个重要的自定义属性
属性 | 值 | 描述 | 补充 |
---|---|---|---|
app:unit | String | 向气泡中的文本添加后缀 | 例如 px , % |
app:lucency | boolean | 气泡是否透明 | 默认为 false |
app:thumbPosition | top / center | 气泡在中间还是顶部 | 无 |
下面是重写Seekbar的代码,注释应该写的很清楚了,就不做过多描述了。
package com.norkm.diy;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.AppCompatSeekBar;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ViewGroup;
public class NSeekBar extends AppCompatSeekBar {
private boolean isDrag=false;
private String seekBar_unit;
private int seekBar_thumbPosition;
private boolean seekBar_lucency;
public NSeekBar(Context context) {
super(context);
}
public NSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.NSeekBar);
seekBar_unit = typedArray.getString(R.styleable.NSeekBar_unit);
seekBar_thumbPosition = typedArray.getInteger(R.styleable.NSeekBar_thumbPosition,0);
seekBar_lucency =typedArray.getBoolean(R.styleable.NSeekBar_lucency,false);
typedArray.recycle();
if(seekBar_unit ==null){
seekBar_unit ="";
}else{
seekBar_unit =" "+ seekBar_unit+" ";
}
}
@Override
protected synchronized void onDraw(Canvas canvas) {
super.onDraw(canvas);
ViewGroup mViewGroup = (ViewGroup) getParent();
mViewGroup.setClipChildren(false);
// 字体大小 、 气泡半径 、气泡的 y 轴位置 、拖拽条左边距、拖拽条左边距(像素)
int textSize=40;
int pointSize=(textSize)*(String.valueOf(getProgress()).length()+1);
int floatTop,paddingLeft,paddingLeftPx;
// 画笔初始化、消除锯齿、填充式风格
Paint paint=new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
paddingLeft = getPaddingLeft();
paddingLeftPx = (getMeasuredWidth() - paddingLeft * 2) * getProgress() / getMax();
String text= getProgress()+ seekBar_unit;
// 浮动球距离顶部距离,0 为top ,1 为 center
if(seekBar_thumbPosition == 0 ){
floatTop =getMeasuredHeight() / 2 - pointSize;
}else{
floatTop =getMeasuredHeight() / 2;
}
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setTextAlign(Paint.Align.CENTER);
// 如果正在拖动并且非透明效果
if(isDrag && !seekBar_lucency){
// 绘制球形阴影
paint.setStrokeWidth((pointSize/10)*14);
paint.setColor(Color.GRAY);
paint.setAlpha(25);
canvas.drawPoint(paddingLeftPx + paddingLeft, floatTop, paint);
// 绘制纯色圆形
paint.setAlpha(255);
paint.setColor(ContextCompat.getColor(getContext(),R.color.colorPrimary));
paint.setStrokeWidth(pointSize);
canvas.drawPoint(paddingLeftPx + paddingLeft, floatTop, paint);
// 绘制球形上面的文字
paint.setTextSize(textSize);
paint.setColor(Color.WHITE);
canvas.drawText(text, paddingLeftPx + paddingLeft, floatTop +textSize/4, paint);
}
// 透明效果
if(seekBar_lucency){
// 如果是透明气泡 且位于顶部 floatTop = 10 否则 TOP = getMeasuredHeight() / 2
floatTop = (seekBar_thumbPosition==0) ? 10 : getMeasuredHeight() / 2 ;
// 去除默认thunb 与 thumb 的阴影
if(seekBar_thumbPosition==1){
setThumb(null);
setBackground(null);
// 绘制白色矩形
paint.setAlpha(255);
paint.setColor(Color.WHITE);
int left=(paddingLeftPx + paddingLeft)-pointSize/2;
int rigt=(paddingLeftPx + paddingLeft)+(pointSize/2);
int top=getHeight()/2-textSize;
int bottom=getHeight()/2+textSize;
canvas.drawRect(new Rect(left,top,rigt,bottom),paint);
Log.i("结果",getSuggestedMinimumHeight()+"");
}else{
// 绘制透明背景
paint.setStrokeCap(Paint.Cap.SQUARE);
paint.setAlpha(255);
paint.setColor(Color.TRANSPARENT);
paint.setStrokeWidth(pointSize);
canvas.drawPoint(paddingLeftPx + paddingLeft, floatTop, paint);
}
// 绘制控件上面的文字
paint.setTextSize(textSize);
paint.setColor(ContextCompat.getColor(getContext(),R.color.colorPrimary));
canvas.drawText(text, paddingLeftPx + paddingLeft, floatTop +textSize/4, paint);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
isDrag=true;
break;
case MotionEvent.ACTION_MOVE:
isDrag=true;
break;
case MotionEvent.ACTION_UP:
isDrag=false;
break;
case MotionEvent.ACTION_OUTSIDE:
isDrag=false;
break;
}
return super.onTouchEvent(event);
}
}
写好视图类后,再向 values / attrs.xml 文件中添加自定义属性。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 自定义拖拽条 -->
<declare-styleable name="NSeekBar">
<attr name="thumbPosition" format="integer">
<flag name="top" value="0" />
<flag name="center" value="1"/>
</attr>
<attr name="unit" format="string"/>
<attr name="lucency" format="boolean"/>
</declare-styleable>
</resources>
水平有限,如有疏漏,可在话题区留言,感谢!