版权声明
本文来自博客园,作者:观心静 ,转载请注明原文链接:https://www.cnblogs.com/guanxinjing/p/11947457.html
前言
开发记录博客不是讲解使用博客,更多的是功能与各个点子的记录
基本使用
<SeekBar android:layout_width="match_parent" android:layout_height="wrap_content" android:max="200" android:maxHeight="3dp" android:minHeight="3dp" android:progressDrawable="@drawable/seekbar_bg" android:thumb="@drawable/seekbar_thumb_bg"/>
注意,如果你发现进度的高度或者宽度设置后依然很大,可以尝试使用maxHeight与minHeight 来调整
xml属性:
- android:max="200" 设置进度最大值
- android:progressDrawable="@drawable/seekbar_bg" 设置进度条的背景
- android:thumb="@drawable/seekbar_thumb_bg" 设置进度条上圆点的背景
- android:progress="10" 设置当前进度值
- android:min="0" 设置最小值
- android:splitTrack="false" 设置滑块圆点是否背景透明,在用图片设置thumb后,thumb的四周可能会出现正方形的白色背景。设置此属性可以取消这个背景
- android:padding=“0dp” 请注意,SeekBar 实际上是有内边距的,如果你需要填充满效果就需要设置成0dp。另外如果你需要圆点比今天背景大,也是调整这个内边距
Api:
- setProgress(int value) 设置滑块的位置
- setMax(int value) 设置进度条的最大长度
- setOnSeekBarChangeListener(OnSeekBarChangeListener l)这个主要是监听进度改变 里面包含3个回调方法: onProgressChanged进度条变化 onStartTrackingTouch(SeekBar seekBar) 监听开始拖动滚动条时的操作 onStopTrackingTouch(SeekBar seekBar) 监听停止拖动滚动条的操作
- setSecondaryProgress(int secondaryProgress) 设置缓冲的进度
- setProgressDrawable(Drawable d) 在代码上设置进度条背景,请注意,这里可以直接设置GradientDrawable或者Drawable。但是,设置后只会成为背景。如果需要有进度背景那就需要导入LayerDrawable。
进度条背景xml
seekbar_bg.xml
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@android:id/background"> <shape> <solid android:color="#ff51495e"/> </shape> </item> <item android:id="@android:id/secondaryProgress"> <clip> <shape> <solid android:color="#f9062a"/> </shape> </clip> </item> <item android:id="@android:id/progress"> <clip> <shape> <solid android:color="#2db334"/> </shape> </clip> </item> </layer-list>
根据属性解释一下3个背景的对应功能,原则上如果你不需要显示预加载的功能,可以将@android:id/secondaryProgress 设置为透明,或者不写
android:id="@android:id/background" 是没有如何拖动或者设置的背景,请注意!这个属性下面是没有用<clip>包裹的,如果不小心包裹了会出现没有背景的bug
android:id="@android:id/secondaryProgress" 是次级进度背景,类似你在看视频的时候,视频的进度条会有预加载的进度. 请注意!这个属性下面是用<clip>包裹的,如果没有包裹<clip>就会出现进度条没有颜色的bug
android:id="@android:id/progress"是主进度背景,就是你看视频的时候当前看到哪里的进度条背景. 请注意!这个属性下面是用<clip>包裹的,如果没有包裹<clip>就会出现进度条没有颜色的bug
另外,进度条背景还支持设置伸缩方向,横竖方向与自定义矢量图,可以参考如下设置:
<item android:id="@android:id/progress"> <clip android:drawable="@drawable/ic_curtain" android:gravity="right" android:clipOrientation="horizontal"> </clip> </item>
进度条的圆点背景
seekbar_thumb_bg.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <!--获取焦点和没有按下的时候--> <item android:drawable="@drawable/seekbar_thumb_normal" android:state_focused="true" android:state_pressed="false"/> <!--获取焦点但按下的时候--> <item android:drawable="@drawable/seekbar_thumb_pressed" android:state_focused="true" android:state_pressed="true"/> <!--没有获取焦点按下的时候--> <item android:drawable="@drawable/seekbar_thumb_pressed" android:state_focused="false" android:state_pressed="true"/> <!--默认的时候--> <item android:drawable="@drawable/seekbar_thumb_normal"/> </selector>
在代码上设置的监听
mVideoSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { //进度变化回调 //fromUser 表示改变这个进度的这个操作来自用户,这个布尔值可以区分是代码上改变的进度还是,用户操作后改变的进度 } @Override public void onStartTrackingTouch(SeekBar seekBar) { //开始触摸移动进度条 } @Override public void onStopTrackingTouch(SeekBar seekBar) { //停止触摸移动进度条 } });
进度条圆点偏移
如果你需要进度条圆点能超出进度条就需要将thumbOffset属性设置超出距离,反之如果你希望圆点永远不会超出进度条只需要设置为0dp
android:thumbOffset="0dp"
点子:自定义实现只允许拖拽不允许点击的seekbar进度条
oldProgress = mSeekBar.getProgress(); mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) { if(progress > oldProgress + 3 || progress < oldProgress - 3){ seekBar.setProgress(oldProgress); return; } seekBar.setProgress(progress); oldProgress = progress; } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } });
设置Thumb大小
fun setThumbSize(){ val bitmap = BitmapFactory.decodeResource(resources, R.mipmap.main_ic_vehicle_1) val dp238 = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 238f, resources.displayMetrics).toInt() val dp108 = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 108f, resources.displayMetrics).toInt() val thumb: Bitmap = Bitmap.createScaledBitmap(bitmap, dp238, dp108, true) //设置大小 val d = BitmapDrawable(thumb) val bitmap1 = d.bitmap if (bitmap1.density == Bitmap.DENSITY_NONE) { d.setTargetDensity(resources.getDisplayMetrics()) } val drawable: Drawable = d mBinding.seekBar.thumb = drawable }
点子:将SeekBar进度条竖立
在百度里有很多SeekBar竖立的例子,都是重新实现onDraw方法将画布旋转,但是我觉得那些都是化简为繁,也没深刻理解View这个基础类的强大之处,我的方式就是完美利用View的旋转属性
请注意,这里有两种做法:
第一种适合一些页面简单的地方,直接将SeekBar 旋转,优点是不需要布局嵌套了,但是需要小心翼翼调试好位置.
第二种更适合进度条的形式,那就是在SeekBar外面套一个ConstraintLayout,然后将SeekBar在旋转. 这种方式可以适合在一些复杂的页面中.
第一种
直接将SeekBar 旋转,优点是不需要布局嵌套了,但是需要小心翼翼调试好位置.适合一些简单的地方
效果图:
activity布局
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.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" android:background="@color/color_black_1" tools:context=".function.setting.system.view.SetScreenTimeoutActivity"> <TextView android:id="@+id/title" android:layout_width="match_parent" android:layout_height="76dp" android:text="@string/off_screen_time" android:textColor="@color/ColorWhite" android:textSize="22sp" android:gravity="center" android:background="@color/black" app:layout_constraintTop_toTopOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"/> <ImageView android:id="@+id/back" android:layout_width="wrap_content" android:layout_height="0dp" android:src="@mipmap/img_back_arrow" android:paddingLeft="20dp" app:layout_constraintTop_toTopOf="@id/title" app:layout_constraintBottom_toBottomOf="@id/title" app:layout_constraintLeft_toLeftOf="parent"/> <ImageView android:id="@+id/icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="100dp" android:src="@drawable/ic_screen_timeout" app:layout_constraintTop_toBottomOf="@id/title" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"/> <SeekBar android:id="@+id/seek_bar" android:layout_width="300dp" android:layout_height="70dp" android:rotationX="0.5" android:rotationY="0.5" android:rotation="270" android:thumb="@null" android:layout_marginTop="135dp" android:progressDrawable="@drawable/bg_seekbar" android:max="6" app:layout_constraintTop_toBottomOf="@id/icon" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"/> <ImageView android:id="@+id/add_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_add" android:layout_marginTop="55dp" app:layout_constraintLeft_toLeftOf="@id/seek_bar" app:layout_constraintRight_toRightOf="@id/seek_bar" app:layout_constraintTop_toBottomOf="@id/icon"/> <ImageView android:id="@+id/reduce_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_reduce" android:layout_marginTop="195dp" app:layout_constraintTop_toBottomOf="@id/add_icon" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"/> <TextView android:id="@+id/current_select_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="340dp" android:textSize="22sp" android:textColor="@color/ColorWhite" app:layout_constraintTop_toBottomOf="@id/icon" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"/> </androidx.constraintlayout.widget.ConstraintLayout>
这样里有一个需要注意的点,就是高度和宽度其实是互换的关系了.
进度背景
bg_seekbar.xml
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@android:id/background"> <shape android:shape="rectangle"> <size android:width="300dp" android:height="70dp"/> <solid android:color="#575757"/> <corners android:radius="88dp"/> </shape> </item> <item android:id="@android:id/secondaryProgress"> <clip> <shape> <solid android:color="#575757"/> </shape> </clip> </item> <item android:id="@android:id/progress"> <clip> <shape android:shape="rectangle"> <size android:width="300dp" android:height="70dp"/> <solid android:color="#FFFFFF"/> <corners android:radius="88dp"/> </shape> </clip> </item> </layer-list>
第二种
思想上与第一种一样,关键区别是外部嵌套一个ConstraintLayout用于控制布局旋转后的位置大小.
这种方式更适合进度条的形式,SeekBar外面套ConstraintLayout,然后将SeekBar在旋转. 这种方式可以适合在一些许多View需要配合的页面中. ,关键参考如下:
这里的关键代码就是:app:layout_constraintDimensionRatio="1:1" 其中构思,请自行品味
另外请注意,这里的thumb也会被旋转你需要准备一个相反旋转的thumb图片
<androidx.constraintlayout.widget.ConstraintLayout android:id="@+id/unlockLayout" android:layout_width="69dp" android:layout_height="0dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@id/layout"> <SeekBar android:id="@+id/seekBar" android:layout_width="0dp" android:layout_height="match_parent" android:rotationX="0.5" android:rotationY="0.5" android:rotation="90" android:paddingStart="50dp" android:paddingEnd="50dp" android:max="100" android:thumb="@drawable/snake_ic_lock_1" android:progressDrawable="@drawable/snake_seekbar_open_lock" app:layout_constraintDimensionRatio="1:1" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintLeft_toLeftOf="parent"/> </androidx.constraintlayout.widget.ConstraintLayout>
点子:实现一个多色阶渐变进度条(颜色取值进度条)
颜色取值的部分不说明,这个可以根据progress的位置来自定义取颜色值,这里重点说明的是怎么实现多色阶的渐变的背景。
效果图:
代码:
说明下为什么用代码实现,因为xml的shape属性根本不支持这么多颜色的渐变,在xml上的shape的gradient属性只支持三色阶渐变。当然,如果你直接放矢量图作为渐变色背景,那就不需要参考下面代码了。但是渐变色背景不能是位图,只能是矢量图。
如果你不太了解GradientDrawable,可以参考我这篇博客:https://www.cnblogs.com/guanxinjing/p/11142599.html
int[] colors = {Color.parseColor("#FF0000") , Color.parseColor("#FF00FF") , Color.parseColor("#0000FF") , Color.parseColor("#00FFFF") , Color.parseColor("#00FF00") , Color.parseColor("#FFFF00") , Color.parseColor("#FF0000")}; GradientDrawable gradientDrawable = new GradientDrawable(); gradientDrawable.setShape(GradientDrawable.RECTANGLE); gradientDrawable.setColors(colors); //添加颜色组 gradientDrawable.setCornerRadius(UnitConversionUtil.dip2px(getContext(), 10)); gradientDrawable.setOrientation(GradientDrawable.Orientation.LEFT_RIGHT);//设置渐变方向 gradientDrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT);//设置线性渐变 gradientDrawable.setDither(true); Drawable[] drawables = {gradientDrawable}; LayerDrawable layerDrawable = new LayerDrawable(drawables); layerDrawable.setId(0, android.R.id.background); mColorSeekBar.setProgressDrawable(layerDrawable);
点子:Thumb带文字
效果图:
import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.util.AttributeSet; import android.util.TypedValue; import android.view.MotionEvent; import android.widget.SeekBar; import androidx.annotation.ColorRes; import com.lwlx.ui.main.R; @SuppressLint("AppCompatCustomView") public class TextSeekBar extends SeekBar { private Paint mPaint = new Paint(); private float x; private float mTextSize = 18f; private int mColorId = R.color.main_color_9F621B; private float mWidth = 0f; private float mHeight = 0f; public TextSeekBar(Context context) { super(context); init(); } public TextSeekBar(Context context, AttributeSet attrs) { super(context, attrs); init(); } public TextSeekBar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } public TextSeekBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); init(); } private void init() { mPaint.setColor(getResources().getColor(mColorId)); mPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, mTextSize, getResources().getDisplayMetrics())); mPaint.setTextAlign(Paint.Align.CENTER); mPaint.setStrokeWidth(15); } public void setTextSize(float textSize) { this.mTextSize = textSize; invalidate(); } public void setTextColor(@ColorRes int id) { mColorId = id; invalidate(); } @Override protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); mWidth = MeasureSpec.getSize(widthMeasureSpec); mHeight = MeasureSpec.getSize(heightMeasureSpec); x = getProgress() * mWidth / 100 + getX(); } @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { x = event.getX(); } else if (event.getAction() == MotionEvent.ACTION_MOVE) { x = event.getX(); } else if (event.getAction() == MotionEvent.ACTION_UP) { x = event.getX(); } if (x < 0) { x = 0 + getPaddingLeft(); } else if (x > mWidth) { x = mWidth - getPaddingRight(); } return super.onTouchEvent(event); } @Override protected synchronized void onDraw(Canvas canvas) { super.onDraw(canvas); float y = (mHeight - (getPaddingTop() + getPaddingBottom())) / 2; canvas.drawText(String.valueOf(getProgress()), x, y + 5, mPaint); } }
End
本文来自博客园,作者:观心静 ,转载请注明原文链接:https://www.cnblogs.com/guanxinjing/p/11947457.html