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:
- La Android RatingBar tiene umbral "malo" para ciertos dispositivos, ¿arreglarlo?
- Ocultar sombra de la barra de calificación
- ¿Cómo cambiar las imágenes en estrella de la RatingBar?
- ¿Cómo permitir valores completos (enteros) sólo en barras de calificación?
- Android - Cómo configurar la barra de calificación no se puede hacer clic y se puede tocar en HTC móvil
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
:
¿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:
Y 5/5 seleccionados:
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.
- Android - La barra de calificación personalizada se parece a su sangrado
- Problema de tamaño vertical de la barra de clasificación de Android
- Captura RatingBar Haga clic
- Android RatingBar se pinta mal
- Custom RatingBar Muestra un número diferente de estrellas cuando api 23
- Android: cambia el color de la barra de calificación a oro
- Android Nougat (7.0 / API 24) cuenta de clasificación está mal en OnRatingBarChangeListener
- Android RatingBar icono vector no se muestra
¿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);
- Cómo utilizar SwipeDismissBehavior.OnDismissListener en RecyclerView
- ¿Cuál es la mejor manera de obtener una duración de archivo de audio en Android?