Construir una RatingBar utilizando imágenes cargadas desde la web

Tengo un formulario que estoy generando dinámicamente a partir de los datos que recibo de un servicio web. Este servicio web proporciona imágenes que deben utilizarse en la creación de elementos de entrada. Estoy teniendo difficuly en establecer el progressDrawable de un RatingBar . Aunque XML soy capaz de aplicar una imagen personalizada utilizando lo siguiente como el progressDrawable :

 <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+android:id/background" android:drawable="@drawable/custom_star" /> <item android:id="@+android:id/secondaryProgress" android:drawable="@drawable/custom_star" /> <item android:id="@+android:id/progress" android:drawable="@drawable/custom_star" /> </layer-list> 

Donde custom_star es una simple imagen .png, y con @android:style/Widget.RatingBar como el estilo RatingBar. Esto funciona bien:

Inicio de trabajo

Pero estoy deseando cambiar custom_star dinámicamente.

En código, he intentado establecer el progreso dibujable usando un mapa de bits directamente:

 Drawable d = new BitmapDrawable(getResources(), downloadedImage); ratingBar.setProgressDrawable(d); 

Y también construyendo una layer-list :

 LayerDrawable layerDrawable = new LayerDrawable(new Drawable[] { getResources().getDrawable(R.drawable.custom_star), getResources().getDrawable(R.drawable.custom_star), getResources().getDrawable(R.drawable.custom_star) }); layerDrawable.setId(0, android.R.id.background); layerDrawable.setId(1, android.R.id.secondaryProgress); layerDrawable.setId(2, android.R.id.progress); ratingBar.setProgressDrawable(layerDrawable); 

Ninguno de los dos trabaja para mí; Ambos resultan en el custom_star dibujable apareciendo una vez, estirado por las dimensiones de la RatingBar :

Introduzca aquí la descripción de la imagen

¿Algunas ideas?

Actualizar:

La respuesta de Luksprog a continuación ha mejorado, pero todavía tengo un par de problemas. Ahora, la estrella dibujable no es estirada y el valor puede ser fijado por el tacto, pero aparece como así con 3/5 seleccionado:

Sin secundario

Y 5/5 seleccionados:

Demasiadas estrellas

Creo que la escala de las imágenes se puede arreglar con unos pocos ajustes, pero molesto el secondaryProgress dibujable no parece estar establecido – el dibujable utilizado para las estrellas de color gris no seleccionado. Sin eso, no es muy útil.

¿Algunas ideas?

Cuando se utiliza el progressDrawable defecto progressDrawable o un conjunto progressDrawable través de un tema todo estará bien como en el constructor de la RatingBar (su superclase ProgressBar para ser más preciso) widget un método será llamado para "hacer azulejos" a partir de ese dibujable. Cuando se utiliza el método setProgressDrawable esto no sucede y si pasas un simple BitmapDrawable o un LayerDrawable (con BitmapDrawables simple) Drawable simplemente se Drawable para cubrir el área de fondo del widget (lo que ves sabes).

Con el fin de hacer que funcione necesitaría hacer manualmente lo que hace la RatingBar al inicio, crear las fichas junto con la ClipDrawables que utiliza. He escrito un método para esto, siguiendo el código fuente del widget ProgressBar :

 private Drawable buildRatingBarDrawables(Bitmap[] images) { final int[] requiredIds = { android.R.id.background, android.R.id.secondaryProgress, android.R.id.progress }; final float[] roundedCorners = new float[] { 5, 5, 5, 5, 5, 5, 5, 5 }; Drawable[] pieces = new Drawable[3]; for (int i = 0; i < 3; i++) { ShapeDrawable sd = new ShapeDrawable(new RoundRectShape( roundedCorners, null, null)); BitmapShader bitmapShader = new BitmapShader(images[i], Shader.TileMode.REPEAT, Shader.TileMode.CLAMP); sd.getPaint().setShader(bitmapShader); ClipDrawable cd = new ClipDrawable(sd, Gravity.LEFT, ClipDrawable.HORIZONTAL); if (i == 0) { pieces[i] = sd; } else { pieces[i] = cd; } } LayerDrawable ld = new LayerDrawable(pieces); for (int i = 0; i < 3; i++) { ld.setId(i, requiredIds[i]); } return ld; } 

Entonces utilizaría el LayerDrawable devuelto por este método con el método setProgressDrawable . El RatingBar establecer su ancho multiplicando el ancho de uno de los mapas de estado bit con el número de estrellas, por lo que a fin de mostrar la cantidad correcta de estrellas esto también tiene que ser calculado.

Tus ids están equivocados, tienes que configurar @android: id / background @android: id / secondaryProgress @android: id / progress

También puede definir un dibujable en xml que contenga su personalización

 <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+android:id/background" android:drawable="@drawable/star_empty" /> <item android:id="@+android:id/secondaryProgress" android:drawable="@drawable/star_empty" /> <item android:id="@+android:id/progress" android:drawable="@drawable/star_full" /> </layer-list> 

Y puede usar setMax en el objeto RatingBar para establecer la cantidad máxima de estrellas que se pueden mostrar

Es mucho más fácil con esta solución:

 RatingBar ratingBar = new RatingBar(new ContextThemeWrapper(context, R.style.AppTheme_RatingBar), null, 0); 
  • Android RatingBar: No puede completar un ratingBar parcial si personalizo su color
  • Android: la barra de calificación no es visible, sólo se hace visible al tocarla
  • Androide. RatingBar (llenando la siguiente estrella)
  • RatingBar se está semi-transparente
  • ¿Cómo puedo configurar el color estrella de la barra de calificación?
  • Cómo establecer una calificación específica en RatingBar en Espresso?
  • Clasificación de estrellas de Android cómo ajustar a ancho
  • obtener valor RatingBar mientras se desliza
  • ¿Cómo dar el espaciamiento entre la barra de clasificación de estrellas Android?
  • RatingBar: mismo rating dos veces
  • RatingBar - Alternar o deshacer
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.