L预览中的环形形状不起作用。

13

刚刚测试了新的开发者预览版,发现我的现有环形可绘制对象没有正确地渲染。它不是一个环形而是一个完整的圆圈。这是一个错误还是有什么改变了,或者我一开始就做错了?有什么可能的解决方案吗?

以下是代码:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:id="@android:id/progress">
        <shape
            android:innerRadiusRatio="3"
            android:shape="ring"
            android:thicknessRatio="7.0">
            <solid android:color="#ff5698fb"/>
        </shape>
    </item>
</layer-list>

谢谢!

更新

我已按以下方式更新形状:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item>
        <shape
            android:innerRadiusRatio="3"
            android:shape="ring"
            android:thicknessRatio="7.0">
            <solid android:color="#ff5698fb"/>
        </shape>
    </item>
    <item >
        <shape
            android:innerRadiusRatio="4"
            android:shape="ring"
            android:thicknessRatio="5.5">
            <solid android:color="#ffffff"/>
        </shape>
    </item>
</layer-list>

这个代码使用两个圆叠加在一起来生成一个环形。但是我在使用该进度条时遇到了问题。 以下是该进度条的代码:

<ProgressBar
                android:id="@+id/progressCircle"
                style="?android:attr/progressBarStyleHorizontal"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:indeterminate="false"
                android:max="100"
                android:progress="65"
                android:rotation="270"
                android:progressDrawable="@drawable/progress_circle"
                android:visibility="visible"/>

1
你解决了这个问题吗?我的代码和你的基本上一样——一个自定义的圆形进度条。现在当我调用updateProgress()时,它似乎没有效果,进度仍然停留在100%。在之前的Android版本中它运行得很好,但是在Android L预览版中似乎有些问题。 - Kano
3个回答

21

您需要在进度条项目中添加android:useLevel="true"。在之前的版本中似乎不需要,但L版本需要。

<item android:id="@android:id/progress">
    <shape
        android:innerRadiusRatio="3"
        android:shape="ring"
        android:thicknessRatio="7.0"
        android:useLevel="true" >
        <solid android:color="#ff5698fb"/>
    </shape>
</item>

谢谢!我几周没机会继续我的项目了,但是这个非常感激! - RogueX
1
奇怪...但现在我的背景不可见了?!编辑:必须将useLevel="false"用于背景。 - Informatic0re
请问“uselevel”属性代表什么意思?从Android文档中无法理解。 - Abhimaan
说实话,我也没有完全理解它。查看Drawable文档,级别“允许可绘制对象根据连续控制器变化其图像,例如显示进度或音量级别。”因此,级别可能会根据您拥有的可绘制对象类型执行不同的操作。在我们的情况下,它只是设置要绘制的环的特定数量。这确实引出了一个问题,为什么这不是默认行为,为什么我们需要显式设置它! - Kano

21

简述:在自定义进度条中,明确设置所有环形图形的useLevel值。


Kano的答案是解决您问题的方法。我在补充一些关于自定义进度条中环形形状的通用信息。
似乎Android版本中useLevel的默认值已经改变。以下是与此相关的调查结果。
以下是使用环形作为进度指示器和另一个环形作为进度背景的进度条的工作实现:
<?xml version="1.0" encoding="utf-8"?>

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Progress background -->
    <item android:id="@android:id/background">
        <shape
            android:shape="ring"
            android:useLevel="false">
            <solid
                android:color="#dae1e6"/>
        </shape>
    </item>

    <!-- Progress -->
    <item android:id="@android:id/progress">
        <!-- Rotation of the progress to start at the top-->
        <rotate
            android:fromDegrees="-90"
            android:pivotX="50%"
            android:pivotY="50%"
            android:toDegrees="-90">
            <shape
                android:shape="ring"
                android:useLevel="true">
                <solid
                    android:color="#61bcf9"/>
            </shape>
        </rotate>
    </item>

</layer-list>

在 ProgressBar 中将其用作 progressDrawable:
<ProgressBar
    style="?android:attr/progressBarStyleHorizontal"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:progressDrawable="@drawable/custom_horizontal"
    android:progress="50"
    android:max="100"
    android:id="@+id/progressBar"
    android:layout_gravity="center"/>

将进度环形状的useLevel=true,而将背景环形状的useLevel=false设置正确,可以在所有Android版本中获得所需的正确行为。

Correct in both versions

从背景形状中移除useLevel

5.0之前(左)| 5.0(右)

Incorrect in KitKat Correct in Lollipop

从进度形状中移除useLevel

5.0之前(左)| 5.0(右)

Correct in KitKat Incorrect in Lollipop


所以,据我理解,useLevel用于指示形状是否受进度值影响。如果不受影响(false),它将完全绘制;如果受影响(true),它将根据进度值绘制。

总之,似乎:

  • useLevelAndroid < 5.0中默认为true,如果其环形形状中未设置useLevel,则导致背景环跟随进度值而隐藏在进度指示器环后面。
  • useLevelAndroid >= 5.0中默认为false,如果其环形形状中未设置useLevel,则导致进度指示器环完全绘制。

因此,由于这种不一致性,在依赖于进度的形状中明确设置useLevel的值为true,在不依赖于进度的形状中设置为false会更好。

这种行为是基于我的观察,我没有找到任何证实它的来源。 官方Android文档 对此并不十分清晰...

终于了。我没想到在Android 5.0中有这样的方法。感谢这个指南! - Matt Robertson
请问“uselevel”属性代表什么意思?从Android文档中无法理解。 - Abhimaan

1

我只是想在框架源代码中添加一些参考,以确认在Android API版本 < 21(<5.0)中默认为true,并在API版本 >= 21(>=5.0)中默认为false,正如之前Christian García所述。

在android-20中,文件GradientDrawable.java,第820-835行:

if (shapeType == RING) {
    ....
    st.mUseLevelForShape = a.getBoolean(
                    com.android.internal.R.styleable.GradientDrawable_useLevel, true);
}

在android-21中,文件GradientDrawable.java,第1028至1047行:
if (state.mShape == RING) {
    ....
    state.mUseLevelForShape = a.getBoolean(
                    R.styleable.GradientDrawable_useLevel, state.mUseLevelForShape);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接