Android 自定义SeekBar显示进度百分比(1)

文章详细描述了一个Android组件中的`onDraw`方法,涉及绘制滑动条效果,包括透明度处理和触摸事件的响应,如位置计算和背景颜色变化。同时提到了`onTouchEvent`中的触摸处理逻辑和背景颜色调整机制。
摘要由CSDN通过智能技术生成

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

if (!placedBall)

placeBall();

if (value == min) {

// Crop line to transparent effect

Bitmap bitmap = Bitmap.createBitmap(canvas.getWidth(),

canvas.getHeight(), Bitmap.Config.ARGB_8888);

Canvas temp = new Canvas(bitmap);

Paint paint = new Paint();

paint.setColor(Color.parseColor(“#B0B0B0”));

paint.setStrokeWidth(Utils.dpToPx(2, getResources()));

temp.drawLine(getHeight() / 2, getHeight() / 2, getWidth()

  • getHeight() / 2, getHeight() / 2, paint);

Paint transparentPaint = new Paint();

transparentPaint.setColor(getResources().getColor(

android.R.color.transparent));

transparentPaint.setXfermode(new PorterDuffXfermode(

PorterDuff.Mode.CLEAR));

temp.drawCircle(ViewHelper.getX(ball) + ball.getWidth() / 2,

ViewHelper.getY(ball) + ball.getHeight() / 2,

ball.getWidth() / 2, transparentPaint);

canvas.drawBitmap(bitmap, 0, 0, new Paint());

} else {

Paint paint = new Paint();

paint.setColor(Color.parseColor(“#B0B0B0”));

paint.setStrokeWidth(Utils.dpToPx(2, getResources()));

canvas.drawLine(getHeight() / 2, getHeight() / 2, getWidth()

  • getHeight() / 2, getHeight() / 2, paint);

paint.setColor(backgroundColor);

float division = (ball.xFin - ball.xIni) / (max - min);

int value = this.value - min;

canvas.drawLine(getHeight() / 2, getHeight() / 2, value * division

  • getHeight() / 2, getHeight() / 2, paint);

}

if (press && !showNumberIndicator) {

Paint paint = new Paint();

paint.setColor(backgroundColor);

paint.setAntiAlias(true);

canvas.drawCircle(ViewHelper.getX(ball) + ball.getWidth() / 2,

getHeight() / 2, getHeight() / 3, paint);

}

invalidate();

}

@Override

public boolean onTouchEvent(MotionEvent event) {

isLastTouch = true;

if (isEnabled()) {

if (event.getAction() == MotionEvent.ACTION_DOWN

|| event.getAction() == MotionEvent.ACTION_MOVE) {

if (numberIndicator != null

&& numberIndicator.isShowing() == false)

numberIndicator.show();

if ((event.getX() <= getWidth() && event.getX() >= 0)) {

press = true;

// calculate value

int newValue = 0;

float division = (ball.xFin - ball.xIni) / (max - min);

if (event.getX() > ball.xFin) {

newValue = max;

} else if (event.getX() < ball.xIni) {

newValue = min;

} else {

newValue = min

  • (int) ((event.getX() - ball.xIni) / division);

}

if (value != newValue) {

value = newValue;

if (onValueChangedListener != null)

onValueChangedListener.onValueChanged(newValue);

}

// move ball indicator

float x = event.getX();

x = (x < ball.xIni) ? ball.xIni : x;

x = (x > ball.xFin) ? ball.xFin : x;

ViewHelper.setX(ball, x);

ball.changeBackground();

// If slider has number indicator

if (numberIndicator != null) {

// move number indicator

numberIndicator.indicator.x = x;

numberIndicator.indicator.finalY = Utils

.getRelativeTop(this) - getHeight() / 2;

numberIndicator.indicator.finalSize = getHeight() / 2;

numberIndicator.numberIndicator.setText(“”);

}

} else {

press = false;

isLastTouch = false;

if (numberIndicator != null)

numberIndicator.dismiss();

}

} else if (event.getAction() == MotionEvent.ACTION_UP

|| event.getAction() == MotionEvent.ACTION_CANCEL) {

if (numberIndicator != null)

numberIndicator.dismiss();

isLastTouch = false;

press = false;

}

}

return true;

}

/**

  • Make a dark color to press effect

  • @return

*/

protected int makePressColor() {

int r = (this.backgroundColor >> 16) & 0xFF;

int g = (this.backgroundColor >> 8) & 0xFF;

int b = (this.backgroundColor >> 0) & 0xFF;

r = (r - 30 < 0) ? 0 : r - 30;

g = (g - 30 < 0) ? 0 : g - 30;

b = (b - 30 < 0) ? 0 : b - 30;

return Color.argb(70, r, g, b);

}

private void placeBall() {

ViewHelper.setX(ball, getHeight() / 2 - ball.getWidth() / 2);

ball.xIni = ViewHelper.getX(ball);

ball.xFin = getWidth() - getHeight() / 2 - ball.getWidth() / 2;

ball.xCen = getWidth() / 2 - ball.getWidth() / 2;

placedBall = true;

}

// GETERS & SETTERS

public OnValueChangedListener getOnValueChangedListener() {

return onValueChangedListener;

}

public void setOnValueChangedListener(

OnValueChangedListener onValueChangedListener) {

this.onValueChangedListener = onValueChangedListener;

}

public int getValue() {

return value;

}

public void setValue(final int value) {

if (placedBall == false)

post(new Runnable() {

@Override

public void run() {

setValue(value);

}

});

else {

this.value = value;

float division = (ball.xFin - ball.xIni) / max;

ViewHelper.setX(ball,

value * division + getHeight() / 2 - ball.getWidth() / 2);

ball.changeBackground();

}

}

public int getMax() {

return max;

}

public void setMax(int max) {

this.max = max;

}

public int getMin() {

return min;

}

public void setMin(int min) {

this.min = min;

}

public boolean isShowNumberIndicator() {

return showNumberIndicator;

}

public void setShowNumberIndicator(boolean showNumberIndicator) {

this.showNumberIndicator = showNumberIndicator;

numberIndicator = (showNumberIndicator) ? new NumberIndicator(

getContext()) : null;

}

@Override

public void setBackgroundColor(int color) {

backgroundColor = color;

if (isEnabled())

beforeBackground = backgroundColor;

}

boolean placedBall = false;

class Ball extends View {

float xIni, xFin, xCen;

public Ball(Context context) {

super(context);

setBackgroundResource(R.drawable.background_switch_ball_uncheck);

}

public void changeBackground() {

if (value != min) {

setBackgroundResource(R.drawable.background_checkbox);

LayerDrawable layer = (LayerDrawable) getBackground();

GradientDrawable shape = (GradientDrawable) layer

.findDrawableByLayerId(R.id.shape_bacground);

shape.setColor(backgroundColor);

} else {

setBackgroundResource(R.drawable.background_switch_ball_uncheck);

}

}

}

// Slider Number Indicator

class NumberIndicator extends Dialog {

Indicator indicator;

TextView numberIndicator;

public NumberIndicator(Context context) {

super(context, android.R.style.Theme_Translucent);

}

@Override

protected void onCreate(Bundle savedInstanceState) {

requestWindowFeature(Window.FEATURE_NO_TITLE);

super.onCreate(savedInstanceState);

setContentView(R.layout.number_indicator_spinner);

setCanceledOnTouchOutside(false);

RelativeLayout content = (RelativeLayout) this

.findViewById(R.id.number_indicator_spinner_content);

indicator = new Indicator(this.getContext());

content.addView(indicator);

numberIndicator = new TextView(getContext());

numberIndicator.setTextColor(Color.WHITE);

numberIndicator.setGravity(Gravity.CENTER);

content.addView(numberIndicator);

indicator.setLayoutParams(new RelativeLayout.LayoutParams(

RelativeLayout.LayoutParams.FILL_PARENT,

RelativeLayout.LayoutParams.FILL_PARENT));

}

@Override

public void dismiss() {

super.dismiss();

indicator.y = 0;

indicator.size = 0;

indicator.animate = true;

}

@Override

public void onBackPressed() {

}

}

class Indicator extends RelativeLayout {

// Position of number indicator

float x = 0;

float y = 0;

// Size of number indicator

float size = 0;

// Final y position after animation

float finalY = 0;

// Final size after animation

float finalSize = 0;

boolean animate = true;

boolean numberIndicatorResize = false;

public Indicator(Context context) {

super(context);

setBackgroundColor(getResources().getColor(

android.R.color.transparent));

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

if (numberIndicatorResize == false) {

LayoutParams params = (LayoutParams) numberIndicator.numberIndicator

.getLayoutParams();

最后

其实要轻松掌握很简单,要点就两个:

  1. 找到一套好的视频资料,紧跟大牛梳理好的知识框架进行学习。
  2. 多练。 (视频优势是互动感强,容易集中注意力)

你不需要是天才,也不需要具备强悍的天赋,只要做到这两点,短期内成功的概率是非常高的。

对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。

阿里P7Android高级教程

下面资料部分截图,诚意满满:特别适合有3-5年开发经验的Android程序员们学习。

附送高清脑图,高清知识点讲解教程,以及一些面试真题及答案解析。送给需要的提升技术、近期面试跳槽、自身职业规划迷茫的朋友们。

Android核心高级技术PDF资料,BAT大厂面试真题解析;

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!
s) numberIndicator.numberIndicator

.getLayoutParams();

最后

其实要轻松掌握很简单,要点就两个:

  1. 找到一套好的视频资料,紧跟大牛梳理好的知识框架进行学习。
  2. 多练。 (视频优势是互动感强,容易集中注意力)

你不需要是天才,也不需要具备强悍的天赋,只要做到这两点,短期内成功的概率是非常高的。

对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。

阿里P7Android高级教程

下面资料部分截图,诚意满满:特别适合有3-5年开发经验的Android程序员们学习。

[外链图片转存中…(img-kCUoCclq-1714573414235)]

附送高清脑图,高清知识点讲解教程,以及一些面试真题及答案解析。送给需要的提升技术、近期面试跳槽、自身职业规划迷茫的朋友们。

Android核心高级技术PDF资料,BAT大厂面试真题解析;
[外链图片转存中…(img-YC0IYiiW-1714573414236)]
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

  • 19
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android中,可以通过自定义SeekBar实现数字滑动功能。首先,在布局文件中定义自定义SeekBar的样式,可以使用ProgressBar来实现。如下所示: ``` <ProgressBar android:id="@+id/customSeekBar" style="@style/Widget.AppCompat.ProgressBar.Horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="100" android:progress="50" android:progressDrawable="@drawable/custom_seekbar_progress" android:thumb="@drawable/custom_seekbar_thumb" /> ``` 在drawable文件夹下创建custom_seekbar_progress.xml和custom_seekbar_thumb.xml来定义SeekBar的背景和滑块样式。在custom_seekbar_progress.xml中,可以使用shape和gradient标签来定义进度条的背景样式。在custom_seekbar_thumb.xml中,可以使用shape标签来定义滑块的样式。 接下来,在Activity或Fragment中找到SeekBar的实例,并设置OnSeekBarChangeListener监听器。在监听器中,通过getProgress方法获取SeekBar进度值,并根据需要进行相应的处理。例如,可以在TextView中显示SeekBar进度值,如下所示: ``` SeekBar customSeekBar = findViewById(R.id.customSeekBar); final TextView progressTextView = findViewById(R.id.progressTextView); customSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { progressTextView.setText(String.valueOf(progress)); } @Override public void onStartTrackingTouch(SeekBar seekBar) { // 当开始滑动SeekBar时执行的操作 } @Override public void onStopTrackingTouch(SeekBar seekBar) { // 当结束滑动SeekBar时执行的操作 } }); ``` 通过设置OnSeekBarChangeListener监听器,可以在SeekBar滑动时实时更新进度值,并进行相应的处理操作。根据自己的需求,可以在onProgressChanged、onStartTrackingTouch和onStopTrackingTouch方法中添加自定义的逻辑。 以上就是使用自定义SeekBar实现数字滑动的简单方法。可以根据自己的需求进行进一步的定制和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值