Android:带有自定义可绘制对象的 SeekBar
Android: SeekBar with custom drawable
我有带有自定义可绘制对象的 SeekBar。 Progress 元素并没有完全从左侧呈现,而是移到了右侧。我怎样才能避免这种情况?
<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>
seekbar_progress.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 使它具有两种不同的宽度,这可能吗?也许有不同的形状而不仅仅是线条?
看来问题正在进行中,我认为它们的宽度应该相同
但是你正在制作 width = 4 android:width="4dp"
并且搜索栏宽度 = 2 android:width="2dp"
只需将它们匹配为 2 或 4 不要使用不同的值
我无法解释为什么在画笔画时会出现这个问题,我认为这与笔画的宽度有关,但我还没有找到来源来验证。
修复叠加层
要解决手头的问题,您只需在左侧设置一个 inset
。 1dp
或 2dp
的值都有效,搜索栏将被正确绘制。
注意:使用这种方法应该没有背景可能太短且进度值低时不可见的风险,因为拇指会覆盖并隐藏它案例.
<?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>
尝试使用宽度为 4dp(转换为 px)的 .9.png 可绘制对象。
在顶部和底部保持 1 dp 透明。
然后将颜色添加到您选择的背景中心 2 dp。
这样背景和进度条的宽度将相同,但背景看起来会比进度条更细。
像这样尝试使用
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"/>`
观察
当您使用 shape drawable 创建线条时,它会保留左右填充(从使用此 drawable 的视图来看。)等于其笔划宽度的一半。
解决方法
您需要用插图包裹您的 progress_background,然后将其设置为进度背景。
插图可以像下面这样-
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.You 可以使用 9 路径图像作为线条,因为它在默认 material 设计中完成 -
<?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.You 可以将主题设置为您的视图,在 android 样式中使用不同的颜色-
<style name="AppTheme.SeekBar">
<item name="colorPrimary">@color/colorAccent</item>
<item name="colorPrimaryDark">@color/colorPrimary</item>
<item name="colorAccent">@color/colorPrimaryDark</item>
</style>
这里我已经使用了 Seekbars 的所有选项-
<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" />
这是输出-
如果您选择的颜色有限制并且是预定义的。您可以尝试使用不同主题的 Seekbars 添加 XML 个文件。
像这样:
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);
我有带有自定义可绘制对象的 SeekBar。 Progress 元素并没有完全从左侧呈现,而是移到了右侧。我怎样才能避免这种情况?
<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>
seekbar_progress.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 使它具有两种不同的宽度,这可能吗?也许有不同的形状而不仅仅是线条?
看来问题正在进行中,我认为它们的宽度应该相同
但是你正在制作 width = 4 android:width="4dp"
并且搜索栏宽度 = 2 android:width="2dp"
只需将它们匹配为 2 或 4 不要使用不同的值
我无法解释为什么在画笔画时会出现这个问题,我认为这与笔画的宽度有关,但我还没有找到来源来验证。
修复叠加层
要解决手头的问题,您只需在左侧设置一个 inset
。 1dp
或 2dp
的值都有效,搜索栏将被正确绘制。
注意:使用这种方法应该没有背景可能太短且进度值低时不可见的风险,因为拇指会覆盖并隐藏它案例.
<?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>
尝试使用宽度为 4dp(转换为 px)的 .9.png 可绘制对象。
在顶部和底部保持 1 dp 透明。
然后将颜色添加到您选择的背景中心 2 dp。
这样背景和进度条的宽度将相同,但背景看起来会比进度条更细。
像这样尝试使用
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"/>`
观察
当您使用 shape drawable 创建线条时,它会保留左右填充(从使用此 drawable 的视图来看。)等于其笔划宽度的一半。
解决方法
您需要用插图包裹您的 progress_background,然后将其设置为进度背景。 插图可以像下面这样-
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.You 可以使用 9 路径图像作为线条,因为它在默认 material 设计中完成 -
<?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.You 可以将主题设置为您的视图,在 android 样式中使用不同的颜色-
<style name="AppTheme.SeekBar">
<item name="colorPrimary">@color/colorAccent</item>
<item name="colorPrimaryDark">@color/colorPrimary</item>
<item name="colorAccent">@color/colorPrimaryDark</item>
</style>
这里我已经使用了 Seekbars 的所有选项-
<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" />
这是输出-
如果您选择的颜色有限制并且是预定义的。您可以尝试使用不同主题的 Seekbars 添加 XML 个文件。
像这样:
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);