Android RatingBar更改星星颜色
如何更改星星的颜色和大小?步骤1:通过克隆一个现有样式(从Android RatingBar更改星星颜色,android,rating,Android,Rating,如何更改星星的颜色和大小?步骤1:通过克隆一个现有样式(从$ANDROID\u HOME/platforms/$SDK/data/res/values/styles.xml),将其放在您自己项目的styles.xml中,并在将小部件添加到布局时引用它,创建您自己的样式 步骤2:为分级栏创建自己的LayerDrawableXML资源,指向要用于分级栏的适当图像。原始样式将指向可以比较的现有资源。然后,调整您的样式以使用您自己的图层可绘制资源,而不是内置资源。正如前面的答案所暗示的,更改分级栏的颜色
$ANDROID\u HOME/platforms/$SDK/data/res/values/styles.xml
),将其放在您自己项目的styles.xml
中,并在将小部件添加到布局时引用它,创建您自己的样式
步骤2:为
分级栏
创建自己的LayerDrawable
XML资源,指向要用于分级栏的适当图像。原始样式将指向可以比较的现有资源。然后,调整您的样式以使用您自己的图层可绘制资源,而不是内置资源。正如前面的答案所暗示的,更改分级栏的颜色并不容易。星星不是以编程方式绘制的,它们是具有固定大小和特定颜色渐变的图像。要更改颜色,您必须使用不同的颜色创建自己的星形图像,然后继续创建自己的可绘制XML资源,并使用setProgressDrawable(drawable d)或XML属性android:progressDrawable将其传递给ratingsBar类。在上述博客中有点复杂,我使用了类似但更简单的方法。
您确实需要3个星形图像(red_star_full.png、red_star_half.png和red_star_empty.png)和一个xml,仅此而已
将这3幅图像设置为res/drawable
将以下ratingbar_red.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/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>
最后,告诉你的评级条定义使用这个,即
<RatingBar android:progressDrawable="@drawable/ratingbar_red"/>
就是这样。Alex和Commonware发布的解决方案是正确的。不过,安卓从未提及的一件事是不同密度的像素大小是否合适。以下是基于光晕光的每个密度所需的尺寸
小星星
mdpi: 16px
hdpi: 24px
xhdpi: 32px
xxhdpi: 48px
mdpi: 24px
hdpi: 36px
xhdpi: 48px
xxhdpi: 72px
mdpi: 35px
hdpi: 52px
xhdpi: 69px
xxhdpi: 105px
中星级
mdpi: 16px
hdpi: 24px
xhdpi: 32px
xxhdpi: 48px
mdpi: 24px
hdpi: 36px
xhdpi: 48px
xxhdpi: 72px
mdpi: 35px
hdpi: 52px
xhdpi: 69px
xxhdpi: 105px
大星星
mdpi: 16px
hdpi: 24px
xhdpi: 32px
xxhdpi: 48px
mdpi: 24px
hdpi: 36px
xhdpi: 48px
xxhdpi: 72px
mdpi: 35px
hdpi: 52px
xhdpi: 69px
xxhdpi: 105px
如果您只想更改颜色,请尝试以下操作:
RatingBar ratingBar = (RatingBar) findViewById(R.id.ratingBar);
LayerDrawable stars = (LayerDrawable) ratingBar.getProgressDrawable();
stars.getDrawable(2).setColorFilter(Color.YELLOW, PorterDuff.Mode.SRC_ATOP);
如果要更改所有星星的颜色,请说明我的用法:
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);
2015年更新
现在,您可以使用着色所有类型的绘图。例如:
Drawable progress = ratingBar.getProgressDrawable();
DrawableCompat.setTint(progress, Color.WHITE);
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
这是向后兼容到API 4的,现在您可以从AppCompat v22.1.0开始使用它动态着色所有类型的可绘制内容,当您使用一组可绘制内容支持多个主题时非常有用。例如:
Drawable progress = ratingBar.getProgressDrawable();
DrawableCompat.setTint(progress, Color.WHITE);
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
这是向后兼容到API 4。另请参见Chris Banes在
对于实际的大小和形状,您需要定义一个新的样式和图层列表,以获得合适的大小,其他人已经在上面给出了回答。1)声明此xml
<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) in style.xml
<style name="coloredRatingBarStyleSmall">
<item name="indicator">false</item>
<item name="type">small</item>
</style>
假的
小的
(三)
导入android.content.Context;
导入android.content.res.Resources;
导入android.content.res.TypedArray;
导入android.graphics.Bitmap;
导入android.graphics.BitmapFactory;
导入android.graphics.Canvas;
导入android.graphics.Color;
导入android.graphics.Paint;
导入android.util.AttributeSet;
导入android.view.MotionEvent;
导入android.view.view;
公共类CustomRatingBar扩展视图{
私有静态最终字符串TAG=“ColoredRatingBar”;
专用静态最终int-NORMAL=0;
私有静态final int SMALL=1;
位图[]可绘制;
位图背景;
语境;
私有int mNumStars=9;
私有浮点数=0;
专用布尔值指示器;
私人浮动席位;
私有int-mType;
/**
*当评级更改时通知客户端的回调
*包括用户通过触摸手势发起的更改
*或箭头键/轨迹球以及启动的更改
*以编程方式。
*/
公共接口OnRatingBarChangeListener{
/**
*通知分级已更改。客户端可以使用
*fromUser参数以区分用户发起的更改和
*以编程方式发生的。将不会连续调用
*当用户拖动时,仅当用户通过
*解除接触。
*
*@param ratingBar评级已更改的评级栏。
*@param rating当前额定值。这将在范围内
*0..numStars。
*@param fromUser True,如果评级更改是由用户的
*触摸手势或箭头键/水平履带铃移动。
*/
void onRatingChanged(自定义栏ratingBar、浮动评级、布尔值fromUser);
}
专用OnRatingBarChangeListener mOnRatingBarChangeListener;
公共自定义栏(上下文){
这个(上下文,空);
}
公共自定义栏(上下文、属性集属性){
this(context,attrs,0);//R.attr.coloredRatingBarStyle
}
公共自定义栏(上下文、属性集属性、int-defStyle){
超级(上下文、属性、定义样式);
TypedArray a=上下文。获取样式属性(attrs,R.styleable.CustomRatingBar,defStyle,0);
最终布尔指示符=a.getBoolean(R.styleable.CustomRatingBar_指示符,false);
最终浮动评级=a.getFloat(R.styleable.CustomRatingBar_setrating,-1);
final int type=a.getInt(R.styleable.CustomRatingBar_type,0);
a、 回收();
设置指示器(指示器);
设定额定值(额定值);
setType(类型);
init(上下文);
}
公共int getType(){
返回mType;
}
公共void集合类型(int类型){
this.mType=type;
}
私有void init(上下文){
mContext=上下文;
Resources res=getResources();
如果(mType==小){
drawables=新位图[]{BitmapFactory.decodeResource(res,R.drawable.rating_inactive),BitmapFactory.decodeResource(res,R.drawable.rating_active)}
<style name="Theme.Rating" parent="Theme.AppCompat.Light">
<item name="colorAccent">@color/rating</item>
</style>
<android.support.v7.widget.AppCompatRatingBar
android:theme="@style/Theme.Rating"
android:numStars="5"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
dependencies {
compile 'com.android.support:appcompat-v7:X.X.X' // where X.X.X version
}
public class MainActivity extends AppCompatActivity {
...
}
<style name="RatingBar" parent="Theme.AppCompat">
<item name="colorControlNormal">@color/indigo</item>
<item name="colorControlActivated">@color/pink</item>
</style>
<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"/>
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);
}
}
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));
RatingBar mRating=(RatingBar)findViewById(R.id.rating);
LayerDrawable layerDrawable=(LayerDrawable)mRating.getProgressDrawable();
layerDrawable.getDrawable(2).setColorFilter(Color.parseColor
("#32CD32"), PorterDuff.Mode.SRC_ATOP);
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;
}
}
}
<!--For rating bar -->
<style name="RatingBarfeed" parent="Theme.AppCompat">
<item name="colorControlNormal">@color/colorPrimary</item>
<item name="colorControlActivated">@color/colorPrimary</item>
</style>
<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"/>
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
<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" />
<style name="WhiteRatingStar" parent="Base.Widget.AppCompat.RatingBar.Small">
<item name="colorAccent">@android:color/white</item>
</style>
<style name="RatingBar" parent="Theme.AppCompat">
<item name="colorControlNormal">@android:color/darker_gray</item>
<item name="colorControlActivated">@color/com_facebook_blue</item>
</style>
<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"/>
android:progressTint="@color/color"