Intereting Posts

Построение RatingBar с использованием изображений, загруженных из Интернета.

У меня есть форма, которую я динамически генерирую из данных, получаемых с веб-службы. Этот веб-сервис предоставляет изображения, которые необходимо использовать при создании элементов ввода. У меня трудности с настройкой progressDrawable из RatingBar . Хотя XML я могу применить пользовательский образ, используя следующее как 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> 

Где custom_star – это простое .png изображение, а с @android:style/Widget.RatingBar как стиль RatingBar. Это прекрасно работает:

Начало работы

Но я хочу изменить custom_star динамически.

В коде я попытался установить доступность выполнения с помощью растрового изображения напрямую:

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

А также путем создания 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); 

Ни для меня не работает; Оба приводят к тому, что custom_star появляется один раз, растягивается по размерам RatingBar :

Введите описание изображения здесь

Есть идеи?

Обновить:

Ответ Luksprog ниже сделал улучшение, но у меня все еще есть пара проблем. Теперь вытягиваемая звезда не растягивается, и значение может быть установлено прикосновением, но оно выглядит так, как показано на рисунке 3/5:

Нет вторичных

И 5/5:

Слишком много звезд

Я считаю, что масштабирование изображений может быть исправлено с помощью нескольких настроек, но раздражающе, что drawProcessProcessable не кажется установленным – drawable используется для серых не выбранных звезд. Без этого это не очень удобно.

Solutions Collecting From Web of "Построение RatingBar с использованием изображений, загруженных из Интернета."

Есть идеи?

При использовании стандартного progressDrawable или progressDrawable установленного через тему, все будет в порядке, как в конструкторе для более RatingBar (его суперкласс ProgressBar ), который будет вызываться методом «сделать плитки» из этого чертежа. При использовании метода setProgressDrawable этого не происходит, и если вы передаете простой BitmapDrawable или LayerDrawable (с простым BitmapDrawables ), то Drawable будет просто растянут, чтобы покрыть фоновый диапазон виджета (что вы знаете).

Чтобы заставить его работать, вам нужно вручную сделать то, что делает RatingBar при запуске, создать плитки вместе с ClipDrawables которые он использует. Я написал метод для этого, следуя исходному коду виджета 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; } 

Затем вы должны использовать LayerDrawable возвращенный этим методом, с setProgressDrawable метода setProgressDrawable . RatingBar установил свою ширину, умножая ширину одного из растровых изображений состояния на количество звезд, поэтому для того, чтобы показать нужное количество звезд, это также нужно вычислить.

Ваши идентификаторы ошибочны, вам нужно установить @android: id / background @android: id / secondaryProgress @android: id / progress

Вы также можете определить drawable в xml, который содержит вашу настройку

 <?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> 

И вы можете использовать setMax в объекте RatingBar для установки максимального количества звезд, которые могут отображаться

С таким решением намного проще:

 RatingBar ratingBar = new RatingBar(new ContextThemeWrapper(context, R.style.AppTheme_RatingBar), null, 0);