【问题标题】:Android - Tinting ProgressBar on pre-Lollipop devicesAndroid - 在棒棒糖之前的设备上着色 ProgressBar
【发布时间】:2023-03-21 10:10:01
【问题描述】:

我的应用程序的最低 API 级别是 19 (KitKat),并且包含一个带有水平 ProgressBar 的布局。我正在使用android:progressTint 属性将条着色为自定义颜色。它在 Lollipop (API 21) 及以上版本上运行良好,但在以下版本(例如在 API 19 上)则不行;它以不同的颜色显示。原因是这个属性

仅用于 API 级别 21 及更高级别

如 Android Studio 所述。

所以我想知道在棒棒糖之前的设备上为ProgressBar 着色还有什么好的替代方法。可以用 XML 在布局文件中制作吗?还是应该以不同的方式完成?


编辑#1:我的 ProgressBar 用于以百分比显示具体值,而不是表示我的布局正在加载。我想澄清这一点,因为在尝试了 Kuldeep Kulkarni 下面写的内容后,我的栏看起来像一个材料加载指示器(当然在 Lollipop 设备上,在 KitKat 设备上没有任何可见的结果)。

【问题讨论】:

  • progressTint 在 Lollipop 上对我不起作用有人知道原因

标签: android android-layout android-progressbar android-api-levels


【解决方案1】:

您可以使用ProgressBar indeterminateDrawable 方法包装pre-Lollipop

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {

     Drawable drawableProgress = DrawableCompat.wrap(progressBar.getIndeterminateDrawable());
     DrawableCompat.setTint(drawableProgress, ContextCompat.getColor(getContext(), android.R.color.holo_green_light));
     progressBar.setIndeterminateDrawable(DrawableCompat.unwrap(drawableProgress));

} else {
    progressBar.getIndeterminateDrawable().setColorFilter(ContextCompat.getColor(getContext(), android.R.color.holo_green_light), PorterDuff.Mode.SRC_IN);
}

【讨论】:

  • 我试过用它,代码也能运行,但没有可见的结果……另见问题的编辑。
  • 你需要setProgressDrawable
【解决方案2】:
progress.getProgressDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN);

【讨论】:

  • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。
  • 这个解决方案比目前评分最高的解决方案更适合我。
  • 现在已弃用
【解决方案3】:

感谢大家的建议! :)

对我有用的解决方案是使用 &lt;layer-list&gt; 根元素创建自定义可绘制 XML 文件。在那里,我使用原生 Android ID @android:id/background@android:id/progress 定义了两个层项。在此之后,我可以定义我想使用的形状和颜色资源。此解决方案类似于this SO question 上更受欢迎的答案。


我的res/drawable/progressbar.xml 文件的内容:

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

    <item android:id="@android:id/background">

        <shape>

            <corners android:radius="2dip" /> <!--optional-->

            <gradient
                android:angle="270"
                android:endColor="@color/gray"
                android:startColor="@color/gray" />

        </shape>

    </item>

    <item android:id="@android:id/progress">

        <clip>

            <shape>

                <corners android:radius="2dip" /> <!--optional-->

                <gradient
                    android:angle="270"
                    android:endColor="@color/blue"
                    android:startColor="@color/blue" />

            </shape>

        </clip>

    </item>

</layer-list>

在布局 XML 文件中为我的 ProgressBar 定义为 progressDrawable

<ProgressBar
        android:id="@+id/progress_bar"
        android:layout_width="0dp"
        android:layout_height="@dimen/progress_bar_height"
        android:progressDrawable="@drawable/progressbar" />

我没有机会在 API 19 以下测试它,但在这个级别及以上它可以完美运行。

【讨论】:

    【解决方案4】:

    这对我有用

    <ProgressBar
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:theme="@style/progressBarBlue" />
    

    然后在你的style.xml 中定义progressBarBlue

    <style name="progressBarWhite" parent="@style/Theme.AppCompat">
       <item name="colorAccent">@color/blue</item>
    </style>
    

    【讨论】:

      【解决方案5】:

      如果你想以编程方式进行,试试这个

      public static void setSeekbarTint(SeekBar seekbar, int color) {
              PorterDuff.Mode porterDuffMode = PorterDuff.Mode.SRC_IN;
              if (seekbar.getIndeterminateDrawable() != null)
                  seekbar.getIndeterminateDrawable().setColorFilter(color, porterDuffMode);
      
              if (seekbar.getProgressDrawable() != null &&
                      seekbar.getProgressDrawable() instanceof LayerDrawable) {
                  LayerDrawable layerDrawable = (LayerDrawable) seekbar.getProgressDrawable();
                  GradientDrawable gradientDrawable = (GradientDrawable) layerDrawable.findDrawableByLayerId(android.R.id.background);
      
                  layerDrawable.setColorFilter(color, porterDuffMode);
                  seekbar.setProgressDrawable(layerDrawable);
                  gradientDrawable.setColorFilter(Color.WHITE, porterDuffMode);
              } else if (seekbar.getProgressDrawable() != null &&
                      seekbar.getProgressDrawable() instanceof ClipDrawable) {
                  ClipDrawable clipDrawable = (ClipDrawable) seekbar.getProgressDrawable();
                  clipDrawable.setColorFilter(color, porterDuffMode);
                  seekbar.setProgressDrawable(clipDrawable);
              }
      }
      

      【讨论】:

        【解决方案6】:

        我希望这会对你有所帮助。 试试这个:

        <ProgressBar
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:indeterminate="true"
                android:indeterminateTint="#F00"
                android:indeterminateTintMode="src_in" />
        

        【讨论】:

        • 对不起,它不能像我想的那样工作 - indeterminateTint 属性使用应用程序的原色,这与我想要使用的颜色不同;它也适用于 API 21 及更高版本。
        • 这与之前要求的棒棒糖不兼容。
        猜你喜欢
        • 1970-01-01
        • 2016-02-11
        • 1970-01-01
        • 2015-09-01
        • 2018-09-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多