【问题标题】:Android multiple Progressbar Instances not updating correctlyAndroid 多个 Progressbar 实例未正确更新
【发布时间】:2020-09-20 04:34:09
【问题描述】:

我有一个自定义视图,其中有一个进度条。自定义视图有一个进度条,标题和文本进度为“1/5”。我在几个地方使用了这个 CustomView (ProgressBadgeWidget),包括在我的项目布局中的两次 RecyclerView (item_levels.xml - 为此简化):

<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="wrap_content"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"

>

<com.trala.learn.violin.view.core.widgets.ProgressBadgeWidget
    android:id="@+id/courses_done_progress_widget"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:elevation="4dp"
    android:visibility="visible"
    app:badge_image="@drawable/trophy_gold"
    app:layout_constraintBottom_toBottomOf="@id/background_image"
    app:layout_constraintEnd_toEndOf="@id/background_image"
    app:layout_constraintHeight_percent="0.18"
    app:layout_constraintHorizontal_bias="0.12"
    app:layout_constraintStart_toStartOf="@id/background_image"
    app:layout_constraintTop_toTopOf="@id/background_image"
    app:layout_constraintVertical_bias="0.96"
    app:layout_constraintWidth_percent="0.24"
    app:progress_badge_title="@string/courses_done"
    app:progress_bar_background_color="@color/progress_bar_background_default"
    app:progress_text_color="@color/progress_bar_background_course_header"

    />


<com.trala.learn.violin.view.core.widgets.ProgressBadgeWidget
    android:id="@+id/medals_earned_progress_widget"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:elevation="4dp"
    android:visibility="visible"
    app:badge_image="@drawable/medal_gold_small"
    app:layout_constraintBottom_toBottomOf="@id/background_image"
    app:layout_constraintEnd_toEndOf="@id/background_image"
    app:layout_constraintHeight_percent="0.18"
    app:layout_constraintHorizontal_bias="0.85"
    app:layout_constraintStart_toStartOf="@id/background_image"
    app:layout_constraintTop_toTopOf="@id/background_image"
    app:layout_constraintVertical_bias="0.96"
    app:layout_constraintWidth_percent="0.24"
    app:progress_badge_title="@string/medals_earned"
    app:progress_bar_background_color="@color/progress_bar_background_default"
    app:progress_bar_foreground_color="@color/progress_bar_default_color"
    app:progress_text_color="@color/progress_bar_background_course_header" />

ProgressBadgeWidget 的 xml 布局如下:

<merge 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="match_parent"
android:gravity="center_horizontal"
tools:parentTag="com.trala.learn.violin.view.core.widgets.ProgressBadgeWidget">

<TextView
    android:id="@+id/badge_title"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:fontFamily="@font/avenir_family"
    android:gravity="center"
    android:letterSpacing="-0.04"
    android:textColor="@color/courses_badge_text_color"
    android:textSize="12sp"
    app:lineHeight="16sp"
    app:layout_constraintBottom_toTopOf="@id/badge_image"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"

    />

<com.trala.learn.violin.view.core.widgets.EZColorProgressBar
    android:id="@+id/progress_badge_widget_progress_bar"
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHeight_percent="0.10"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintWidth_percent="0.90"
    tools:progress="50" />

<ImageView
    android:id="@+id/badge_image"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:visibility="invisible"
    app:layout_constraintBottom_toBottomOf="@id/progress_badge_widget_progress_bar"
    app:layout_constraintDimensionRatio="1:1"
    app:layout_constraintEnd_toEndOf="@id/progress_badge_widget_progress_bar"
    app:layout_constraintStart_toStartOf="@id/progress_badge_widget_progress_bar"
    app:layout_constraintTop_toTopOf="@id/progress_badge_widget_progress_bar"
    app:layout_constraintWidth_percent="0.27"
    tools:src="@drawable/trophy_gold" />

<TextView
    android:id="@+id/progress_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:fontFamily="@font/avenir_family"
    android:textColor="@color/courses_badge_text_color"
    android:textSize="12sp"
    android:textStyle="bold"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@id/badge_image"
    tools:text="4/7" />

非常简单,如前所述。主要部分是 EZColorProgressBar,它是 ProgressBar 的一个子类,只是提供了更改条形颜色的方法以及设置进度和最大值的方法:

 class EZColorProgressBar @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = android.R.attr.progressBarStyleHorizontal, defStyleRes: Int = 0):
            ProgressBar(context, attrs, defStyleAttr, defStyleRes) {


fun setProgressNumbers(currentCount: Int, totalCount: Int) {
        if (currentCount > totalCount) Timber.d("Current Badge Count > Total Badge Count")

        val shouldShowBadges = currentCount >= totalCount && (currentCount != 0 && totalCount != 0)
        showBadge(shouldShowBadges)

        viewBinding?.progressBadgeWidgetProgressBar?.setMax(totalCount)
        viewBinding?.progressBadgeWidgetProgressBar?.setProgress(currentCount)
        viewBinding?.progressText?.setText(String.format(context.getString(R.string.score_string), currentCount, totalCount))


      }
}

我在几乎所有的 Fragment 上都使用 ProgressBadgeWidget 和 EZProgressBar。当我在片段之间移动并向后导航时,进度条并不总是正确显示它们的数字,即第一次 0/5 将正确显示,然后导航到使用此 EZProgressBar 并向后导航的其他页面将显示 1/5,即使文本有 0/5。

第一个导航:

之后:数据模型后备进度条正确(从 0/5 可以看出是正确的)。看起来它正在应用另一个进度条中的 3/11

当这种情况发生时,它实际上将不正确的进度条编号应用于布局中的所有进度条(即 recyclerview 适配器中 item_level 的所有项目中的每个进度条,甚至在单独的片段中,因此它不与 recyclerview 绑定。)但是所有文本“x/x”再次正确显示。

我尝试过使用 kotlin 合成绑定和谷歌视图绑定。感觉就像进度条的单独实例(它们是分开的,因为我打印了哈希码)它们指向同一个进度条,因为它正在搜索基于 ID 的视图。 ProgressBadgeWidgets 具有唯一的 ID,但它们嵌套的进度条具有相同的 ID。

有没有人遇到过类似的问题和/或专门针对 Android 进度条的问题?

【问题讨论】:

    标签: android android-custom-view android-progressbar android-viewbinding


    【解决方案1】:

    我使用常规进度条,但将层列表 xml 用作 progressDrawable。有时,循环进度条的末尾没有更新其位置,而是使用了另一个回收视图值的位置。我使用mutate() 解决了这个问题:

    item.progress?.let {
        holder.mProgressLabel.text = String.format(context.getString(R.string.progress_label), it * 100)
        holder.mProgressView.progress = Math.round(it * 100).toInt()
        (holder.mProgressView.progressDrawable as LayerDrawable?)?.apply {
            mutate()
        }
    }
    

    【讨论】:

      【解决方案2】:

      如果有人遇到多个进度条没有正确更新的问题,似乎有一个与此相关的大 Android 错误。解决它的方法是在设置为正确数字之前显式更改/重置最大值和进度值。我将这些方法添加到我的自定义进度条中:

      fun setProgressSafely(progress: Int) {
          setProgress(progress + 1)
          setProgress(progress)
      }
      
      fun setMaxSafely(max: Int) {
          setMax(max + 1)
          setMax(max)
      }
      

      【讨论】:

        猜你喜欢
        • 2017-08-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多