比好看的一些自定义SeekBar
来源:互联网 发布:linux集成开发环境 编辑:程序博客网 时间:2024/04/30 22:36
看到了一个App自定义的SeekBar很有趣,尝试着自己做一个。
不废话,先上图,看是否是你期望的:
增加了背景图片的自定义,增加了Thumb的自定义。当然还有动画效果。会动画滑动到附近的点。具体代码稍后奉上...
啊。。。乱七八糟事儿太多,这几天都没时间整理
这个demo的点可以自定义数量,并增加回调。我就不写原理了...直接把代码传上去...有时间再写...
首先需要画出seekbar的背景drawable:
[java] view plain copy
- package com.zkbc.tougu.demo;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.ColorFilter;
- import android.graphics.LinearGradient;
- import android.graphics.Paint;
- import android.graphics.Rect;
- import android.graphics.RectF;
- import android.graphics.Shader;
- import android.graphics.drawable.Drawable;
- /**
- * 自定义seekBar背景图
- * Created by Rock Lee on 2016/6/21.
- */
- public class MySeekBarDrawable extends Drawable {
- int pointCount;
- int startColor;
- int centerColor;
- int endColor;
- private Paint paint;//画笔(背景)
- LinearGradient shader;
- private Paint paintCircle;//画笔-外圆
- private Paint paintCircleCenter;//画笔-内圆
- RectF rectF;//矩形上下左右的坐标
- int colors[] = new int[3];//三个颜色渐变(shader)
- float positions[] = new float[3];//渐变色的三个点(shader)
- public MySeekBarDrawable(int pointCount, int startColor, int centerColor, int endColor) {
- this.pointCount = pointCount * 2;//增加两点之间的中线
- this.startColor = startColor;
- this.centerColor = centerColor;
- this.endColor = endColor;
- paint = new Paint();
- paintCircle = new Paint();
- paintCircleCenter = new Paint();
- rectF = new RectF();
- }
- @Override
- public void draw(Canvas canvas) {
- final Rect bounds = getBounds();
- // 第1个点
- colors[0] = startColor;
- positions[0] = 0;
- // 第2个点
- colors[1] = centerColor;
- positions[1] = 0.5f;
- // 第3个点
- colors[2] = endColor;
- positions[2] = 1;
- //是否有中间色
- if (centerColor == 0) {
- shader = new LinearGradient(0f, 0f, bounds.width(), bounds.height(), startColor, endColor, Shader.TileMode.MIRROR);
- } else {
- shader = new LinearGradient(0f, 0f, bounds.width(), bounds.height(), colors, positions, Shader.TileMode.MIRROR);
- }
- paint.setShader(shader);
- paint.setStrokeCap(Paint.Cap.ROUND);// 圆角
- paint.setAntiAlias(true); // 消除锯齿
- paintCircle.setShader(shader);
- // paintCircle.setStyle(Paint.Style.STROKE); // 设置空心
- // paintCircle.setStrokeWidth(bounds.height()/2); // 设置笔画的宽度
- paintCircle.setAntiAlias(true); // 消除锯齿
- paintCircleCenter.setAntiAlias(true); // 消除锯齿
- paintCircleCenter.setColor(Color.WHITE);
- float lineHeight = bounds.height()/4.0f;
- rectF.set(0, bounds.centerY() - lineHeight, bounds.width(), bounds.centerY() + lineHeight);
- //绘制圆角矩形
- canvas.drawRoundRect(rectF, lineHeight, lineHeight, paint);
- float section = (float) bounds.width() / pointCount;
- for (int i = 1; i < pointCount; i++) {
- paint.setShader(null);
- paint.setColor(Color.WHITE);
- // paint.setStrokeWidth(1);
- float cx = section * i;//X轴圆心坐标
- if (i % 2 == 0) {
- canvas.drawLine(cx, bounds.centerY() - lineHeight, cx, bounds.centerY() + lineHeight, paint);
- } else {
- canvas.drawCircle(cx, bounds.centerY(), lineHeight*2, paintCircle);
- canvas.drawCircle(cx, bounds.centerY(), lineHeight, paintCircleCenter);
- }
- }
- }
- @Override
- public void setAlpha(int alpha) {
- paint.setAlpha(alpha);
- }
- @Override
- public void setColorFilter(ColorFilter colorFilter) {
- paint.setColorFilter(colorFilter);
- }
- @Override
- public int getOpacity() {
- return 1 - paint.getAlpha();
- }
- /**
- * MySeekBarDrawable Builder
- */
- public static class Builder {
- /**
- * 分割段数
- */
- int pointCount;
- /**
- * 起始颜色
- */
- int startColor;
- /**
- * 中间色
- */
- int centerColor;
- /**
- * 结束颜色
- */
- int endColor;
- /**
- * Sets the seekBar point count.
- *
- * @returns This Builder
- */
- public Builder setPointCount(int pointCount) {
- this.pointCount = pointCount;
- return this;
- }
- /**
- * Sets the seekBar start color.
- *
- * @param startColor start color in #AARRGGBB format.
- * @returns This Builder
- */
- public Builder setStartColor(int startColor) {
- this.startColor = startColor;
- return this;
- }
- /**
- * Sets the seekBar center color.
- *
- * @param centerColor center color in #AARRGGBB format.
- * @returns This Builder
- */
- public Builder setCenterColor(int centerColor) {
- this.centerColor = centerColor;
- return this;
- }
- /**
- * Sets the seekBar end color.
- *
- * @param endColor end color in #AARRGGBB format.
- * @returns This Builder
- */
- public Builder setEndColor(int endColor) {
- this.endColor = endColor;
- return this;
- }
- /**
- * Creates a new MySeekBarDrawable with the requested parameters
- *
- * @return New MySeekBarDrawableInstance
- */
- public MySeekBarDrawable create() {
- return new MySeekBarDrawable(pointCount, startColor, centerColor, endColor);
- }
- }
- }
第二步:自定义seekbar,并将我们的自定义drawable附上:
[java] view plain copy
- package com.zkbc.tougu.demo;
- import android.animation.Animator;
- import android.animation.AnimatorSet;
- import android.animation.ObjectAnimator;
- import android.content.Context;
- import android.content.res.TypedArray;
- import android.graphics.Bitmap;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.drawable.BitmapDrawable;
- import android.graphics.drawable.Drawable;
- import android.util.AttributeSet;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.view.animation.AccelerateDecelerateInterpolator;
- import android.widget.LinearLayout;
- import android.widget.PopupWindow;
- import android.widget.SeekBar;
- import android.widget.TextView;
- import com.zkbc.tougu.R;
- /**
- * 自定义seekBar
- * Created by Rock Lee on 2016/6/21.
- */
- public class MyNiceSeekBar extends SeekBar implements SeekBar.OnSeekBarChangeListener {
- private int pointCount;
- private int startColor;
- private int centerColor;
- private int endColor;
- public final int oneLength = 100;//每个隔断的刻度
- int risk;
- TextView centerText;
- Drawable thumbDrawable;
- View thumb;
- MySeekBarDrawable drawable;
- SeekBarInterface barInterface;//参数回调
- SeekBarOnDrawListener onDrawListener;//seekBar绘画监听
- private boolean mPopupStyle;//是否显示pop
- private boolean mThumbStyle;
- private int xOffset;
- private PopupWindow mPopup;
- private TextView mPopupTextView;
- private int mYLocationOffset;
- public MyNiceSeekBar(Context context) {
- this(context, null);
- }
- public MyNiceSeekBar(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
- public MyNiceSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- init(context, attrs);
- }
- private void init(Context context, AttributeSet attrs) {
- TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.MySeekBar);
- pointCount = mTypedArray.getInteger(R.styleable.MySeekBar_pointCount, 5);
- startColor = mTypedArray.getColor(R.styleable.MySeekBar_startColor, Color.GREEN);
- centerColor = mTypedArray.getColor(R.styleable.MySeekBar_centerColor, 0);
- endColor = mTypedArray.getColor(R.styleable.MySeekBar_endColor, Color.RED);
- mPopupStyle = mTypedArray.getBoolean(R.styleable.MySeekBar_popupStyle, false);
- mThumbStyle = mTypedArray.getBoolean(R.styleable.MySeekBar_popupStyle, false);
- xOffset = (int) mTypedArray.getDimension(R.styleable.MySeekBar_xOffset, 0);
- mYLocationOffset = (int) mTypedArray.getDimension(R.styleable.MySeekBar_yOffset, 0);
- mTypedArray.recycle();
- setMax(pointCount * 2 * oneLength);
- setProgress(3 * oneLength);
- setOnSeekBarChangeListener(this);
- drawable = new MySeekBarDrawable.Builder()
- .setPointCount(pointCount)
- .setStartColor(startColor)
- .setCenterColor(centerColor)
- .setEndColor(endColor).create();
- setProgressDrawable(drawable);
- initThumb((getProgress() / (2 * oneLength) + 1) + "");
- initHintPopup();
- }
- public void initThumb(String risk) {
- LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- thumb = inflater.inflate(R.layout.seekbar_thumb, null);
- centerText = (TextView) thumb.findViewById(R.id.text1);
- if (mThumbStyle) {
- centerText.setText(risk);
- }
- thumbDrawable = convertViewToDrawable(thumb);
- setThumb(thumbDrawable);
- }
- public static Drawable convertViewToDrawable(View view) {
- view.measure(
- View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
- View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
- view.layout(0, 0, view.getMeasuredHeight(), view.getMeasuredHeight());
- view.setDrawingCacheEnabled(true);
- Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache(true));
- Drawable drawable = new BitmapDrawable(null, bitmap);
- view.destroyDrawingCache();
- view.setDrawingCacheEnabled(false);
- return drawable;
- }
- @Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
- super.onSizeChanged(w, h, oldw, oldh);
- }
- @Override
- protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- setMeasuredDimension(getMeasuredWidth(), getMeasuredHeight());
- }
- @Override
- protected synchronized void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- if (onDrawListener != null) {
- onDrawListener.onDrawListener();
- }
- }
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- //进度改变时调用
- risk = getTargetProgress(seekBar) / (2 * oneLength) + 1;
- String popupText;
- if (barInterface != null) {
- int targetProgress = getTargetProgress(seekBar);
- popupText = barInterface.progressChangeCallBack(this, getProgress(), targetProgress);
- mPopupTextView.setText(popupText != null ? popupText : String.valueOf(targetProgress));
- }
- if (mPopupStyle && mPopup != null) {
- showPopup();
- mPopup.update(this, (int) getXPosition(getProgress(), mPopup.getContentView()), -(this.getHeight() + mPopup.getContentView().getMeasuredHeight() + mYLocationOffset), -1, -1);
- } else {
- hidePopup();
- }
- }
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
- //进度条开始拖动的时候调用
- showPopup();
- centerText.setText("");
- thumbDrawable = convertViewToDrawable(thumb);
- setThumb(thumbDrawable);
- }
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
- //进度条停止拖动的时候调用
- int targetProgress = getTargetProgress(seekBar);
- dodo(seekBar.getProgress(), targetProgress);
- if (mThumbStyle) {
- centerText.setText(risk + "");
- }
- thumbDrawable = convertViewToDrawable(thumb);
- setThumb(thumbDrawable);
- }
- /**
- * 赋值+执行动画
- *
- * @param progressText 当前滑动的点
- * @param targetProgress 自动滑动到目标点
- */
- public void dodo(int progressText, int targetProgress) {
- AnimatorSet animation = new AnimatorSet();
- ObjectAnimator progressAnimation = ObjectAnimator.ofInt(this, "progress",
- progressText, targetProgress);
- progressAnimation.setDuration(300);
- progressAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
- //增加动画监听
- progressAnimation.addListener(new Animator.AnimatorListener() {
- @Override
- public void onAnimationStart(Animator animation) {
- }
- @Override
- public void onAnimationEnd(Animator animation) {
- hidePopup();
- }
- @Override
- public void onAnimationCancel(Animator animation) {
- hidePopup();
- }
- @Override
- public void onAnimationRepeat(Animator animation) {
- }
- });
- animation.playTogether(progressAnimation);
- animation.start();
- }
- /**
- * 选中回调
- *
- * @param barInterface 回调监听
- */
- public void setSeekBarCallBack(SeekBarInterface barInterface) {
- this.barInterface = barInterface;
- }
- /**
- * 绘画监听接口
- *
- * @param onDrawListener 绘画监听实现接口
- */
- public void setOnDrawListener(SeekBarOnDrawListener onDrawListener) {
- this.onDrawListener = onDrawListener;
- }
- /**
- * 是否显示pop
- * @param style 是否显示pop
- */
- public void setPopupStyle(boolean style) {
- mPopupStyle = style;
- }
- private void initHintPopup() {
- String popupText = null;
- if (barInterface != null) {
- int targetProgress = getTargetProgress(this);
- popupText = barInterface.progressChangeCallBack(this, getProgress(), targetProgress);
- }
- LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- final View undoView = inflater.inflate(R.layout.popup, null);
- mPopupTextView = (TextView) undoView.findViewById(R.id.text);
- mPopupTextView.setText(popupText != null ? popupText : String.valueOf(getProgress()));
- mPopup = new PopupWindow(undoView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, false);
- mPopup.getContentView().measure(0, 0);//获取测量后的popWindow高度
- mPopup.setAnimationStyle(R.style.fade_animation);
- }
- private void showPopup() {
- if (mPopupStyle) {
- mPopup.showAsDropDown(this, (int) getXPosition(getProgress(), mPopup.getContentView()), -(this.getHeight() + mPopup.getContentView().getMeasuredHeight() + mYLocationOffset));
- }
- }
- private void hidePopup() {
- if (mPopup != null && mPopup.isShowing()) {
- mPopup.dismiss();
- }
- }
- /**
- * 获取X坐标
- *
- * @param progress 进度
- * @param v 在seekBar上显示的View
- * @return X
- */
- private float getXPosition(int progress, View v) {
- //seekBar总宽度包含ThumbOffset两边
- float val = (((float) progress * ((float) getWidth())) / (float) getMax());
- int textWidth = v.getMeasuredWidth();
- float textCenter = (textWidth / 2.0f) + xOffset;
- return val - textCenter;
- }
- /**
- * 获取目标进度
- *
- * @return 返回目标进度
- */
- private int getTargetProgress(SeekBar seekBar) {
- int targetProgress;//进度参数回调默认值
- int proNow = seekBar.getProgress();//当前点
- int yu = proNow % oneLength;//取余数
- if ((proNow / oneLength) % 2 == 0) {
- //是否为满进度,满进度回退一格
- targetProgress = proNow == getMax() ? proNow - oneLength : proNow + oneLength - yu;
- } else {
- targetProgress = proNow - yu;
- }
- return targetProgress;
- }
- /**
- * 设置推荐坐标
- *
- * @param recommendPosition 显示在第几个点,从0开始
- * @param ll_recommend
- */
- public void setRecommendPosition(int recommendPosition, View ll_recommend) {
- int progress = oneLength + recommendPosition * 2 * oneLength;
- float x = getXPosition(progress, ll_recommend);
- LinearLayout.LayoutParams pa = (LinearLayout.LayoutParams) ll_recommend.getLayoutParams();
- pa.setMargins((int) x, 0, 0, 0);
- ll_recommend.setLayoutParams(pa);
- }
[java] view plain copy
- public int getRisk() {
- return risk;
- }
- public void setRisk(int risk) {
- this.risk = risk;
- }
- /**
- * 是否显示Thumb数字
- * @param mThumbStyle
- */
- public void setThumbStyle(boolean mThumbStyle) {
- this.mThumbStyle = mThumbStyle;
- }
使用方式:
[java] view plain copy
- private void initSeekbar() {
- recommend = 3;
- mSeekBar1.initThumb((mSeekBar1.getProgress() / (2 * mSeekBar1.oneLength)) + "");
- mSeekBar1.setSeekBarCallBack(new SeekBarInterface() {
- @Override
- public String progressChangeCallBack(MyNiceSeekBar myNiceSeekBar, int progress, int targetProgress) {
- risk = myNiceSeekBar.getRisk();
- myNiceSeekBar.setRisk(risk);
- //返回Pop上需要显示的字符串
- return "节点" + risk;
- }
- });
- mSeekBar1.setOnDrawListener(new SeekBarOnDrawListener() {
- @Override
- public void onDrawListener() {
- mSeekBar1.setRecommendPosition(recommend, ll_recommend);
- }
- });
- }
0 0
- 比好看的一些自定义SeekBar
- 好看的 自定义AlertDialog
- 自定义好看的吐司
- 一些好看的color
- SeekBar 的自定义样式
- 自定义竖着的SeekBar
- 自定义风格的SeekBar
- 自定义Seekbar的注意事项
- 自定义半圆的SeekBar
- 自定义SeekBar的外观
- 自定义seekBar的样式
- seekbar的一些感想
- 【SeekBar】Android 自定义漂亮的SeekBar样式
- 自定义实现好看的toast
- android 好看的自定义日历
- 收藏的一些好看视频
- 摄影:一些好看的拍摄
- Android的SeekBar自定义样式
- loadrunner动态从mysql取值 [需要下载跟数据库服务器一致的dll,32位或64位]
- 线程基础:线程(2)——JAVA中的基本线程操作(上)
- [学习笔记]设计模式[2]-{装饰者模式}
- NHibernate之旅(10):探索父子(一对多)关联查询
- Apache OpenNLP下载
- 比好看的一些自定义SeekBar
- 什么是Docker
- Windows 10四大版本官方对比:国人肯定专业版
- 获取系统/sdcard存储空间路径无效的处理
- 同步/异步 与 阻塞/非阻塞的区别
- 线程基础:线程(3)——JAVA中的基本线程操作(中)
- [学习笔记]设计模式[4]-{单件模式}
- 数据库(第一范式,第二范式,第三范式)
- QT4.7自定义标题栏简单实现