基于Anko与Kotlin的自定义RatingBar设置评分不生效问题求助
Hey there! Let's tackle why your custom StarRatingView isn't showing the 3-star rating when you call setRating(3) in your Anko layout. This is a common gotcha with Anko's DSL and custom Views, so let's break down the likely issues and fixes.
Common Causes & Solutions
1. Your Custom RatingBar Isn't Triggering UI Updates
First, check if your StarRatingView properly handles rating changes. When you call setRating(), you need to ensure the View redraws itself to reflect the new value.
Here's a corrected version of your custom RatingBar:
class StarRatingView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = android.R.attr.ratingBarStyle ) : RatingBar(context, attrs, defStyleAttr) { init { // Add your custom styling here (e.g., custom star drawables) val starDrawable = ContextCompat.getDrawable(context, R.drawable.custom_star) starDrawable?.let { progressDrawable = it secondaryProgressDrawable = it ratingDrawable = it } } override fun setRating(rating: Float) { super.setRating(rating) // Force the View to redraw with the new rating invalidate() // If your custom View has size changes, add requestLayout() too // requestLayout() } }
The key here is calling invalidate() after setting the rating—this tells Android to redraw the View immediately.
2. Timing Issue in Anko DSL
Anko creates Views quickly during layout inflation, and sometimes setRating() is called before the View is fully attached to the screen. In this case, the rating change doesn't trigger a redraw because the View isn't ready yet.
Fix this by using post() to delay the rating setting until the View is attached:
verticalLayout { starRatingView { // Post the rating update to the main thread's message queue post { setRating(3f) } } }
post() ensures your setRating() call runs after the View has finished measuring and attaching to the window, so the change will be visible.
3. Missing or Incorrect Anko DSL Extension
Double-check that you have a proper Anko extension function for your custom View. Without this, Anko might not initialize the View correctly:
// Add this at the top level or in a dedicated Anko extensions file inline fun ViewManager.starRatingView(init: StarRatingView.() -> Unit): StarRatingView { return ankoView({ StarRatingView(it) }, theme = 0, init = init) }
This extension lets Anko properly create and initialize your StarRatingView in the DSL.
4. Hardcoded Default Rating in Custom View
Make sure you aren't setting a default rating in your StarRatingView's init block that overrides the value you set later. For example, avoid lines like setRating(0f) in the init unless that's intentional—this would overwrite your 3-star setting.
Test It Out
Putting it all together, your MainActivity should look something like this:
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) verticalLayout { starRatingView { post { setRating(3f) } } } } }
This should correctly display a 3-star rating once the View is ready.
内容的提问来源于stack exchange,提问作者Blender

