2013-02-22 35 views
11

Tôi có một biểu mẫu mà tôi đang tạo động từ dữ liệu tôi nhận được từ một dịch vụ web. Dịch vụ web này cung cấp hình ảnh cần được sử dụng để tạo các yếu tố đầu vào. Tôi đang có difficuly trong việc thiết lập các progressDrawable của một RatingBar. Mặc dù XML tôi có thể áp dụng một hình ảnh tùy chỉnh bằng cách sử dụng sau khi progressDrawable:Xây dựng một RatingBar sử dụng hình ảnh được tải từ trang web

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

nơi custom_star là một hình ảnh .png đơn giản, và với @android:style/Widget.RatingBar như phong cách RatingBar. Đây hoạt động tốt:

Working start

nhưng tôi muốn thay đổi custom_star động.

Trong mã, tôi đã cố gắng thiết lập các drawable tiến sử dụng một bitmap trực tiếp:

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

và cũng bằng cách xây dựng một 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); 

Không làm việc cho tôi; cả hai dẫn đến việc custom_star drawable xuất hiện một lần, kéo dài bằng kích thước của RatingBar:

enter image description here

Bất kỳ ý tưởng?

Cập nhật:

Luksprog của câu trả lời dưới đây đã được cải thiện, nhưng tôi vẫn đang gặp một vài vấn đề. Bây giờ, drawable sao không kéo dài và giá trị có thể được thiết lập bằng cảm ứng, nhưng nó xuất hiện như vậy với 3/5 chọn:

no secondary

và 5/5 chọn:

too many stars

Tôi tin rằng việc chia tỷ lệ hình ảnh có thể được sửa với một số chỉnh sửa, nhưng khó có thể vẽ được hình secondaryProgress - hình vẽ được sử dụng cho các ngôi sao không được chọn màu xám. Không có điều đó, nó không thể sử dụng được.

Trả lời

11

Bất kỳ ý tưởng nào?

Khi sử dụng mặc định progressDrawable hoặc một tập progressDrawable thông qua một chủ đề tất cả sẽ ok như trong các nhà xây dựng cho RatingBar (nó lớp cha ProgressBar được chính xác hơn) phụ tùng một phương pháp sẽ được gọi để "làm cho gạch" từ có thể vẽ được. Khi sử dụng phương pháp setProgressDrawable, điều này không xảy ra và nếu bạn vượt qua một đơn giản BitmapDrawable hoặc LayerDrawable (với đơn giản BitmapDrawables) thì Drawable sẽ đơn giản được kéo dài để che khu vực nền của tiện ích (những gì bạn biết).

Để làm cho nó hoạt động, bạn sẽ cần phải tự làm những gì các RatingBar không lúc bắt đầu, tạo gạch cùng với ClipDrawables mà nó sử dụng.Tôi đã viết một phương pháp cho điều này, sau khi mã nguồn của 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; 
} 

Sau đó, bạn sẽ sử dụng LayerDrawable trả về bởi phương pháp này với phương pháp setProgressDrawable. Các RatingBar thiết lập chiều rộng của nó nhân chiều rộng của một trong những bitmap nhà nước với số lượng các ngôi sao, do đó, để hiển thị số tiền phải của các ngôi sao này đã được tính là tốt.

+0

Great stuff. Điều này chắc chắn là làm việc cho tôi, mặc dù tôi dường như không thể làm cho nó để thiết lập secondaryProgress. Các ngôi sao xuất hiện khi được nhấp, nhưng các hình nền không được chọn màu xám không xuất hiện (tôi đang sử dụng một đối tượng có thể vẽ khác, R.drawable.star_off). – blork

+1

Mặc dù giải pháp chính xác của bạn không hiệu quả đối với tôi, tôi đã xem [mã nguồn Android cho ProgressBar] (http://grepcode.com/file_/repository.grepcode.com/java/ext/com.google.android/ android/2.3.3_r1/android/widget/ProgressBar.java /) như bạn đã đề xuất, và tách ra phương thức tileify() làm việc tuyệt vời cho tôi. Cảm ơn! – blork

+2

@blork Xin lỗi về mã tôi đã đăng (không có nhiều thời gian), nó không sao chép đầy đủ phương thức đó (bằng cách nào đó tôi đã mất cờ 'clip' đó). Tôi chắc chắn rằng bạn quản lý để cũng làm cho các ngôi sao có kích thước chính xác. 'RatingBar' đặt chiều rộng của nó bằng cách nhân chiều rộng của một trong các bitmap với số lượng các ngôi sao (tính toán điều này trong phương thức' onMeasure' của một 'RatingBar' tùy chỉnh sẽ hiển thị số lượng các ngôi sao phù hợp). – Luksprog

0

id của bạn là sai, bạn phải thiết lập @android: id/nền @android: id/secondaryProgress @android: id/tiến độ

Bạn cũng có thể xác định đối tượng vẽ được trong xml chứa tùy biến của bạ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> 

Và bạn có thể sử dụng setMax trên đối tượng RatingBar để đặt số tiền tối đa của các ngôi sao có thể được hiển thị

0

đó là dễ dàng hơn nhiều với ví dụ để lution:

RatingBar ratingBar = new RatingBar(new ContextThemeWrapper(context, R.style.AppTheme_RatingBar), null, 0); 
Các vấn đề liên quan