从水平进度条中删除垂直填充

默认情况下,ProgressBar 在工具条本身的上方和下方都有一定的填充。有没有办法去除这个填充,以便只有在最后的酒吧?

44590 次浏览

我使用以下内容作为这个问题的解决方案。

android:layout_marginBottom="-8dp"
android:layout_marginTop="-4dp"

这个问题的完整解决方案如下。以防有人需要代码片段,我就是这么做的。

  1. 复制了所有8个不确定的水平进度条绘制
  2. 使用一些图像处理器编辑绘图,并删除不必要的填充
  3. 从 android 平台复制可绘制的 XML,命名为 Progress _ insetate _ level _ holo.XML
  4. 复制样式部件。进度条。水平线及其父元素
  5. 在布局中手动设置样式和 min _ height

下面是 Progress _ insetate _ level _ holo. xml

<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/progressbar_indeterminate_holo1" android:duration="50" />
<item android:drawable="@drawable/progressbar_indeterminate_holo2" android:duration="50" />
<item android:drawable="@drawable/progressbar_indeterminate_holo3" android:duration="50" />
<item android:drawable="@drawable/progressbar_indeterminate_holo4" android:duration="50" />
<item android:drawable="@drawable/progressbar_indeterminate_holo5" android:duration="50" />
<item android:drawable="@drawable/progressbar_indeterminate_holo6" android:duration="50" />
<item android:drawable="@drawable/progressbar_indeterminate_holo7" android:duration="50" />
<item android:drawable="@drawable/progressbar_indeterminate_holo8" android:duration="50" />
</animation-list>

样式资源复制到我的本地样式文件。

<style name="Widget">
<item name="android:textAppearance">@android:attr/textAppearance</item>
</style>


<style name="Widget.ProgressBar">
<item name="android:indeterminateOnly">true</item>
<item name="android:indeterminateBehavior">repeat</item>
<item name="android:indeterminateDuration">3500</item>
</style>


<style name="Widget.ProgressBar.Horizontal">
<item name="android:indeterminateOnly">false</item>
<item name="android:indeterminateDrawable">@drawable/progress_indeterminate_horizontal_holo</item>
</style>

最后,在本地布局文件中将 min height 设置为4dp。

<ProgressBar
android:id="@+id/pb_loading"
style="@style/Widget.ProgressBar.Horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:indeterminate="true"
android:minHeight="4dp"
android:minWidth="48dp"
android:progressDrawable="@drawable/progress_indeterminate_horizontal_holo" />

可以在父节点中绘制垂直居中的 Progress 条,从而消除填充。因为 ProgressBar 不能绘制自己大于父级,所以我们必须创建一个大的父级来放置在剪辑视图中。

<FrameLayout
android:id="@+id/clippedProgressBar"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="4dp"
tools:ignore="UselessParent">


<FrameLayout
android:layout_width="match_parent"
android:layout_height="16dp"
android:layout_gravity="center_vertical">


<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:indeterminate="true"/>


</FrameLayout>


</FrameLayout>

这就是我如何使用 Juozas 的回答:

我的 ProgressBar高度是4dp。所以我创建了一个高度为4dp 的 FrameLayout,并将 ProgressBarlayout_gravity设置为 center。效果很好。

<FrameLayout
android:layout_width="match_parent"
android:layout_height="4dp">


<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="4dp"
android:layout_gravity="center"
android:indeterminate="true" />
</FrameLayout>

注意: FrameLayout所做的就是剪掉多余的部分,所以如果你遇到 ProgressBar仍然很薄的问题,只需要将 ProgressBarlayout_height设置为一些大的数字,比如 100dp。它将完全覆盖 FrameLayout,并且只显示它的 4dp

我使用了 minHeight 和 maxHeigh,它可以帮助不同的 Api 版本。

<ProgressBar
android:id="@+id/progress_bar"
style="@style/Base.Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxHeight="3dp"
android:minHeight="3dp" />

它需要同时使用两者,Api 23很适合

