删除水平进度条中的填充

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" />