2011-04-27 64 views
58

您好我需要在我的應用程序中執行評級...所以我需要創建自定義評級欄...任何人都可以幫助我嗎?如何在Android中創建自定義評級欄

+5

某些代碼片段會很有用(可能是您的目標的模型),以查看您到目前爲止的位置。看看你的帖子,它不覺得要解決問題,更多的工作機會,請詳細說明。 – rekaszeru 2011-04-27 07:18:13

回答

134

編輯

看一看定製的評級摩托羅拉http://community.developer.motorola.com/t5/Android-App-Development-for/custom-rating-bar-style-using-android-s-ratingBar-small-style/td-p/10462

更新

styles.xml

這必須位於你的價值觀夾

<?xml version="1.0" encoding="utf-8"?> 
    <resources> 
    <style name="foodRatingBar" parent="@android:style/Widget.RatingBar"> 
     <item name="android:progressDrawable">@drawable/food_rating_bar_full</item> 
     <item name="android:minHeight">23dip</item> 
     <item name="android:maxHeight">25dip</item> 
    </style> 
    </resources> 

food_rating_bar_full.xml

此文件必須位於Drawable文件夾中。

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

food_ratingbar_full_empty.xml

此文件必須是可繪製文件夾內。

<?xml version="1.0" encoding="utf-8"?> 

<!-- This is the rating bar drawable that is used to 
show a filled cookie. --> 
<selector 
xmlns:android="http://schemas.android.com/apk/res/android"> 

<item android:state_pressed="true" 
     android:state_window_focused="true" 
     android:drawable="@drawable/cookiee" /> 

<item android:state_focused="true" 
     android:state_window_focused="true" 
     android:drawable="@drawable/cookiee" /> 

<item android:state_selected="true" 
     android:state_window_focused="true" 
     android:drawable="@drawable/cookiee" /> 

<item android:drawable="@drawable/cookiee" /> 

</selector> 

food_ratingbar_full_filled.xml

此文件必須位於可繪製文件夾中。

<?xml version="1.0" encoding="utf-8"?> 

<!-- This is the rating bar drawable that is used to 
show a unfilled cookie. --> 
<selector 
xmlns:android="http://schemas.android.com/apk/res/android"> 

<item android:state_pressed="true" 
     android:state_window_focused="true" 
     android:drawable="@drawable/cookie" /> 

<item android:state_focused="true" 
     android:state_window_focused="true" 
     android:drawable="@drawable/cookie" /> 

<item android:state_selected="true" 
     android:state_window_focused="true" 
     android:drawable="@drawable/cookie" /> 

<item android:drawable="@drawable/cookie" /> 

</selector> 

的main.xml文件應該是這樣:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 

    <RatingBar android:id="@+id/ratingBar1" 
     style="@style/foodRatingBar" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content"> 

    </RatingBar> 
</LinearLayout> 

MainActivity.class應該是這樣的:

import android.app.Activity; 
import android.os.Bundle; 
import android.widget.RatingBar; 
import android.widget.RatingBar.OnRatingBarChangeListener; 
import android.widget.Toast; 

public class MainActivity extends Activity { 
/** Called when the activity is first created. */ 

RatingBar rb; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    rb=(RatingBar)findViewById(R.id.ratingBar1); 

    rb.setOnRatingBarChangeListener(new OnRatingBarChangeListener(){ 

     @Override 
     public void onRatingChanged(RatingBar ratingBar, float rating, 
       boolean fromUser) { 
      // TODO Auto-generated method stub 
       Toast.makeText(getApplicationContext(),Float.toString(rating),Toast.LENGTH_LONG).show(); 

     } 

    }); 
} 
} 

我用兩個圖像:

cookie.jpg

cookiee .JPG

這兩個圖像是相同的大小爲一用於識別選擇的評分酒吧和其它用於識別未被選擇的RatingBar

+0

我無法使用我創建的自定義樣式,如<?xml version =「1.0」encoding =「utf-8」?> 時我使用它像這樣然後它給我錯誤 – 2011-04-27 08:05:56

+0

最新錯誤?... – 2011-04-27 08:45:16

+0

指定我自己的自定義樣式,當我在我的main.xml中使用它像樣式=「@ style/hotel_rating_bar_indicator」然後它顯示無法解決資源@ style/hotel_rating_bar_indicator ..... – 2011-04-28 04:10:19

48

