Làm cách nào để thay đổi màu sắc và kích thước của các ngôi sao?
Làm cách nào để thay đổi màu sắc và kích thước của các ngôi sao?
Câu trả lời:
Bước # 1: Tạo kiểu riêng của bạn, bằng cách sao chép một trong các kiểu hiện có (từ $ANDROID_HOME/platforms/$SDK/data/res/values/styles.xml
), đặt nó vào dự án của riêng bạn styles.xml
và tham chiếu nó khi bạn thêm tiện ích vào bố cục.
Bước # 2: Tạo LayerDrawable
tài nguyên XML của riêng bạn cho RatingBar
, chỉ vào hình ảnh phù hợp để sử dụng cho thanh. Các kiểu ban đầu sẽ chỉ cho bạn các tài nguyên hiện có mà bạn có thể so sánh với. Sau đó, điều chỉnh phong cách của bạn để sử dụng LayerDrawable
tài nguyên của riêng bạn , thay vì các tài nguyên tích hợp.
Có một chút phức tạp tại blog được đề cập, tôi đã sử dụng một cách tương tự nhưng đơn giản hơn. Bạn cần hình ảnh 3 sao (red_star_full.png, red_star_half.png và red_star_empty.png) và một xml, đó là tất cả.
Đặt 3 hình ảnh này ở độ phân giải / vẽ.
Đặt ở đó ratingbar_red.xml sau đây:
<?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/red_star_empty" />
<item android:id="@android:id/secondaryProgress" android:drawable="@drawable/red_star_half" />
<item android:id="@android:id/progress" android:drawable="@drawable/red_star_full" />
</layer-list>
và cuối cùng, cho biết định nghĩa thanh đánh giá của bạn để sử dụng điều này, tức là
<RatingBar android:progressDrawable="@drawable/ratingbar_red"/>
Đó là nó.
Hãy thử điều này, nếu bạn chỉ muốn thay đổi màu sắc:
RatingBar ratingBar = (RatingBar) findViewById(R.id.ratingBar);
LayerDrawable stars = (LayerDrawable) ratingBar.getProgressDrawable();
stars.getDrawable(2).setColorFilter(Color.YELLOW, PorterDuff.Mode.SRC_ATOP);
PorterDuff.Mode.SRC_ATOP
có nghĩa là gì hay làm gì?
Drawable stars = rb.getProgressDrawable(); stars.setTint( Color.YELLOW );
Cách dễ nhất có hiệu quả với tôi ... nếu bạn đang mở rộng Hoạt động AppCompat
Trong build.gradle của bạn thêm thư viện appcompat mới nhất.
dependencies {
compile 'com.android.support:appcompat-v7:X.X.X' // where X.X.X version
}
Làm cho hoạt động của bạn mở rộng android.support.v7.app.AppCompatActivity
public class MainActivity extends AppCompatActivity {
...
}
Khai báo kiểu tùy chỉnh trong tệp kiểu tệp của bạn.
<style name="RatingBar" parent="Theme.AppCompat">
<item name="colorControlNormal">@color/indigo</item>
<item name="colorControlActivated">@color/pink</item>
</style>
Áp dụng kiểu này cho RatingBar của bạn thông qua thuộc tính android: theme.
<RatingBar
android:theme="@style/RatingBar"
android:rating="3"
android:stepSize="0.5"
android:numStars="5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
style="?android:ratingBarStyleSmall"
cùng nhau.
<style name="RatingBarSmallTheme" parent="Theme.AppCompat"> <item name="colorControlNormal">@color/colorOrangeNormal</item> <item name="colorControlActivated">@color/colorOrangeActivated</item> <item name="ratingBarStyle">@style/Widget.AppCompat.RatingBar.Small</item> </style>
và xếp hạng của bạnBar android:theme="@style/RatingBarSmallTheme"
Cập nhật 2015
Bây giờ bạn có thể sử dụng DrawableCompat để tô màu tất cả các loại drawable. Ví dụ:
Drawable progress = ratingBar.getProgressDrawable();
DrawableCompat.setTint(progress, Color.WHITE);
Điều này tương thích ngược với API 4
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {}
vì nó hoạt động theo mặc định từ API 22.
Từ API 21 trở đi, thật dễ dàng để thay đổi màu sắc của các ngôi sao với ba dòng mã này:
android:progressTint="@android:color/holo_red_dark"
android:progressBackgroundTint="@android:color/holo_red_dark"
android:secondaryProgressTint="@android:color/holo_red_dark"
Làm như thế này, bạn sẽ thay đổi:
Nếu bạn muốn thay đổi màu sắc cho tất cả các ngôi sao, hãy sử dụng:
LayerDrawable stars = (LayerDrawable) ratingBar.getProgressDrawable();
stars.getDrawable(2).setColorFilter(getResources().getColor(R.color.starFullySelected), PorterDuff.Mode.SRC_ATOP);
stars.getDrawable(1).setColorFilter(getResources().getColor(R.color.starPartiallySelected), PorterDuff.Mode.SRC_ATOP);
stars.getDrawable(0).setColorFilter(getResources().getColor(R.color.starNotSelected), PorterDuff.Mode.SRC_ATOP);
Các giải pháp mà Alex và CommonsWares đã đăng là chính xác. Một điều mà Android không bao giờ nói về mặc dù là kích thước pixel phù hợp cho các mật độ khác nhau. Dưới đây là các kích thước cần thiết cho mỗi mật độ dựa trên ánh sáng quầng.
Ngôi sao nhỏ
mdpi: 16px
hdpi: 24px
xhdpi: 32px
xxhdpi: 48px
Sao trung bình
mdpi: 24px
hdpi: 36px
xhdpi: 48px
xxhdpi: 72px
Ngôi sao lớn
mdpi: 35px
hdpi: 52px
xhdpi: 69px
xxhdpi: 105px
Vì vậy, tôi đã vật lộn với vấn đề này trong hai giờ và tôi đã đưa ra một giải pháp hoạt động cho tất cả các phiên bản API, trong đó xếp hạng một nửa sao cũng được hiển thị.
private void setRatingStarColor(Drawable drawable, @ColorInt int color)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
DrawableCompat.setTint(drawable, color);
}
else
{
drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
}
}
Bạn gọi phương thức với thứ tự này của drawables:
LayerDrawable stars = (LayerDrawable) ratingBar.getProgressDrawable();
// Filled stars
setRatingStarColor(stars.getDrawable(2), ContextCompat.getColor(getContext(), R.color.foreground));
// Half filled stars
setRatingStarColor(stars.getDrawable(1), ContextCompat.getColor(getContext(), R.color.background));
// Empty stars
setRatingStarColor(stars.getDrawable(0), ContextCompat.getColor(getContext(), R.color.background));
LƯU Ý: Ngoài ra, bạn phải chỉ định các thuộc tính "max" và "numStars" trong XML, nếu không thì nửa sao không được hiển thị.
Mode.SRC_IN
hay Mode.MULTIPLY
?
Bây giờ bạn có thể sử dụng DrawableCompat từ AppCompat v22.1.0 trở đi để tự động điều chỉnh tất cả các loại hình vẽ, hữu ích khi bạn hỗ trợ nhiều chủ đề với một bộ có thể vẽ được. Ví dụ:
LayerDrawable layerDrawable = (LayerDrawable) ratingBar.getProgressDrawable();
DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable.getDrawable(0)), Color.RED); // Empty star
DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable.getDrawable(1)), Color.GREEN); // Partial star
DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable.getDrawable(2)), Color.BLUE); // Full star
Điều này tương thích ngược với API 4. Cũng xem bài đăng trên blog của Chris Banes trên Thư viện hỗ trợ v22.1.0
Đối với kích thước và hình dạng thực tế, bạn sẽ cần xác định kiểu dáng mới và các biểu đồ danh sách lớp cho kích thước phù hợp, như những người khác đã trả lời ở trên.
Sử dụng android:theme
thuộc tính:
kiểu tệp
<style name="Theme.Rating" parent="Theme.AppCompat.Light">
<item name="colorAccent">@color/rating</item>
</style>
layout.xml
<android.support.v7.widget.AppCompatRatingBar
android:theme="@style/Theme.Rating"
android:numStars="5"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Để thay đổi màu sắc, bạn chỉ cần đặt tham số android: ProgressTint
<RatingBar
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginTop="15dp"
android:numStars="5"
android:rating="1"
android:progressTint="@android:/color/black"
android:layout_gravity="center"
/>
Đối với kích thước tài sản phong cách.
Xây dựng câu trả lời @ lgvalle.
Cập nhật 2015
Bây giờ bạn có thể sử dụng DrawableCompat để tô màu tất cả các loại drawable. Ví dụ:
Tiến trình có thể rút ra = ratingBar.getProTHERDrawable (); DrawableCompat.setTint (tiến trình, Color.WHITE); Điều này tương thích ngược với API 4
LayerDrawable drawable = (LayerDrawable) getProgressDrawable();
Drawable progress = drawable.getDrawable(2);
DrawableCompat.setTint(progress, getResources().getColor(COLOR1));
progress = drawable.getDrawable(1);
DrawableCompat.setTintMode(progress, PorterDuff.Mode.DST_ATOP);
DrawableCompat.setTint(progress, getResources().getColor(COLOR1));
DrawableCompat.setTintMode(progress, PorterDuff.Mode.SRC_ATOP);
DrawableCompat.setTint(progress, getResources().getColor(COLOR2));
progress = drawable.getDrawable(0);
DrawableCompat.setTint(progress, getResources().getColor(COLOR2));
Điều này sẽ giữ cho các bước phân số màu sắc.
<!--For rating bar -->
<style name="RatingBarfeed" parent="Theme.AppCompat">
<item name="colorControlNormal">@color/colorPrimary</item>
<item name="colorControlActivated">@color/colorPrimary</item>
</style>
sử dụng màu của riêng bạn
Không thêm phong cách mới, bạn có thể sử dụng màu sắc trong RatingBar
<RatingBar
android:id="@+id/ratingBar"
style="@android:style/Widget.Holo.RatingBar.Small"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numStars="5"
android:rating="4.5"
android:stepSize="0.5"
android:progressTint="@color/colorPrimary"/>
Sau một số nghiên cứu, tôi đã đưa ra phương pháp này để thiết lập tông màu nền, khoảng cách màu (ví dụ: nửa sao) và màu sắc sao.
LayerDrawable layers = (LayerDrawable) ratingBar.getProgressDrawable();
DrawableCompat.setTint(layers.getDrawable(0), 0x33000000); // The background tint
DrawableCompat.setTint(layers.getDrawable(1), 0x00000000); // The gap tint (Transparent in this case so the gap doesnt seem darker than the background)
DrawableCompat.setTint(layers.getDrawable(2), 0xffFED80A); // The star tint
Giải pháp đơn giản, sử dụng AppCompatRatingBar và phương thức setProTHERTintList của nó để đạt được điều này, xem câu trả lời này để tham khảo.
Tôi giải quyết vấn đề này như sau:
LayerDrawable layerDrawable = (LayerDrawable) ratingBar.getProgressDrawable();
DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable.getDrawable(0)),
Color.WHITE); // Empty star
DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable.getDrawable(1)),
Color.YELLOW); // Partial star
DrawableCompat.setTint(DrawableCompat.wrap(layerDrawable.getDrawable(2)),
Color.YELLOW);
Tôi tìm thấy một giải pháp đơn giản để thay đổi màu sắc của ngôi sao theo chủ đề của bạn.
Xem trang này: http://android-holo-colors.com/
Chọn màu chủ đề của bạn và tạo hình ảnh ngôi sao của bạn.
Sử dụng các câu trả lời ở trên, tôi đã tạo ra một phương thức tĩnh nhanh có thể dễ dàng sử dụng lại. Nó chỉ nhằm mục đích pha màu tiến độ cho các ngôi sao được kích hoạt. Những ngôi sao không được kích hoạt vẫn có màu xám.
public static RatingBar tintRatingBar (RatingBar ratingBar, int progressColor)if (ratingBar.getProgressDrawable() instanceof LayerDrawable) {
LayerDrawable progressDrawable = (LayerDrawable) ratingBar.getProgressDrawable();
Drawable drawable = progressDrawable.getDrawable(2);
Drawable compat = DrawableCompat.wrap(drawable);
DrawableCompat.setTint(compat, progressColor);
Drawable[] drawables = new Drawable[3];
drawables[2] = compat;
drawables[0] = progressDrawable.getDrawable(0);
drawables[1] = progressDrawable.getDrawable(1);
LayerDrawable layerDrawable = new LayerDrawable(drawables);
ratingBar.setProgressDrawable(layerDrawable);
return ratingBar;
}
else {
Drawable progressDrawable = ratingBar.getProgressDrawable();
Drawable compat = DrawableCompat.wrap(progressDrawable);
DrawableCompat.setTint(compat, progressColor);
ratingBar.setProgressDrawable(compat);
return ratingBar;
}
}
Chỉ cần vượt qua thanh đánh giá của bạn và sử dụng màu getResources().getColor(R.color.my_rating_color)
Như bạn có thể thấy, tôi sử dụng DrawableCompat để nó tương thích ngược.
EDIT: Phương pháp này không hoạt động trên API21 (xem tại sao). Bạn kết thúc với một NullPulumException khi gọi setProTHERBar. Tôi đã kết thúc việc vô hiệu hóa toàn bộ phương thức trên API> = 21.
Đối với API> = 21, tôi sử dụng giải pháp SupperPuccio.
Thanh đánh giá được sử dụng tự động trong thời gian chạy để thay đổi màu sắc trên ngôi sao cảm ứng.
Đầu tiên thêm kiểu trong tệp ứng dụng \ src \ main \ res \ value \ Styles.xml:
<style name="RatingBar" parent="Theme.AppCompat">
<item name="colorControlNormal">@android:color/darker_gray</item>
<item name="colorControlActivated">@color/com_facebook_blue</item>
</style>
Sau đó, thanh đánh giá của bạn thêm chủ đề như thế này:
<RatingBar
android:id="@+id/rating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numStars="5"
android:stepSize="1"
android:theme="@style/RatingBar"/>
1) khai báo xml này
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:layout_marginBottom="20dp"
android:background="#323232"
android:gravity="center_horizontal">
<com.example.android.custom_ratingbar.CustomRatingBar
android:id="@+id/coloredRatingBar5"
style="@style/coloredRatingBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="match_parent"
/>
</LinearLayout>
2) trong style.xml
<style name="coloredRatingBarStyleSmall">
<item name="indicator">false</item>
<item name="type">small</item>
</style>
3)
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class CustomRatingBar extends View{
private static final String TAG="ColoredRatingBar";
private static final int NORMAL = 0;
private static final int SMALL = 1;
Bitmap[] drawables;
Bitmap progressBackground;
Context mContext;
private int mNumStars =9;
private float mRating =0;
private boolean mIndicator;
private float slidePosition;
private int mType;
/**
* A callback that notifies clients when the rating has been changed. This
* includes changes that were initiated by the user through a touch gesture
* or arrow key/trackball as well as changes that were initiated
* programmatically.
*/
public interface OnRatingBarChangeListener {
/**
* Notification that the rating has changed. Clients can use the
* fromUser parameter to distinguish user-initiated changes from those
* that occurred programmatically. This will not be called continuously
* while the user is dragging, only when the user finalizes a rating by
* lifting the touch.
*
* @param ratingBar The RatingBar whose rating has changed.
* @param rating The current rating. This will be in the range
* 0..numStars.
* @param fromUser True if the rating change was initiated by a user's
* touch gesture or arrow key/horizontal trackbell movement.
*/
void onRatingChanged(CustomRatingBar ratingBar, float rating, boolean fromUser);
}
private OnRatingBarChangeListener mOnRatingBarChangeListener;
public CustomRatingBar(Context context) {
this(context, null);
}
public CustomRatingBar(Context context, AttributeSet attrs) {
this(context, attrs,0);//R.attr.coloredRatingBarStyle
}
public CustomRatingBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomRatingBar,defStyle, 0);
final boolean indicator = a.getBoolean(R.styleable.CustomRatingBar_indicator, false);
final float rating = a.getFloat(R.styleable.CustomRatingBar_setrating, -1);
final int type = a.getInt(R.styleable.CustomRatingBar_type, 0);
a.recycle();
setIndicator(indicator);
setRating(rating);
setType(type);
init(context);
}
public int getType() {
return mType;
}
public void setType(int type) {
this.mType = type;
}
private void init(Context context) {
mContext = context;
Resources res = getResources();
if(mType==SMALL){
drawables = new Bitmap[]{BitmapFactory.decodeResource(res, R.drawable.rating_inactive),BitmapFactory.decodeResource(res, R.drawable.rating_active)};
progressBackground = BitmapFactory.decodeResource(res, R.drawable.rating_inactive);
}else{
drawables = new Bitmap[]{BitmapFactory.decodeResource(res, R.drawable.rating_inactive),BitmapFactory.decodeResource(res, R.drawable.rating_active)};
progressBackground = BitmapFactory.decodeResource(res, R.drawable.rating_inactive);
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//draw empty stars bg
for(int i=0;i< mNumStars;i++){
drawStar(canvas,i);
}
}
private void drawStar(Canvas canvas, int position) {
float fraction = mRating -(position);
Bitmap ratedStar1 = getRatedStar();
Paint paint=getPaint(position);
int division=getSize();
Bitmap ratedStar=null;
Bitmap emptyStar=null;
if(!isInEditMode()){
ratedStar=Bitmap.createScaledBitmap(ratedStar1, division, division, false);
emptyStar=Bitmap.createScaledBitmap(progressBackground, division, division, false);
}
if((position)< mRating){
if(!isInEditMode()){
canvas.drawBitmap(ratedStar,(position* division),0,paint);
}
} else{
if(!isInEditMode()){
canvas.drawBitmap(emptyStar,(position*division),0,null);
}
}
}
private int getSize(){
return (getWidth()/mNumStars);
}
private Bitmap getRatedStar() {
if(mRating==0){
return drawables[0];
}
else{
return drawables[1];
}
}
private Paint getPaint(int position){
int value=(255*(position+1))/mNumStars;
String hexString=Integer.toHexString(value).equals("0")?"00":Integer.toHexString(value);
String hexvalue="#"+hexString+"000000";//FEE98E
//Log.e("TAG", position+"/"+value+"/"+hexvalue);
Paint paint=new Paint();
paint.setColor(Color.parseColor(hexvalue));
return paint;
}
public int getNumStars() {
return mNumStars;
}
public void setNumStars(int numStars) {
this.mNumStars = numStars;
}
public float getRating() {
return mRating;
}
public void setRating(float rating) {
setRating(rating,false);
}
void setRating(float rating,boolean fromUser) {
if(rating>mNumStars){
this.mRating = mNumStars;
}
this.mRating = rating;
invalidate();
dispatchRatingChange(fromUser);
}
public boolean isIndicator() {
return mIndicator;
}
public void setIndicator(boolean indicator) {
this.mIndicator = indicator;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (progressBackground != null) {
final int width = progressBackground.getWidth() * mNumStars;
final int height = progressBackground.getHeight();
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
Bitmap emptyStar=Bitmap.createScaledBitmap(progressBackground, widthSize/mNumStars, widthSize/mNumStars, false);
int heightSize = emptyStar.getHeight();
setMeasuredDimension(resolveSizeAndState(widthSize, widthMeasureSpec, 0),
resolveSizeAndState(heightSize, heightMeasureSpec, 0));
}
else{
int desiredWidth = 100;
int desiredHeight = 50;
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height;
//Measure Width
if (widthMode == MeasureSpec.EXACTLY) {
//Must be this size
width = widthSize;
} else if (widthMode == MeasureSpec.AT_MOST) {
//Can't be bigger than...
width = Math.min(desiredWidth, widthSize);
} else {
//Be whatever you want
width = desiredWidth;
}
//Measure Height
if (heightMode == MeasureSpec.EXACTLY) {
//Must be this size
height = heightSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
//Can't be bigger than...
height = Math.min(desiredHeight, heightSize);
} else {
//Be whatever you want
height = desiredHeight;
}
//MUST CALL THIS
setMeasuredDimension(resolveSizeAndState(width, widthMeasureSpec, 0),resolveSizeAndState(height, heightMeasureSpec, 0));
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if(mIndicator){
return false;
}
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
slidePosition = getRelativePosition(event.getX());
int newRating = (int)(slidePosition>0?slidePosition+1:0) ;
if(newRating>mNumStars){
newRating=mNumStars;
}
// Log.e("TAG", ""+newRating);
if (newRating != mRating) {
setRating(newRating,true);
}
break;
case MotionEvent.ACTION_CANCEL:
break;
default:
break;
}
return true;
}
private float getRelativePosition(float x) {
Bitmap emptyStar=Bitmap.createScaledBitmap(progressBackground, getWidth()/mNumStars, getWidth()/mNumStars, false);
int widthSize = emptyStar.getWidth();
// Log.e("TAG", widthSize+"/"+x);
float position = x / widthSize;
position = Math.max(position, 0);
return Math.min(position, mNumStars);
}
/**
* Sets the listener to be called when the rating changes.
*
* @param listener The listener.
*/
public void setOnRatingBarChangeListener(OnRatingBarChangeListener listener) {
mOnRatingBarChangeListener = listener;
}
/**
* @return The listener (may be null) that is listening for rating change
* events.
*/
public OnRatingBarChangeListener getOnRatingBarChangeListener() {
return mOnRatingBarChangeListener;
}
void dispatchRatingChange(boolean fromUser) {
if (mOnRatingBarChangeListener != null) {
mOnRatingBarChangeListener.onRatingChanged(this, getRating(),
fromUser);
}
}
}
5) then in calling activity---
CustomRatingBar coloredRatingBar5=(CustomRatingBar)findViewById(R.id.coloredRatingBar5);
coloredRatingBar5.setOnRatingBarChangeListener(new OnRatingBarChangeListener() {
@Override
public void onRatingChanged(CustomRatingBar ratingBar, float rating,boolean fromUser) {
// TODO Auto-generated method stub
Log.e("RATING", ""+rating);
}
});
6) xếp hạng hoạt động --- chụp bất kỳ hình ảnh nào có màu tối vì nó sẽ được sử dụng làm độ trong suốt của màu cho các xếp hạng khác nhau
rating_inactive - lấy bất kỳ hình ảnh nào có cùng kích thước của hình ảnh trên với nền sáng..tôi sẽ được sử dụng khi không có xếp hạng nào được chọn
Một cách rất dễ dàng để thay đổi màu đường viền của các ngôi sao là sử dụng tham số xml:
android:progressBackgroundTint=""
trong khung nhìn ratingBar. Giá trị phải là mã thập lục phân cho một màu.
Tôi đã tìm kiếm một phương pháp đáng tin cậy để thực hiện điều này hoàn toàn theo API 9. Giải pháp "truyền tới LayerDrawble" có vẻ như là một giải pháp rủi ro đối với tôi và khi tôi thử nghiệm nó trên điện thoại Android vào ngày 2.3, nó đã thực hiện thành công nhưng cuộc gọi tới DrawableCompat.setTint (...) không có tác dụng.
Nhu cầu tải tài sản có thể rút ra dường như cũng không phải là một giải pháp tốt cho tôi.
Tôi quyết định mã hóa giải pháp của riêng mình, đó là một lớp mở rộng AppCompatRatingBar, sử dụng một Drawable tùy chỉnh để chăm sóc việc vẽ các ngôi sao theo lập trình. Nó hoạt động hoàn hảo cho nhu cầu của tôi, tôi sẽ đăng nó trong trường hợp nó giúp được bất cứ ai:
https://gist.github.com/androidseb/2b8044c90a07c7a52b4bbff3453c8460
Liên kết dễ dàng hơn vì bạn có thể lấy tệp đầy đủ trực tiếp, nhưng đây là mã đầy đủ chỉ trong trường hợp:
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.AppCompatRatingBar;
import android.util.AttributeSet;
/**
* @author androidseb
* <p/>
* Extends AppCompatRatingBar with the ability to tint the drawn stars when selected, pressed and un-selected.
* Limitation: Only draws full stars.
*/
public class TintableRatingBar extends AppCompatRatingBar {
private TintableRatingBarProgressDrawable progressDrawable;
public TintableRatingBar(final Context context) {
super(context);
init();
}
public TintableRatingBar(final Context context, final AttributeSet attrs) {
super(context, attrs);
init();
}
public TintableRatingBar(final Context context, final AttributeSet attrs, final int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
progressDrawable = new TintableRatingBarProgressDrawable();
setProgressDrawable(progressDrawable);
}
public void setCustomTintColors(final int _uncheckedColor, final int _pressedColor, final int _checkedColor) {
progressDrawable.setRatingMaxLevelValue(getMax() * 1000);
progressDrawable.setUnCheckedColor(_uncheckedColor);
progressDrawable.setPressedColor(_pressedColor);
progressDrawable.setCheckedColor(_checkedColor);
invalidate();
}
public class TintableRatingBarProgressDrawable extends Drawable {
private static final int STAR_COUNT = 5;
private static final int STAR_BRANCHES_COUNT = 5;
/** Sets the max level value: if the level is at the max, then all stars are selected. */
private int ratingMaxLevelValue = 10000;
/** Color to be painted for unselected stars */
private int uncheckedColor = Color.GRAY;
/** Color to be painted for unselected stars when the ratingbar is pressed */
private int pressedColor = Color.CYAN;
/** Color to be painted for selected stars */
private int checkedColor = Color.BLUE;
@Override
public void setAlpha(final int _i) {
}
@Override
public void setColorFilter(final ColorFilter _colorFilter) {
}
@Override
public boolean isStateful() {
return true;
}
@Override
public boolean setState(final int[] stateSet) {
final boolean res = super.setState(stateSet);
invalidateSelf();
return res;
}
@Override
public int getOpacity() {
return 255;
}
public void setRatingMaxLevelValue(final int _ratingMaxLevelValue) {
ratingMaxLevelValue = _ratingMaxLevelValue;
}
public void setUnCheckedColor(final int _uncheckedColor) {
uncheckedColor = _uncheckedColor;
}
public void setPressedColor(final int _pressedColor) {
pressedColor = _pressedColor;
}
public void setCheckedColor(final int _checkedColor) {
checkedColor = _checkedColor;
}
@Override
public void draw(final Canvas _canvas) {
boolean pressed = false;
for (int i : getState()) {
if (i == android.R.attr.state_pressed) {
pressed = true;
}
}
final int level = (int) Math.ceil(getLevel() / (double) ratingMaxLevelValue * STAR_COUNT);
final int starRadius = Math.min(getBounds().bottom / 2, getBounds().right / STAR_COUNT / 2);
for (int i = 0; i < STAR_COUNT; i++) {
final int usedColor;
if (level >= i + 1) {
usedColor = checkedColor;
} else if (pressed) {
usedColor = pressedColor;
} else {
usedColor = uncheckedColor;
}
drawStar(_canvas, usedColor, (i * 2 + 1) * starRadius, getBounds().bottom / 2, starRadius,
STAR_BRANCHES_COUNT);
}
}
private void drawStar(final Canvas _canvas, final int _color, final float _centerX, final float _centerY,
final float _radius, final int _branchesCount) {
final double rotationAngle = Math.PI * 2 / _branchesCount;
final double rotationAngleComplement = Math.PI / 2 - rotationAngle;
//Calculating how much space is left between the bottom of the star and the bottom of the circle
//In order to be able to center the star visually relatively to the square when drawn
final float bottomOffset = (float) (_radius - _radius * Math.sin(rotationAngle / 2) / Math.tan(
rotationAngle / 2));
final float actualCenterY = _centerY + (bottomOffset / 2);
final Paint paint = new Paint();
paint.setColor(_color);
paint.setStyle(Style.FILL);
final Path path = new Path();
final float relativeY = (float) (_radius - _radius * (1 - Math.sin(rotationAngleComplement)));
final float relativeX = (float) (Math.tan(rotationAngle / 2) * relativeY);
final PointF a = new PointF(-relativeX, -relativeY);
final PointF b = new PointF(0, -_radius);
final PointF c = new PointF(relativeX, -relativeY);
path.moveTo(_centerX + a.x, actualCenterY + a.y);
_canvas.save();
for (int i = 0; i < _branchesCount; i++) {
path.lineTo(_centerX + b.x, actualCenterY + b.y);
path.lineTo(_centerX + c.x, actualCenterY + c.y);
rotationToCenter(b, rotationAngle);
rotationToCenter(c, rotationAngle);
}
_canvas.drawPath(path, paint);
_canvas.restore();
}
private void rotationToCenter(final PointF _point, final double _angleRadian) {
final float x = (float) (_point.x * Math.cos(_angleRadian) - _point.y * Math.sin(_angleRadian));
final float y = (float) (_point.x * Math.sin(_angleRadian) + _point.y * Math.cos(_angleRadian));
_point.x = x;
_point.y = y;
}
}
}
Một câu trả lời hơi muộn nhưng tôi hy vọng nó sẽ giúp một số người.
<RatingBar
android:id="@+id/rating"
style="@style/Base.Widget.AppCompat.RatingBar.Small"
android:theme="@style/WhiteRatingStar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/profil_name"
android:layout_centerHorizontal="true"
android:layout_marginLeft="@dimen/dimen_4"
android:rating="3" />
Và đây là những gì WhiteRatingStar trông giống như
<style name="WhiteRatingStar" parent="Base.Widget.AppCompat.RatingBar.Small">
<item name="colorAccent">@android:color/white</item>
</style>
Với điều này, các ngôi sao sẽ được tô màu trắng chẳng hạn.
Sử dụng liên kết này
Android RatingBar thay đổi màu sao
đặt kiểu của bạn bên trong giá trị / kiểu (v-21);
Như câu trả lời trước ngụ ý, không dễ để thay đổi màu của thanh đánh giá. Các ngôi sao không được vẽ theo chương trình, chúng là những hình ảnh có kích thước cố định và độ dốc màu cụ thể. Để thay đổi màu sắc, bạn phải tạo các hình ảnh ngôi sao của riêng mình bằng các màu khác nhau, sau đó tiến hành tạo tài nguyên XML có thể vẽ của riêng bạn và chuyển nó đến lớp xếp hạng bằng cách sử dụng setProTHERDrawable (Drawable d) hoặc thuộc tính XML android: ProgressDrawable.