如何在 Switch/SwitchCompat 按钮中设置宽度和跟踪文本并实现此结果? (附图片和GIF) admin 2023-05-25 09:48:01 技术标签: 【中文标题】如何在 Switch/SwitchCompat 按钮中设置宽度和跟踪文本并实现此结果? (附图片和GIF)【英文标题】:How to set width and track text in a Switch/SwitchCompat button and achieve this result? (Image and GIF attached) 【发布时间】:2019-02-03 11:04:13 【问题描述】: 我需要像这样在我的应用中实现一个按钮我使用了 SwitchCompat 按钮,但我到达的最近的位置是,有两个主要问题:1 - 当屏幕尺寸改变(drawable 被截断,变得太小等)时,按钮的宽度不能正确调整,宽度正确占据父视图很重要(a包围它的小线性布局)2 -我无法理解如何获得 Switch Track 中的字母是否可以通过开关按钮实现此结果?如何?我应该使用另一个视图而不是切换按钮吗?哪一个?我偶然发现了这个项目,但它似乎有点过时了https://github.com/pellucide/android-Switch-Demo-pre-4.0/tree/master/ 【问题讨论】: 我不认为你可以使用默认的Switch 组件轻松实现这一点。您可能应该使用自定义视图方法 @MatPag 我应该怎么做?我不知道 创建自定义视图并不容易。至少需要一些框架技能。您可以尝试从以下内容开始:github.com/GwonHyeok/StickySwitch 作为基本视图,然后根据您的需要对其进行更改 【参考方案1】: 例如:class SwitchCompatEx : SwitchCompat companion object val TRACK_COLOR = 0xFFFFFFFF.toInt() val TRACK_STROKE_WIDTH = 2f.dp2Px.toInt() val TRACK_STROKE_COLOR = 0xFF00A1FF.toInt() val TRACK_LABEL_COLOR = 0xFF00A1FF.toInt() val TRACK_LABEL_SIZE = 14f.sp2Px val THUMB_COLOR = 0xFF00A1FF.toInt() val THUMB_LABEL_COLOR = 0xFFFFFFFF.toInt() val THUMB_LABEL_SIZE = 14f.sp2Px fun drawLabel(canvas: Canvas, bounds: Rect, paint: Paint, text: CharSequence?) text ?: return val tb = RectF(); tb.right = paint.measureText(text, 0, text.length) tb.bottom = paint.descent() - paint.ascent() tb.left += bounds.centerX() - tb.centerX() tb.top += bounds.centerY() - tb.centerY() - paint.ascent() canvas.drawText(text.toString(), tb.left, tb.top, paint) private inline val Float.sp2Px get() = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, this, Resources.getSystem().displayMetrics) private inline val Float.dp2Px get() = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this, Resources.getSystem().displayMetrics) private val trackLabelPaint = Paint().apply isAntiAlias = true textSize = TRACK_LABEL_SIZE color = TRACK_LABEL_COLOR private val thumbLabelPaint = Paint().apply isAntiAlias = true textSize = THUMB_LABEL_SIZE color = THUMB_LABEL_COLOR private val thumbLabel get () = if (isChecked) textOn else textOff constructor(context: Context?) : super(context) constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) init background = null trackDrawable = TrackDrawable() thumbDrawable = ThumbDrawable() override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) super.onSizeChanged(w, h, oldw, oldh) (trackDrawable as GradientDrawable).setSize(w, h) (thumbDrawable as GradientDrawable).setSize(w / 2, h) inner class TrackDrawable : GradientDrawable() private val textOffBounds = Rect() private val textOnBounds = Rect() init setColor(TRACK_COLOR) setStroke(TRACK_STROKE_WIDTH, TRACK_STROKE_COLOR) override fun onBoundsChange(r: Rect) super.onBoundsChange(r) cornerRadius = r.height() / 2f textOffBounds.set(r) textOffBounds.right /= 2 textOnBounds.set(textOffBounds) textOnBounds.offset(textOffBounds.right, 0) override fun draw(canvas: Canvas) super.draw(canvas) drawLabel(canvas, textOffBounds, trackLabelPaint, textOff) drawLabel(canvas, textOnBounds, trackLabelPaint, textOn) inner class ThumbDrawable : GradientDrawable() private val thumbLabelBounds = Rect() init setColor(THUMB_COLOR) override fun onBoundsChange(r: Rect) super.onBoundsChange(r) cornerRadius = r.height() / 2f thumbLabelBounds.set(r) override fun draw(canvas: Canvas) super.draw(canvas) drawLabel(canvas, thumbLabelBounds, thumbLabelPaint, thumbLabel) ......还可以查看此Custom view components 教程。 希望对你有帮助 【讨论】: 非常感谢您的详细回答!将尝试并提供一些反馈! :) 我试过了,它在带有 api 17 的模拟器中完美运行!问题是,至少对于 api 24 和 27,它不能正确显示,拇指和轨道根本不显示(唯一显示的是设置的 texton 和 textoff)。有什么建议?谢谢:) 很有趣和奇怪的事实,自定义视图类在所有 api 版本中正确显示后我在同一个活动中按随机编辑文本视图并打开软键盘" 嗯,有趣,听起来可绘制边界有问题。我稍后会检查它。谢谢 是的,这似乎是问题所在,我尝试调试它但无法弄清楚...如果您以编程方式设置新高度(在创建所有视图之后)它也可以工作。我试图改变 onStart 调用中的高度,但它没有改变任何东西......再次感谢您的帮助,如果您找出问题所在,我很乐意看到解释!【参考方案2】: 在搞砸之后,我通过在每个可绘制对象的 onDraw 函数末尾添加以下两行来修复渲染问题 invalidate() requestLayout() 【讨论】:以上是关于如何在 Switch/SwitchCompat 按钮中设置宽度和跟踪文本并实现此结果? (附图片和GIF)的主要内容,如果未能解决你的问题,请参考以下文章 如何在Win8系统下安装使用Mathcad15 Java中的关键字volatitle 您可能还会对下面的文章感兴趣: 相关文章 浏览器打不开网址提示“ERR_CONNECTION_TIMED_OUT”错误代码的解决方法 如何安装ocx控件 VMware的虚拟机为啥ip地址老是自动变化 vbyone和EDP区别 linux/debian到底怎么重启和关机 苹果平板键盘被弄到上方去了,如何调回正常? 机器学习常用距离度量 如何查看kindle型号