RatingBar是SeekBar和ProgressBar的扩展,用星星来评级。使用的默认大小RatingBar时,用户可以触摸/拖动或使用键来设置评分,它有俩种样式(大、小),其中大的只适合指示,不适合于用户交互。注意:用户不应修改Secondary Progress .
RatingBar中常用的属性有:
android:isIndicator:该RatingBar是否是指示器,如果设置为ture(是指示器),则用户不能改变他.
android:numStars: 显示“星星”的数量。
android:rating: 默认的等级。
android:stepSize: 步长。
RatingBar的一个监听器RatingBar.OnRatingBarChangeListener每次Rating的改变都会通知onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser)函数:其中参数rating——当前等级;fromUse——指示是否是用户操作使rating改变。
下面通过自定义RatingBar来学习该控件,开始之前先看看准备资源和做出来的效果:
准备资源,两张图片
rating_progress.png http://static.oschina.net/uploads/space/2012/0529/154758_SVgH_560730.png
rating_back.png http://static.oschina.net/uploads/space/2012/0529/154809_rs3X_560730.png
效果图如下:
接下来就一步一步实现上述效果:
1、布局文件widget_rating_bar_layout.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <RatingBar android:id="@+id/show_rating_bar" style="@style/customer_rating_bar_style" android:layout_width="wrap_content" android:layout_height="wrap_content" android:numStars="5" android:rating="0" android:stepSize="0.5" /> </LinearLayout>
上述代码使用了自定义的style
<style name="customer_rating_bar_style" prarent="android:Widget.RatingBar"> <item name="android:progressDrawable">@drawable/rating_bar_style</item> </style>
该style定义在res/values/styles.xml文件中,而使用的真正的RatingBar的样式定义在rating_bar_style.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/rating_back"> </item> <item android:id="@android:id/secondaryProgress" android:drawable="@drawable/rating_back"> </item> <item android:id="@android:id/progress" android:drawable="@drawable/rating_progress"> </item> </layer-list>
上述内容就是完整的自定义RatingBar样式的步骤。
2、与用户交互的activity——WidgetRatingBarActivity.java
package com.xy.zt.selfdefinewieget; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.widget.RatingBar; import android.widget.Toast; public class WidgetRatingBarActivity extends Activity implements RatingBar.OnRatingBarChangeListener { RatingBar mRatingBar; Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { int total = msg.arg2; int cur = msg.arg1; int num = mRatingBar.getNumStars(); float step = mRatingBar.getStepSize(); mRatingBar.setRating(num / step * cur / total); } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.widget_rating_bar_layout); init(); new RatingThead(mHandler).start(); } private void init() { mRatingBar = (RatingBar) findViewById(R.id.show_rating_bar); mRatingBar.setOnRatingBarChangeListener(this); } class RatingThead extends Thread { Handler mHandler; public RatingThead(Handler handler) { mHandler = handler; } public void run() { Message msg; try { for (int i = 1; i < 61; i++) { msg = mHandler.obtainMessage(); msg.arg1 = i; msg.arg2 = 60; msg.sendToTarget(); sleep(300); } } catch (InterruptedException e) { } } } public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) { Toast.makeText(this, "Rating changed rating=" + rating + " ; fromUser=" + fromUser, Toast.LENGTH_SHORT).show(); } }
代码中启动了一个线程每个300毫秒就更新一次rating,在for循环中我们看到消息发送了60次,但是Toast才显示了10次(numStars/stepSize),而且rating都是0.5(stepSize)的倍数。开始的时候是线程更新Rating所以fromUser为false。最后点击更新ratingfromUser变为true。
RatingBar控件就学到这里,下一个控件 SeekBar。