android:layout_height="wrap_content"
android:minHeight="0dp"

但在这种情况下,较低的 Api 版本会将进度条高度增加到 maxHeight。

Subin 的回答似乎是(目前)唯一一个不是脆弱的黑客攻击,在未来的 Android ProgressBar 版本中可能会遭到破坏。

但是,我选择使用 材质进度条库,它为我们做到了这一点,而不是费尽周折地分离资源,修改它们,并无限期地维护它们:

<me.zhanghai.android.materialprogressbar.MaterialProgressBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
android:layout_gravity="bottom"
custom:mpb_progressStyle="horizontal"
custom:mpb_showTrack="false"
custom:mpb_useIntrinsicPadding="false"
style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal.NoPadding"
/>

在 build.gradle:

// Android horizontal ProgressBar doesn't allow removal of top/bottom padding
compile 'me.zhanghai.android.materialprogressbar:library:1.1.6'

这个项目有一个 样带不错,它显示了它和内置的 ProgressBar 之间的区别。

添加 android: ProgressDrawable 到一个图层列表中定义,修复了我的问题。它的工作原理是在自定义绘图中屏蔽进度条

https://stackoverflow.com/a/4454450/1145905中描述的示例实现

我最终使用了一个自定义库来解决这个问题。大多数其他解决方案都可以工作,但是不同设备之间的结果并不一致。

材料进度条

  • Android 4.0 + 外观一致。
  • 平台上的着色正确。
  • 能够删除框架 ProgressBar 的内部填充。
  • 能够隐藏框架水平 ProgressBar 的跟踪。
  • 用作框架 ProgressBar 的插入式替换。

作为等级依赖添加:

compile 'me.zhanghai.android.materialprogressbar:library:1.1.7'

要在布局中添加没有内部填充的 ProgressBar:

<me.zhanghai.android.materialprogressbar.MaterialProgressBar
android:layout_width="wrap_content"
android:layout_height="4dp"
android:indeterminate="true"
app:mpb_progressStyle="horizontal"
app:mpb_useIntrinsicPadding="false"
style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal" />

app:mpb_useIntrinsicPadding="false"可以做到这一点。更多细节见 GitHub 页面

我在使用横向风格的进度条时遇到了同样的问题。

根本原因是进度条的默认9-patch 可绘制: (process _ bg _ holo _ dark. 9.png)有一些垂直透明像素作为填充。

最终的解决方案适合我: 定制可绘制的进度,我的示例代码如下:

自定义 _ 水平 _ 进度条 _ 绘制. 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">
<shape android:shape="rectangle">
<solid android:color="#33ffffff" />
</shape>
</item>
<item android:id="@android:id/secondaryProgress">
<clip>
<shape android:shape="rectangle">
<solid android:color="#ff9800" />
</shape>
</clip>
</item>
<item android:id="@android:id/progress">
<clip>
<shape android:shape="rectangle">
<solid android:color="#E91E63" />
</shape>
</clip>
</item>
</layer-list>

布局片段:

<ProgressBar
android:id="@+id/song_progress_normal"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="5dp"
android:layout_alignParentBottom="true"
android:progressDrawable="@drawable/custom_horizontal_progressbar_drawable"
android:progress="0"/>

我使用的是 style="@style/Widget.AppCompat.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>

我刚刚覆盖了最小/最大高度:

    <ProgressBar
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="2dp"
android:indeterminate="true"
android:minHeight="2dp"
android:maxHeight="2dp" />

试试以下方法:

<ProgressBar
android:id="@+id/progress_bar"
style="@android:style/Widget.ProgressBar.Horizontal"
android:progress="25"
android:progressTint="@color/colorWhite"
android:progressBackgroundTint="@color/colorPrimaryLight"
android:layout_width="match_parent"
android:layout_height="4dp" />

然后根据你的需要配置进度条,因为它最初会显示一个中等大小的进度条,带有黄色的进度色和灰色的进度背景色。另外,请注意没有垂直填充。