我需要添加我的解決辦法是WAY比上面所述一個eaiser。我們甚至不需要使用樣式。

在繪製文件夾中創建一個選擇文件:

custom_ratingbar_selector.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_off" /> 

<item android:id="@android:id/secondaryProgress" 
    android:drawable="@drawable/star_off" /> 

<item android:id="@android:id/progress" 
    android:drawable="@drawable/star_on" /> 

</layer-list> 

在設置選擇文件progressDrawable佈局:

<RatingBar 
     android:id="@+id/ratingBar2" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center_horizontal" 
     android:layout_marginTop="20dp" 
     android:progressDrawable="@drawable/custom_ratingbar_selector" 
     android:numStars="8" 
     android:stepSize="0.2" 
     android:rating="3.0" /> 

這就是我們所需要的。

+0

+1,但對不起,這應該是工作,但它不是。首先,你說你添加了選擇器,但實際上你添加了一個圖層列表。其次,我嘗試了你的代碼,但所有我得到的是一個空白的組件(根本沒有圖像)。也許你可以回答我的問題:http://stackoverflow.com/questions/14251092/custom-rating-bar-not-showing-any-image 謝謝:D – 2013-01-10 05:03:53

+2

這種簡單的方法會導致定位杆在佈局中出現問題,而定義樣式的更傳統方法更好。 – javaxian 2014-05-05 11:25:35

+0

是的,似乎對我需要的東西很好。 – 2015-11-20 23:07:35

-10

你可以有5個imageview與defalut圖像作爲空的明星,並填寫評級欄上的一半或完整的圖像基礎評級。

public View getView(int position, View convertView, ViewGroup parent) { 
    LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    View grid=inflater.inflate(R.layout.griditem, parent, false); 
    imageView=(ImageView)grid.findViewById(R.id.grid_prod); 
    imageView.setImageResource(imgId[position]); 
    imgoff =(ImageView)grid.findViewById(R.id.offer); 
    tv=(TextView)grid.findViewById(R.id.grid_text); 
    tv.setText(namesArr[position]); 
    tv.setTextColor(Color.BLACK); 
    tv.setPadding(0, 2, 0, 0); 
    sta=(ImageView)grid.findViewById(R.id.imageView); 
    sta1=(ImageView)grid.findViewById(R.id.imageView1); 
    sta2=(ImageView)grid.findViewById(R.id.imageView2); 
    sta3=(ImageView)grid.findViewById(R.id.imageView3); 
    sta4=(ImageView)grid.findViewById(R.id.imageView4); 
    Float rate=rateFArr[position]; 


    if(rate==5 || rate==4.5) 
    { 
     sta.setImageResource(R.drawable.full__small); 
     sta1.setImageResource(R.drawable.full__small); 
     sta2.setImageResource(R.drawable.full__small); 
     sta3.setImageResource(R.drawable.full__small); 
     if(rate==4.5) 
     { 
      sta4.setImageResource(R.drawable.half_small); 
     } 
     else 
     { 
      sta4.setImageResource(R.drawable.full__small); 
     } 
    } 
    if(rate==4 || rate==3.5) 
    { 
     sta.setImageResource(R.drawable.full__small); 
     sta1.setImageResource(R.drawable.full__small); 
     sta2.setImageResource(R.drawable.full__small); 
    if(rate==3.5) 
     { 
      sta3.setImageResource(R.drawable.half_small); 
     } 
     else 
     { 
      sta3.setImageResource(R.drawable.full__small); 
     } 
    } 
    if(rate==3 || rate==2.5) 
    { 
     sta.setImageResource(R.drawable.full__small); 
     sta1.setImageResource(R.drawable.full__small); 
     if(rate==2.5) 
     { 
      sta2.setImageResource(R.drawable.half_small); 
     } 
     else 
     { 
      sta2.setImageResource(R.drawable.full__small); 
     } 
    } 
    if(rate==2 || rate==1.5) 
    { 
    sta.setImageResource(R.drawable.full__small); 
    if(rate==1.5) 
     { 
      sta1.setImageResource(R.drawable.half_small); 
     } 
     else 
     { 
      sta1.setImageResource(R.drawable.full__small); 
     } 
    } 
    if(rate==1 || rate==0.5) 
    { 
     if(rate==1) 
     sta.setImageResource(R.drawable.full__small); 
     else 
      sta.setImageResource(R.drawable.half_small); 

    } 
    if(rate>5) 
    { 
     sta.setImageResource(R.drawable.full__small); 
     sta1.setImageResource(R.drawable.full__small); 
     sta2.setImageResource(R.drawable.full__small); 
     sta3.setImageResource(R.drawable.full__small); 
     sta4.setImageResource(R.drawable.full__small); 
    } 

    // rb=(RatingBar)findViewById(R.id.grid_rating); 
    //rb.setRating(rateFArr[position]); 
     return grid; 
    } 
