2013-02-22 18 views
11

Mam formularz, który dynamicznie generuję na podstawie danych, które otrzymuję z usługi internetowej. Ta usługa sieci Web zapewnia obrazy, które należy wykorzystać w tworzeniu elementów wejściowych. Mam trudności z ustawieniem progressDrawable z RatingBar. Choć XML jestem w stanie zastosować niestandardowy obraz przy użyciu następujących jako progressDrawable:Konstruowanie paska ocen za pomocą obrazów załadowanych z Internetu

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

gdzie custom_star jest prosty obraz .png, a wraz z @android:style/Widget.RatingBar jak styl RatingBar. Działa to dobrze:

Working start

ale ja chcąc zmienić custom_star dynamicznie.

W kodzie, próbowałem ustawienie rozciągliwej postępu za pomocą bitmapy bezpośrednio:

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

a także konstruowania 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); 

Ani pracuje dla mnie; zarówno skutkować custom_star odkształcalne pojawiające się raz, przeciągnął przez wymiarów RatingBar:

enter image description here

pomysłów?

Update: Odpowiedź

Luksprog jest poniżej dokonał poprawę, ale nadal mam kilka problemów. Teraz odkształcalne gwiazda nie jest rozciągnięta i wartość można ustawić za pomocą dotyku, ale wydaje się, tak z 3/5 wybrany:

no secondary

i 5/5 wybrany:

too many stars

Uważam, że skalowanie obrazów można naprawić za pomocą kilku poprawek, ale denerwująco rysowanie secondaryProgress wydaje się nie być ustawione - ciągnięcie używane dla wyszarzonych nie wybranych gwiazd. Bez tego nie jest to zbyt użyteczne.

Odpowiedz

11

Jakieś pomysły?

Podczas korzystania z domyślnego progressDrawable lub progressDrawable ustawić za pomocą motywu wszystko będzie ok jak w konstruktor RatingBar (nadklasy ProgressBar być bardziej precyzyjny) widget metoda zostanie wywołana aby „płytki” z że można wyciągnąć. W przypadku korzystania z metody setProgressDrawable tak się nie dzieje i jeśli przekażemy prosty BitmapDrawable lub LayerDrawable (z prostym BitmapDrawables), to po prostu zostanie rozciągnięty, aby pokryć obszar tła widżetu (co widać).

Aby to działało, trzeba ręcznie wykonać to, co na początku robi RatingBar, utworzyć kafelki wraz z użytym ClipDrawables.Pisałem ten sposób, po kodzie źródłowym 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; 
} 

Następnie należy użyć LayerDrawable zwracany przez tej metody z metodą setProgressDrawable. RatingBar ustawił swoją szerokość, mnożąc szerokość jednej ze stanowych bitmap z liczbą gwiazd, więc aby pokazać odpowiednią ilość gwiazdek, należy to również obliczyć.

+0

Świetne rzeczy. To zdecydowanie działa dla mnie, chociaż nie mogę tego zrobić, aby ustawić secondaryProgress. Gwiazdy pojawiają się po kliknięciu, ale wyszarzone, niewybrane tło nie pojawiają się (używam innego losowania, R.drawable.star_off). – blork

+1

Chociaż Twoje dokładne rozwiązanie nie działało dla mnie, sprawdziłem [kod źródłowy Androida dla ProgressBar] (http://grepcode.com/file_/repository.grepcode.com/java/ext/com.google.android/ android/2.3.3_r1/android/widget/ProgressBar.java /) zgodnie z sugestią, a wyodrębnianie metody tileify() zadziałało dla mnie świetnie. Dzięki! – blork

+2

@blork Przepraszam za opublikowany przeze mnie kod (nie miałem zbyt dużo czasu), nie w pełni zreplikowałem tę metodę (w jakiś sposób straciłem flagę 'clip'). Jestem pewien, że udało ci się również sprawić, by gwiazdy miały właściwy rozmiar. 'RatingBar' ustawia swoją szerokość, mnożąc szerokość jednej z bitmap z liczbą gwiazdek (obliczając to w metodzie' onMeasure' niestandardowego 'RatingBar' powinno pokazywać odpowiednią ilość gwiazdek). – Luksprog

0

identyfikatory są złe, trzeba ustawić @android: id/t @android: id/secondaryProgress @android: id/postęp

Można również zdefiniować rozciągliwej w XML zawierający swoją dostosowywanie

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

i można korzystać setMax na obiekcie RatingBar ustawić maksymalną ilość gwiazd, które mogą być wyświetlane

0

jest dużo łatwiej z takim więc lution:

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