一个简单的非技巧解决方案,这是兼容任何版本的 Android,不需要外部库是假装 ProgressBar与两个 Views内的 LinearLayout。这就是我的结局。看起来相当整洁,这种方法是相当灵活的-你可以动画它在时髦的方式,添加文本等。

布局:

<LinearLayout
android:id="@+id/inventory_progress_layout"
android:layout_width="match_parent"
android:layout_height="4dp"
android:orientation="horizontal">


<TextView
android:id="@+id/inventory_progress_value"
android:layout_width="match_parent"
android:layout_height="match_parent" />


<TextView
android:id="@+id/inventory_progress_remaining"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

密码:

public void setProgressValue(float percentage) {
TextView progressValue = (TextView) findViewById(R.id.inventory_progress_value);
TextView progressRemaining = (TextView) findViewById(R.id.inventory_progress_remaining);


LinearLayout.LayoutParams paramsValue = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
LinearLayout.LayoutParams paramsRemaining = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);


paramsValue.weight = (100 - percentage);
paramsRemaining.weight = percentage;


progressValue.setLayoutParams(paramsValue);
progressRemaining.setLayoutParams(paramsRemaining);


}

结果(加上一些抬高) :

enter image description here

一个技巧是在进度条中添加负边距。

下面是一个 XML 代码示例,假设它位于屏幕上方:

<ProgressBar
android:id="@+id/progressBar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="-7dp"
android:layout_marginBottom="-7dp"
android:indeterminate="true" />

result of code

如果有人仍然需要帮助,可以尝试这样做:

<androidx.core.widget.ContentLoadingProgressBar
android:id="@+id/progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline"
android:indeterminate="true"
android:visibility="visible"
app:layout_constraintBottom_toTopOf="@+id/guideline" />

在这里,进度条位于 约束布局内部,ConstraintTop _ toTopOfConstraintBottom _ toTopOf属性必须应用于同一个元素(在本例中,它是指南)。

完全解决方案:

<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="48dp">


<View
android:id="@+id/guideline"
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="vertical"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />


<ProgressBar
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="true"
app:layout_constraintBottom_toTopOf="@+id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline" />
</androidx.constraintlayout.widget.ConstraintLayout>

要删除 ProgressBar的垂直填充,可以通过

  • 固定 ProgressBar的高度
  • 使用 scaleY = “ value”(value = height/4)(4是默认的进度条高度)

示例包含1回合内容 ProgressBar,18dp ProgressBar,1100dp ProgressBar

enter image description here

<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
...
android:layout_height="8dp"
android:scaleY="2" />
 <ProgressBar
android:layout_marginTop="-8dp"
android:layout_marginLeft="-8dp"
android:layout_marginRight="-8dp"
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="4dp"
android:indeterminate="false"
android:indeterminateTint="@color/white"
android:max="100"
android:paddingStart="8dp"
android:paddingRight="0dp"
android:progressDrawable="@drawable/progress_bg" />

不需要下载任何新模块,甚至不需要在进度条周围放置 FrameLayout。这些都是黑客。只有两个步骤:

在 whatever.xml 中

<ProgressBar
android:id="@+id/workoutSessionGlobalProgress"
android:layout_width="match_parent"
android:layout_height="YOUR_HEIGHT"
android:progressDrawable="@drawable/progress_horizontal"
android:progress="0"
<!-- High value to make ValueAnimator smoother -->
android:max="DURATION * 1000"
android:indeterminate="false"
style="@style/Widget.MaterialProgressBar.ProgressBar.Horizontal"/>

如果愿意,可以更改这些值。

不喜欢圆角? 删除圆角半径

不喜欢这些颜色? 改变颜色等等。 成交!

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">


<item android:id="@android:id/background">
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#ff9d9e9d"
android:centerColor="#ff5a5d5a"
android:centerY="0.75"
android:endColor="#ff747674"
android:angle="270"
/>
</shape>
</item>