+0

這不是做這件事的方法。爲了做到這一點,就是'RatingBar'部件。這也不是OP要求的。 – 4gus71n 2013-10-25 13:48:31

+0

不要建立一個we – Borys 2014-03-20 06:58:02

+2

這是不正確的方式。 – 2014-08-08 10:23:59

0

當創建一個顯示在搜索欄般的軌道上運行了堅實的梯度線,而不是明星定製的評價吧,我也遇到了相關的背景(軌跡繪製)的垂直居中的問題。這是有缺陷的可繪製代碼我最初使用(其產生的問題),由Android顯影劑和其他的StackOverflow條目的建議:

<?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/seekbar_track"/> 
    <item android:id="@android:id/secondaryProgress"> 
     <scale 
      android:drawable="@drawable/seekbar_progress2" 
      android:scaleWidth="100%" /> 
    </item> 

    <item android:id="@android:id/progress" > 
     <clip android:clipOrientation="horizontal" android:gravity="left" > 
      <shape> 
       <gradient 
        android:startColor="@color/ratingbar_bg_start" 
        android:centerColor="@color/ratingbar_bg_center" 
        android:centerX="0.5" 
        android:endColor="@color/ratingbar_bg_end" 
        android:angle="0" 
        /> 
      </shape> 
     </clip> 
    </item>  

</layer-list> 

這裏的問題是第一項,其涉及到自定義的RatingBar的背景。許多條目會告訴您將layout_minHeight功能設置爲較大的值,以避免拇指與其軌道之間的垂直空間斷開。這對我來說並不是解決方案 - 在平板電腦上觀看時,背景仍然在繪製到較小的手機尺寸 - 因此軌道始終位於RatingBar軌道中心的上方。解決的辦法是除去上述的RatingBar繪製此項目,所以現在看起來是這樣的:

<?xml version="1.0" encoding="utf-8"?> 
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> 

    <item android:id="@android:id/secondaryProgress"> 
     <scale 
      android:drawable="@drawable/seekbar_progress2" 
      android:scaleWidth="100%" /> 
    </item> 

    <item android:id="@android:id/progress" > 
     <clip android:clipOrientation="horizontal" android:gravity="left" > 
      <shape> 
       <gradient 
        android:startColor="@color/ratingbar_bg_start" 
        android:centerColor="@color/ratingbar_bg_center" 
        android:centerX="0.5" 
        android:endColor="@color/ratingbar_bg_end" 
        android:angle="0" 
        /> 
      </shape> 
     </clip> 
    </item>  

</layer-list> 

然後,在自定義的RatingBar的風格定義,layout_background設置爲軌道繪製。我看起來像這樣:

<style name="styleRatingBar" parent="@android:style/Widget.RatingBar"> 
    <item name="android:indeterminateOnly">false</item> 
    <item name="android:background">@drawable/seekbar_track</item> 
    <item name="android:progressDrawable">@drawable/abratingbar</item> 
    <item name="android:thumb">@drawable/abseekbar_thumb</item> 
    <item name="android:minHeight">@dimen/base_29dp</item> 
    <item name="android:maxHeight">@dimen/base_29dp</item> 
    <item name="android:layout_marginLeft">@dimen/base_10dp</item> 
    <item name="android:layout_marginRight">@dimen/base_10dp</item> 
    <item name="android:layout_marginTop">@dimen/base_10dp</item> 
    <item name="android:layout_marginBottom">@dimen/base_10dp</item> 
    <item name="android:scaleType">fitXY</item> 
</style> 

(以前,這裏的背景設置是未定義的。)。

這是我的佈局中的條目,它同時使用的樣式和繪圖資源:

<RatingBar 
    android:id="@+id/ratingbar_vote" 
    style="@style/styleRatingBar" 
    android:hint="@string/ratingbar_vote" 
    android:contentDescription="@string/ratingbar_vote" 
    android:numStars="5" 
    android:rating="5" 
    android:stepSize="1" 
    android:layout_width="match_parent" 
    android:layout_height="@dimen/base_29dp" 
    android:layout_marginLeft="@dimen/base_120dp" 
    android:layout_gravity="bottom|right" /> 

