删除水平进度条中的填充
Remove padding in horizontal progress bar
在我们的应用中我们需要一个不确定的进度条,像这样:
我们可以通过在 ProgressBar 上设置负边距来实现这一点,如下所示:
<ProgressBar
android:id="@+id/progressbar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
android:marginTop="-7dp"
android:visibility="@{loading ? View.VISIBLE : View.GONE}" />
BUT因为ConstraintLayout不支持负边距,所以看起来像这样:
好的,负边距是一个黑客。让我们用不同的 hack 替换它,好吗?让我们介绍一下我们的自定义视图 CustomProgressBar
,它扩展了 ProgressBar
并覆盖了它的 onDraw
方法,像这样:
@Override
protected void onDraw(Canvas canvas) {
int marginTop = dpToPx(7);
canvas.translate(0, -marginTop);
super.onDraw(canvas);
}
但是所有这些闻起来都像是糟糕的代码。必须有更好的解决方案!
你会推荐什么?
另一种方法是在父级顶部和指南之间使用指南和中心 ProgressBar。
<ProgressBar
android:id="@+id/progressBar2"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
android:paddingTop="-4dp"
android:layout_height="wrap_content"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toTopOf="@+id/guideline"
app:layout_constraintTop_toTopOf="parent" />
<android.support.constraint.Guideline
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/guideline"
android:orientation="horizontal"
app:layout_constraintGuide_begin="4dp" />
我也遇到了同样的问题。就像你说的,我遇到过很多解决方案,它们看起来都像是黑客攻击,可能会破坏其他东西。
话虽如此,我遇到了一种解决方案,即使用 library 代替进度条。
需要注意的一件事是,它告诉您通过添加来集成它:
compile 'me.zhanghai.android.materialprogressbar:library:1.3.0'
但是,当我使用它时,它给了我一个来自 Android 浮动操作栏支持库的错误。所以我建议你改用这个:
compile 'me.zhanghai.android.materialprogressbar:library:1.1.7'
关于我如何使用它的示例代码片段:
<me.zhanghai.android.materialprogressbar.MaterialProgressBar
android:id="@+id/reviewProgressBar"
style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="6dp"
android:layout_below="@+id/my_toolbar"
android:indeterminate="false"
app:mpb_progressStyle="horizontal"
app:mpb_useIntrinsicPadding="false"/>
希望对您有所帮助!
我做的脏解决方法是将 ProgressBar 的高度设置为接近描边宽度,如下所示:
进度条:
<ProgressBar
android:id="@+id/pb_loading_progress"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="2.1dp"
android:layout_below="@id/tb_browser"
android:max="100"
android:progressDrawable="@drawable/style_browser_progress_drawable"
android:visibility="invisible" />
可绘制进度:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape android:shape="line">
<stroke
android:width="2dp"
android:color="@color/colorPrimary" />
</shape>
</item>
<item android:id="@android:id/progress">
<clip
android:clipOrientation="horizontal"
android:gravity="left">
<shape android:shape="line">
<stroke
android:width="2dp"
android:color="@color/white" />
</shape>
</clip>
</item>
</layer-list>
看起来像这样:
感觉不太像 hack 的解决方案:将巨大的 ProgressBar
包裹在较小的 FrameLayout
中。这样 FrameLayout
限制了它的高度,但 ProgressBar
仍然完整显示。
<FrameLayout
android:layout_width="match_parent"
android:layout_height="4dp">
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="32dp"
android:layout_gravity="center" />
</FrameLayout>
在Linearlayout里面使用就可以成功,方法很简单
<LinearLayout
android:layout_width="match_parent"
android:background="#efefef"
android:layout_height="wrap_content">
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
android:visibility="gone"
android:layout_marginTop="-7dp"
android:layout_marginBottom="-7dp"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
/>
</LinearLayout>
您声明的视图没有任何明确的高度,因此它的高度是从预定义样式中选取的。
<ProgressBar
android:id="@+id/progressbar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
android:marginTop="-7dp"
android:visibility="@{loading ? View.VISIBLE : View.GONE}" />
"?android:attr/progressBarStyleHorizontal" 将在当前主题中搜索并存储在 attrs.xml 文件中。由于这是由平台定义的,它将从那里获得它的价值。在撰写此答案时,我在 android 平台 29 上搜索“?android:attr/progressBarStyleHorizontal”得到以下结果
➜ values
pwd
/Users/vihaanverma/Library/Android/sdk/platforms/android-29/data/res/values
➜ values
grep -rin "progressBarStyleHorizontal" .
./themes_device_defaults.xml:126: <item name="progressBarStyleHorizontal">@style/Widget.DeviceDefault.ProgressBar.Horizontal</item>
./themes_device_defaults.xml:857: <item name="progressBarStyleHorizontal">@style/Widget.DeviceDefault.Light.ProgressBar.Horizontal</item>
./themes.xml:272: <item name="progressBarStyleHorizontal">@style/Widget.ProgressBar.Horizontal</item>
./themes_holo.xml:263: <item name="progressBarStyleHorizontal">@style/Widget.Holo.ProgressBar.Horizontal</item>
./themes_holo.xml:626: <item name="progressBarStyleHorizontal">@style/Widget.Holo.Light.ProgressBar.Horizontal</item>
./public.xml:148: <public type="attr" name="progressBarStyleHorizontal" id="0x01010078" />
./themes_material.xml:258: <item name="progressBarStyleHorizontal">@style/Widget.Material.ProgressBar.Horizontal</item>
./themes_material.xml:635: <item name="progressBarStyleHorizontal">@style/Widget.Material.Light.ProgressBar.Horizontal</item>
./styles_material.xml:1010: <item name="progressBarStyle">?attr/progressBarStyleHorizontal</item>
./attrs.xml:684: <attr name="progressBarStyleHorizontal" format="reference" />
➜ values
打开其中一个包含 "progressBarStyleHorizontal" 的文件,您将看到样式中定义的 minHeight 等于 16dp。
<style name="Widget.Material.ProgressBar.Horizontal" parent="Widget.ProgressBar.Horizontal">
<item name="progressDrawable">@drawable/progress_horizontal_material</item>
<item name="indeterminateDrawable">@drawable/progress_indeterminate_horizontal_material</item>
<item name="minHeight">16dip</item>
<item name="maxHeight">16dip</item>
</style>
这就是您获得额外填充的原因。您可以通过提供您的视图高度和如下所示的 scaleY 值来修复它
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="5dp"
android:indeterminate="true"
android:scaleY="5"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
在我们的应用中我们需要一个不确定的进度条,像这样:
我们可以通过在 ProgressBar 上设置负边距来实现这一点,如下所示:
<ProgressBar
android:id="@+id/progressbar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
android:marginTop="-7dp"
android:visibility="@{loading ? View.VISIBLE : View.GONE}" />
BUT因为ConstraintLayout不支持负边距,所以看起来像这样:
好的,负边距是一个黑客。让我们用不同的 hack 替换它,好吗?让我们介绍一下我们的自定义视图 CustomProgressBar
,它扩展了 ProgressBar
并覆盖了它的 onDraw
方法,像这样:
@Override
protected void onDraw(Canvas canvas) {
int marginTop = dpToPx(7);
canvas.translate(0, -marginTop);
super.onDraw(canvas);
}
但是所有这些闻起来都像是糟糕的代码。必须有更好的解决方案! 你会推荐什么?
另一种方法是在父级顶部和指南之间使用指南和中心 ProgressBar。
<ProgressBar
android:id="@+id/progressBar2"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
android:paddingTop="-4dp"
android:layout_height="wrap_content"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toTopOf="@+id/guideline"
app:layout_constraintTop_toTopOf="parent" />
<android.support.constraint.Guideline
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/guideline"
android:orientation="horizontal"
app:layout_constraintGuide_begin="4dp" />
我也遇到了同样的问题。就像你说的,我遇到过很多解决方案,它们看起来都像是黑客攻击,可能会破坏其他东西。 话虽如此,我遇到了一种解决方案,即使用 library 代替进度条。
需要注意的一件事是,它告诉您通过添加来集成它:
compile 'me.zhanghai.android.materialprogressbar:library:1.3.0'
但是,当我使用它时,它给了我一个来自 Android 浮动操作栏支持库的错误。所以我建议你改用这个:
compile 'me.zhanghai.android.materialprogressbar:library:1.1.7'
关于我如何使用它的示例代码片段:
<me.zhanghai.android.materialprogressbar.MaterialProgressBar
android:id="@+id/reviewProgressBar"
style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="6dp"
android:layout_below="@+id/my_toolbar"
android:indeterminate="false"
app:mpb_progressStyle="horizontal"
app:mpb_useIntrinsicPadding="false"/>
希望对您有所帮助!
我做的脏解决方法是将 ProgressBar 的高度设置为接近描边宽度,如下所示:
进度条:
<ProgressBar
android:id="@+id/pb_loading_progress"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="2.1dp"
android:layout_below="@id/tb_browser"
android:max="100"
android:progressDrawable="@drawable/style_browser_progress_drawable"
android:visibility="invisible" />
可绘制进度:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape android:shape="line">
<stroke
android:width="2dp"
android:color="@color/colorPrimary" />
</shape>
</item>
<item android:id="@android:id/progress">
<clip
android:clipOrientation="horizontal"
android:gravity="left">
<shape android:shape="line">
<stroke
android:width="2dp"
android:color="@color/white" />
</shape>
</clip>
</item>
</layer-list>
看起来像这样:
感觉不太像 hack 的解决方案:将巨大的 ProgressBar
包裹在较小的 FrameLayout
中。这样 FrameLayout
限制了它的高度,但 ProgressBar
仍然完整显示。
<FrameLayout
android:layout_width="match_parent"
android:layout_height="4dp">
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="32dp"
android:layout_gravity="center" />
</FrameLayout>
在Linearlayout里面使用就可以成功,方法很简单
<LinearLayout
android:layout_width="match_parent"
android:background="#efefef"
android:layout_height="wrap_content">
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
android:visibility="gone"
android:layout_marginTop="-7dp"
android:layout_marginBottom="-7dp"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
/>
</LinearLayout>
您声明的视图没有任何明确的高度,因此它的高度是从预定义样式中选取的。
<ProgressBar
android:id="@+id/progressbar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
android:marginTop="-7dp"
android:visibility="@{loading ? View.VISIBLE : View.GONE}" />
"?android:attr/progressBarStyleHorizontal" 将在当前主题中搜索并存储在 attrs.xml 文件中。由于这是由平台定义的,它将从那里获得它的价值。在撰写此答案时,我在 android 平台 29 上搜索“?android:attr/progressBarStyleHorizontal”得到以下结果
➜ values
pwd
/Users/vihaanverma/Library/Android/sdk/platforms/android-29/data/res/values
➜ values
grep -rin "progressBarStyleHorizontal" .
./themes_device_defaults.xml:126: <item name="progressBarStyleHorizontal">@style/Widget.DeviceDefault.ProgressBar.Horizontal</item>
./themes_device_defaults.xml:857: <item name="progressBarStyleHorizontal">@style/Widget.DeviceDefault.Light.ProgressBar.Horizontal</item>
./themes.xml:272: <item name="progressBarStyleHorizontal">@style/Widget.ProgressBar.Horizontal</item>
./themes_holo.xml:263: <item name="progressBarStyleHorizontal">@style/Widget.Holo.ProgressBar.Horizontal</item>
./themes_holo.xml:626: <item name="progressBarStyleHorizontal">@style/Widget.Holo.Light.ProgressBar.Horizontal</item>
./public.xml:148: <public type="attr" name="progressBarStyleHorizontal" id="0x01010078" />
./themes_material.xml:258: <item name="progressBarStyleHorizontal">@style/Widget.Material.ProgressBar.Horizontal</item>
./themes_material.xml:635: <item name="progressBarStyleHorizontal">@style/Widget.Material.Light.ProgressBar.Horizontal</item>
./styles_material.xml:1010: <item name="progressBarStyle">?attr/progressBarStyleHorizontal</item>
./attrs.xml:684: <attr name="progressBarStyleHorizontal" format="reference" />
➜ values
打开其中一个包含 "progressBarStyleHorizontal" 的文件,您将看到样式中定义的 minHeight 等于 16dp。
<style name="Widget.Material.ProgressBar.Horizontal" parent="Widget.ProgressBar.Horizontal">
<item name="progressDrawable">@drawable/progress_horizontal_material</item>
<item name="indeterminateDrawable">@drawable/progress_indeterminate_horizontal_material</item>
<item name="minHeight">16dip</item>
<item name="maxHeight">16dip</item>
</style>
这就是您获得额外填充的原因。您可以通过提供您的视图高度和如下所示的 scaleY 值来修复它
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="5dp"
android:indeterminate="true"
android:scaleY="5"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />