安卓:具有自定义图像的SeekBar

27

我有一个带有自定义Drawable的SeekBar。进度元素不是精确地从左侧呈现,而是移到右侧。我该如何避免这种情况?

在此输入图片描述

<SeekBar
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@android:id/summary"
    android:background="@null"

    android:progressDrawable="@drawable/seekbar"
    android:thumb="@drawable/seekbar_thumb"/>

拖动条布局文件: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"
        android:drawable="@drawable/seekbar_background"/>
    <item android:id="@android:id/progress">
        <clip android:drawable="@drawable/seekbar_progress" />
    </item>

</layer-list>

滑动条背景 seekbar_background.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="line">

    <stroke android:width="2dp" android:color="@color/colorNeutral" />

</shape>

拖动条进度.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="line">

    <stroke
        android:width="4dp"
        android:color="@color/colorAccentDark" />
</shape>

编辑:

如评论所述,如果两个宽度都相同,则问题将消失。但是我需要通过drawable使用不同的宽度,这可能吗?也许不仅仅是线条,可以使用不同的形状吗?


尝试将 android:gravity="left|top" 添加到进度中。 - Anoop Kanyan
是的,我尝试了,但没有任何效果。 - Michal
进度条的宽度怎么样?尝试将其更改为2dp,以确定是否导致问题。 - Anoop Kanyan
在 seekbar_progress 内部描边。 - Anoop Kanyan
这个可以工作,但如果我需要四位小数的进度怎么办? - Michal
显示剩余3条评论
6个回答

15

我不能解释为什么在绘制笔画时会出现问题,我认为这与笔画的宽度有关,但我还没有找到源来验证。

修复叠加

要解决手头的问题,您只需在左侧设置inset1dp2dp的值都可以正常绘制拖动条。

注意:使用此方法不应该存在背景过短,在低进度值下不可见的风险,因为无论如何,拇指都会覆盖并隐藏它。

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@android:id/background"
        android:drawable="@drawable/seekbar_background"
        android:left="2dp"><!-- or 1dp -->
    </item>
    <item android:id="@android:id/progress">
        <clip android:drawable="@drawable/seekbar_progress"/>
    </item>
</layer-list>

6

观察

当您使用形状可绘制对象创建一条线时,它会将左右填充(从使用此可绘制对象的视图中)等于其描边宽度的一半。

解决方法

您需要使用嵌套可绘制对象包装进度背景,然后将其设置为进度背景。嵌套可绘制对象可以像以下示例一样-

inset_seekbar_background.xml

<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/seekbar_progress"
    android:insetLeft="2dp"
    android:insetRight="2dp" />

你的最终 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"
        android:drawable="@drawable/inset_seekbar_background"/>
    <item android:id="@android:id/progress">
        <clip android:drawable="@drawable/seekbar_progress" />
    </item>

</layer-list>

备选项

1.您可以像默认的材料设计一样使用九宫格图片作为线条-

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@android:id/background"
        android:drawable="@drawable/abc_scrubber_primary_mtrl_alpha" />
    <item android:id="@android:id/secondaryProgress">
        <scale android:scaleWidth="100%">
            <selector>
                <item android:state_enabled="false">
                    <color android:color="@android:color/transparent" />
                </item>
                <item android:drawable="@drawable/abc_scrubber_primary_mtrl_alpha" />
            </selector>
        </scale>
    </item>
    <item android:id="@android:id/progress">
        <scale android:scaleWidth="100%">
            <selector>
                <item android:state_enabled="true">
                    <color android:color="@android:color/transparent" />
                </item>
                <item android:drawable="@drawable/abc_scrubber_primary_mtrl_alpha" />
            </selector>
        </scale>
    </item>
</layer-list><!-- From: file:/usr/local/google/buildbot/src/googleplex-android/mnc-supportlib-release/frameworks/support/v7/appcompat/res/drawable/abc_seekbar_track_material.xml -->

这里输入图片描述 这里输入图片描述 这里输入图片描述 这里输入图片描述

2.在Android样式中,您可以使用不同的颜色设置主题:

<style name="AppTheme.SeekBar">
        <item name="colorPrimary">@color/colorAccent</item>
        <item name="colorPrimaryDark">@color/colorPrimary</item>
        <item name="colorAccent">@color/colorPrimaryDark</item>
</style>

这里我使用了SeekBar的所有选项-

            <SeekBar 
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:theme="@style/AppTheme.SeekBar" />

            <SeekBar
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

            <SeekBar
                android:layerType="software"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:progressDrawable="@drawable/seekbar" />

这里是输出结果- 输入图像描述

3

尝试使用宽度为4dp(转换为px)的.9.png可绘制对象。

保持顶部和底部的1 dp透明。

选择在中心2dp处添加所需颜色的背景。

这样既可以使背景和进度条具有相同的宽度,但背景看起来比进度条更窄。


3

由于问题正在进行中,我认为它们两个应该具有相同的宽度

但是你在进度条中设置了宽度 = 4 android:width="4dp"

而SeekBar的宽度为2 android:width="2dp"

请将它们匹配为2或4,不要使用不同的值


经过长时间的研究,我认为你不能这样做,也许你可以尝试将填充零。 - Mina Fawzy

2
尝试像这样使用 android:layout_marginLeft="-3dp"-2dp
<SeekBar
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@android:id/summary"
    android:background="@null"
    android:layout_marginLeft="-2dp"
    android:progressDrawable="@drawable/seekbar"
    android:thumb="@drawable/seekbar_thumb"/>`

2
如果您的颜色选择受到限制并且是预定义的,您可以尝试使用不同主题的XML文件和Seekbar来添加。类似于这样:themed_seekbar_one.xml。
<?xml version="1.0" encoding="utf-8"?>
<SeekBar
    ...
    android:theme="@style/first_theme">
</SeekBar>

themed_seekbar_two.xml

<?xml version="1.0" encoding="utf-8"?>
<SeekBar
    ...
    android:theme="@style/second_theme">
</SeekBar>

您可以按照以下方式以编程方式膨胀这些视图:
SeekBar seekbar = (SeekBar)getLayoutInflater().inflate(R.layout.themed_seekbar_xxx, null);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接