因此,要總結,不設置背景(軌道)功能,在您的自定義的RatingBar繪製,將其設置在您的自定義RatingBar樣式的layout_background功能中。這確保軌道始終垂直居中在水平RatingBar中。 (請記住,在這個自定義的RatingBar中,我使用的是漸變線,它可以水平「增長」或「縮小」以顯示評分 - 此評分線使用SeekBar-like thumb 。在搜索欄般的 「軌道」 上運行)

1

下面的代碼工作:

@Override 
protected synchronized void onDraw(Canvas canvas) 
{ 
    int stars = getNumStars(); 
    float rating = getRating(); 
    try 
    { 
     bitmapWidth = getWidth()/stars; 
    } 
    catch (Exception e) 
    { 
     bitmapWidth = getWidth(); 
    } 
    float x = 0; 

    for (int i = 0; i < stars; i++) 
    { 
     Bitmap bitmap; 
     Resources res = getResources(); 
     Paint paint = new Paint(); 

     if ((int) rating > i) 
     { 
      bitmap = BitmapFactory.decodeResource(res, starColor); 
     } 
     else 
     { 
      bitmap = BitmapFactory.decodeResource(res, starDefault); 
     } 
     Bitmap scaled = Bitmap.createScaledBitmap(bitmap, getHeight(), getHeight(), true); 
     canvas.drawBitmap(scaled, x, 0, paint); 
     canvas.save(); 
     x += bitmapWidth; 
    } 

    super.onDraw(canvas); 
} 
34

第一添加圖像繪製:

enter image description hereenter image description here

的第一張照片「ratingbar_staroff.p NG 「和第二 」ratingbar_staron.png「

後,創建 」ratingbar.xml「 上RES /抽拉

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

下一XML上RES相同的/可繪

」 ratingbar_empty。XML」

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 

    <item android:state_pressed="true" 
     android:state_window_focused="true" 
     android:drawable="@drawable/ratingbar_staroff" /> 

    <item android:state_focused="true" 
     android:state_window_focused="true" 
     android:drawable="@drawable/ratingbar_staroff" /> 

    <item android:state_selected="true" 
     android:state_window_focused="true" 
     android:drawable="@drawable/ratingbar_staroff" /> 

    <item android:drawable="@drawable/ratingbar_staroff" /> 

</selector> 

「ratingbar_filled」

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 

    <item android:state_pressed="true" 
     android:state_window_focused="true" 
     android:drawable="@drawable/ratingbar_staron" /> 

    <item android:state_focused="true" 
     android:state_window_focused="true" 
     android:drawable="@drawable/ratingbar_staron" /> 

    <item android:state_selected="true" 
     android:state_window_focused="true" 
     android:drawable="@drawable/ratingbar_staron" /> 

    <item android:drawable="@drawable/ratingbar_staron" /> 

</selector> 

做下,加上RES /價值/風格的幾行代碼

<style name="CustomRatingBar" parent="@android:style/Widget.RatingBar"> 
    <item name="android:progressDrawable">@drawable/ratingbar</item> 
    <item name="android:minHeight">18dp</item> 
    <item name="android:maxHeight">18dp</item> 
</style> 

現在,已經可以添加樣式的RatingBar資源

 <RatingBar 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      style= "@style/CustomRatingBar" 
      android:id="@+id/ratingBar" 
      android:numStars="5" 
      android:stepSize="0.01" 
      android:isIndicator="true"/> 

終於在你身上ctivity只是聲明:

RatingBar ratingbar = (RatingBar) findViewById(R.id.ratingbar); 
ratingbar.setRating(3.67f); 

enter image description here

+5

與選中的答案類似。但有圖片(顯示分數星)和<! - 在層列表中抑制AndroidDomInspection - >。您可以改爲刪除「@ + android:id/background」中的加號以避免android錯誤。還應該將minHeight和maxHeight更改爲50dp。 – CoolMind 2016-03-17 13:57:13

+0

圖片的好例子 – ono 2016-07-19 19:55:08

+0

感謝您的解決方案。我可否知道你如何調整星星的大小?我的上升很小。謝謝。 – jay 2017-03-03 21:45:59

2