<item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#80ffd300"
android:centerColor="#80ffb600"
android:centerY="0.75"
android:endColor="#a0ffcb00"
android:angle="270"
/>
</shape>
</clip>
</item>


<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#ffffd300"
android:centerColor="#ffffb600"
android:centerY="0.75"
android:endColor="#ffffcb00"
android:angle="270"
/>
</shape>
</clip>
</item>


</layer-list>

一般来说,这些步骤可以更改您不喜欢的任何代码。只要找到源代码,然后找出要修改的地方。如果按照 ProgressBar 源代码,您将找到它引用的一个名为 Progress _ Horizontal.xml 的文件。基本上我是如何解决所有 XML 问题的。

最好的解决办法应该是

android:minHeight="0dp"

没有变通方法,非常有效。

像这样在 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>

如果有人仍在寻找解决方案——请查看这条评论

设置最小高度为 < em > 4 dp

   android:minHeight="4dp"

-

  <ProgressBar
android:id="@+id/web_view_progress_bar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="false"
android:max="100"
android:min="0"
android:progress="5"
android:minHeight="4dp"
android:progressTint="@color/vodafone_red"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:progress="60" />
<androidx.core.widget.ContentLoadingProgressBar
android:id="@+id/progressBar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:indeterminate="true"
android:paddingTop="2dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>

只要使用没有隐藏空白的物质进度指示器。

<com.google.android.material.progressindicator.ProgressIndicator
android:id="@+id/progressBar"
style="@style/Widget.MaterialComponents.ProgressIndicator.Linear.Indeterminate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:indicatorColor="@color/colorPrimary"
app:trackColor="@color/colorAccent" />
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/progress_loading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="visible"
android:indeterminate="true"
app:indicatorColor="@color/colorAccent"
app:layout_constraintTop_toBottomOf="@+id/app_bar_pdfview"/>

我正在使用这个新的进度条

implementation 'com.google.android.material:material:1.3.0'
  • 轨道厚度: 指示器和轨道的厚度。
  • 颜色: 指示器的颜色。
  • TrackColor: 音轨的颜色。
  • TrackCornerRadius: 指示器圆角的半径 追踪。
  • 不确定动画类型。
  • 线性: 指示器的扫动方向。

see result of this horizontal progress bar

一个不需要任何额外视图或修改页边距的简单方法是使用属性 android:translationZ

这样,您可以在 XML 中使用它

<Progressbar
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:translateY="-6dp"
/>

或者

在一种风格中使用它

<style name="MyTheme.Progressbar.Horizontal" parent="Widget.AppCompat.Progressbar.Horizontal">
<item name="android:translateY">-6dp</item>
</style>

然后像这样在布局中引用它

<Progressbar
android:layout_height="wrap_content"
android:layout_width="match_parent"
style="@style/MyTheme.Progressbar.Horizontal"
/>

使进度条的大小真的很大(我的意思是高度) ,然后把它放在一个框架布局的大小,你希望你的进度条需要。

<FrameLayout
android:layout_width="match_parent"
android:layout_height="10dp">


<ProgressBar
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_gravity="center"
android:backgroundTint="@android:color/transparent"
android:indeterminate="true"
android:indeterminateTint="@color/white" />


</FrameLayout>

下面是一个简单的材质水平进度条 而不需要添加文件、缩放或更改维度

    style="@android:style/Widget.ProgressBar.Horizontal"
android:progressTint="Your Progress Color"
android:progressTintMode="src_over"
android:progressBackgroundTint="Your Background Color"
android:backgroundTintMode="src_over"

这是通过在 Widget.ProgressBar.Horizontal中显示的进度或背景颜色上着色来完成的

对我来说,这是工作。进度条很清晰。非常合身。我尝试了不同高度的框架和进度。

<FrameLayout
android:layout_width="match_parent"
android:layout_height="4dp">


<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="16dp"
android:layout_gravity="center"
android:indeterminate="true"/>
</FrameLayout>

预览