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。