製作與層列表,並選擇自定義的等級欄是複雜的,這是更好地覆蓋的RatingBar類,並創建一個自定義的RatingBar。 createBackgroundDrawableShape()是你應該把你的空狀態png的函數,createProgressDrawableShape()是你應該把你的填充狀態png的函數。

注意:此代碼現在不適用於svg。

public class CustomRatingBar extends RatingBar { 

@Nullable 
private Bitmap mSampleTile; 

public ShapeDrawableRatingBar(final Context context, final AttributeSet attrs) { 
    super(context, attrs); 
    setProgressDrawable(createProgressDrawable()); 
} 

@Override 
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 

    if (mSampleTile != null) { 
     final int width = mSampleTile.getWidth() * getNumStars(); 
     setMeasuredDimension(resolveSizeAndState(width, widthMeasureSpec, 0), 
       getMeasuredHeight()); 
    } 
} 

protected LayerDrawable createProgressDrawable() { 
    final Drawable backgroundDrawable = createBackgroundDrawableShape(); 
    LayerDrawable layerDrawable = new LayerDrawable(new Drawable[]{ 
      backgroundDrawable, 
      backgroundDrawable, 
      createProgressDrawableShape() 
    }); 
    layerDrawable.setId(0, android.R.id.background); 
    layerDrawable.setId(1, android.R.id.secondaryProgress); 
    layerDrawable.setId(2, android.R.id.progress); 
    return layerDrawable; 
} 

protected Drawable createBackgroundDrawableShape() { 
    final Bitmap tileBitmap = drawableToBitmap(getResources().getDrawable(R.drawable.ic_star_empty)); 
    if (mSampleTile == null) { 
     mSampleTile = tileBitmap; 
    } 
    final ShapeDrawable shapeDrawable = new ShapeDrawable(getDrawableShape()); 
    final BitmapShader bitmapShader = new BitmapShader(tileBitmap, Shader.TileMode.REPEAT, Shader.TileMode.CLAMP); 
    shapeDrawable.getPaint().setShader(bitmapShader); 
    return shapeDrawable; 
} 

protected Drawable createProgressDrawableShape() { 
    final Bitmap tileBitmap = drawableToBitmap(getResources().getDrawable(R.drawable.ic_star_full)); 
    final ShapeDrawable shapeDrawable = new ShapeDrawable(getDrawableShape()); 
    final BitmapShader bitmapShader = new BitmapShader(tileBitmap, Shader.TileMode.REPEAT, Shader.TileMode.CLAMP); 
    shapeDrawable.getPaint().setShader(bitmapShader); 
    return new ClipDrawable(shapeDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL); 
} 

Shape getDrawableShape() { 
    final float[] roundedCorners = new float[]{5, 5, 5, 5, 5, 5, 5, 5}; 
    return new RoundRectShape(roundedCorners, null, null); 
} 

public static Bitmap drawableToBitmap(Drawable drawable) { 
    if (drawable instanceof BitmapDrawable) { 
     return ((BitmapDrawable) drawable).getBitmap(); 
    } 

    int width = drawable.getIntrinsicWidth(); 
    width = width > 0 ? width : 1; 
    int height = drawable.getIntrinsicHeight(); 
    height = height > 0 ? height : 1; 

    final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 
    final Canvas canvas = new Canvas(bitmap); 
    drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); 
    drawable.draw(canvas); 

    return bitmap; 
} 

}

4

你可以試試這個等級酒吧,更好的動畫

SmileyRating

enter image description here

0

您可以創建通過定義使用您選擇的材料圖標繪製XML,然後應用自定義繪製使用 progressDrawable屬性等級欄自定義材質等級吧。

有關自定義的評價欄看到 http://www.zoftino.com/android-ratingbar-and-custom-ratingbar-example

下面繪製XML infomration使用大拇指圖標的評價吧。

<?xml version="1.0" encoding="utf-8"?> 
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:id="@android:id/background"> 
     <bitmap 
      android:src="@drawable/thumb_up" 
      android:tint="?attr/colorControlNormal" /> 
    </item> 
    <item android:id="@android:id/secondaryProgress"> 
     <bitmap 
      android:src="@drawable/thumb_up" 
      android:tint="?attr/colorControlActivated" /> 
    </item> 
    <item android:id="@android:id/progress"> 
     <bitmap 
      android:src="@drawable/thumb_up" 
      android:tint="?attr/colorControlActivated" /> 
    </item> 
</layer-list>