如何修改自定义AppCompatSeekBar在容器内的垂直位置至底部?
这个问题我之前也碰到过!AppCompatSeekBar默认会把进度条(Bar)垂直居中绘制,当你为了放上方文字给View加高后,底部自然就会出现空白。你之前找到的Window相关代码完全不对路——那是用来调整整个Activity窗口位置的,和View内部的绘制半毛钱关系都没有,当然没用啦。
给你两个靠谱的解决思路,推荐第一种,直接在onDraw里调整画布位置:
方法一:平移画布让进度条靠底绘制
在你重写的onDraw方法里,先把画布向下平移,让默认的SeekBar内容(进度条、滑块)绘制在View底部,然后再恢复画布状态绘制上方的文字。这样既不影响文字位置,又能让Bar精准贴底。
修改你的onDraw方法如下:
@Override protected void onDraw(Canvas canvas) { // 先处理进度条的位置,移到View底部 Drawable progressDrawable = getProgressDrawable(); if (progressDrawable != null) { int barHeight = progressDrawable.getIntrinsicHeight(); // 计算平移距离:View总高度 - 底部内边距 - 进度条自身高度 int translateY = getHeight() - getPaddingBottom() - barHeight; // 保存当前画布状态,避免影响后续文字绘制 canvas.save(); // 把画布向下平移,让进度条从底部开始绘制 canvas.translate(0, translateY); // 调用父类方法绘制默认的SeekBar内容(进度条、滑块) super.onDraw(canvas); // 恢复画布到原来的状态,准备绘制文字 canvas.restore(); } else { // 极端情况:如果获取不到进度条Drawable,就按默认逻辑绘制 super.onDraw(canvas); } // 你的文字绘制逻辑保持不变 String text1 = getResources().getString(R.string.your_text1); // 替换成你的资源 String text2 = getResources().getString(R.string.your_text2); float text2Width = lettersPaint.measureText(text2); String progressText = String.valueOf(getProgress()); float progressTextWidth = numberPaint.measureText(progressText); int middleHor = getWidth() / 2; canvas.drawText(text1, getPaddingLeft(), 40, lettersPaint); canvas.drawText(text2, getWidth() - text2Width - getPaddingRight(), 40, lettersPaint); canvas.drawText(progressText, middleHor - (progressTextWidth / 2), 50, numberPaint); }
方法二:通过内边距调整进度条位置
如果你不想动画布,也可以通过设置顶部内边距,把进度条“挤”到底部。不过这个方法需要注意View高度的计算,适合固定高度的场景:
在你的init方法里添加:
private void init() { lettersPaint = new Paint(); numberPaint = new Paint(); // ... 你的画笔样式设置 ... // 调整内边距,让进度条靠底 Drawable progressDrawable = getProgressDrawable(); if (progressDrawable != null) { int barHeight = progressDrawable.getIntrinsicHeight(); // 顶部内边距 = View总高度 - 进度条高度 - 底部内边距 // 注意:如果View是wrap_content,需要先重写onMeasure指定高度,否则getHeight()可能不准确 int topPadding = getHeight() - barHeight - getPaddingBottom(); setPadding(getPaddingLeft(), topPadding, getPaddingRight(), getPaddingBottom()); } }
为什么之前的代码无效?
那段Window相关的代码是用来调整整个Activity窗口在屏幕上的位置的,和你自定义SeekBar内部的绘制逻辑完全无关,所以对Bar的位置没有任何影响,自然无效。
用第一种方法就能完美实现你要的效果:Bar贴在View底部,上方显示文字,不会有多余的空白。
内容的提问来源于stack exchange,提问作者Chisko
相关产品推荐
相关产品推荐

