DtRatingBar

一个使用在android上的RatingBar。GitHub地址:DtRatingBar

使用依赖:

implementation 'com.yetland.dtratingbar:dtratingbar:1.0.1'

功能

图片自定义

大小自定义

数量自定义

可以打开或关闭半星

支持横向和纵向的滑动评分

效果图

demo.gif

主要参数

rating_sum 总数

rating_check 得分数

rating_width RatingView的宽度

rating_height RatingView的高度

rating_padding_left RatingView的paddingLeft

rating_padding_right RatingView的paddingRight

rating_padding_top RatingView的paddingTop

rating_padding_bottom RatingView的paddingBottom

rating_star_img 全星的图片

rating_half_star_img 半星的图片

rating_un_star_img 没星的图片

rating_support_half 是否支持半星

使用方法

通过xml形式配置

android:id="@+id/rating_bar_1"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

app:rating_check="3.5"

app:rating_half_star_img="@drawable/ic_half_star"

app:rating_height="20"

app:rating_padding_bottom="2"

app:rating_padding_left="2"

app:rating_padding_right="2"

app:rating_padding_top="2"

app:rating_star_img="@drawable/ic_star"

app:rating_support_half="false"

app:rating_un_star_img="@drawable/ic_un_star"

app:rating_width="20" />

通过builder的形式配置

RatingView.Builder builder = new RatingView.Builder()

.context(this)

.width(30)

.height(30)

.paddingLeft(2)

.paddingRight(2)

.paddingBottom(2)

.paddingTop(2)

.star(R.mipmap.ic_star2)

.unStar(R.mipmap.ic_un_star2)

.halfStar(R.mipmap.ic_half_star2);

或者

RatingView.Builder builder = RatingView.with()

.context(this)

.width(30)

.height(30)

.paddingLeft(2)

.paddingRight(2)

.paddingBottom(2)

.paddingTop(2)

.star(R.mipmap.ic_star2)

.unStar(R.mipmap.ic_un_star2)

.halfStar(R.mipmap.ic_half_star2);

实现原理

通过自定义view的形式,将每颗星星(RatingView)通过addView的形式,添加到DtRatingView中。其实我们所有的属性都是基于RatingView,而不是DtRatingView,因为DtRatingView只是一个呈现,而RatingView才是本体。对于参数的设置,通过Builder的形式去设置,而这个Builder也是属于RatingView的。

DtRatingView

构造方法中主要实现了参数的初始化。

public DtRatingBar(Context context, AttributeSet attrs) {

super(context, attrs);

mContext = context;

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.DtRatingBar);

mRating = typedArray.getFloat(R.styleable.DtRatingBar_rating_check, 0f);

mStars = typedArray.getInt(R.styleable.DtRatingBar_rating_sum, 5);

mSupportHalf = typedArray.getBoolean(R.styleable.DtRatingBar_rating_support_half, true);

mRating = getRatingValue(mRating);

int childViewWidth = typedArray.getInt(R.styleable.DtRatingBar_rating_width, 12);

int childViewHeight = typedArray.getInt(R.styleable.DtRatingBar_rating_height, 12);

int childViewPaddingLeft = typedArray.getInt(R.styleable.DtRatingBar_rating_padding_left, 2);

int childViewPaddingRight = typedArray.getInt(R.styleable.DtRatingBar_rating_padding_right, 2);

int childViewPaddingTop = typedArray.getInt(R.styleable.DtRatingBar_rating_padding_top, 0);

int childViewPaddingBottom = typedArray.getInt(R.styleable.DtRatingBar_rating_padding_bottom, 0);

int childViewStarImg = typedArray.getResourceId(R.styleable.DtRatingBar_rating_star_img, R.drawable.ic_star);

int childViewHalfStarImg = typedArray.getResourceId(R.styleable.DtRatingBar_rating_half_star_img, R.drawable.ic_half_star);

int childViewUnStarImg = typedArray.getResourceId(R.styleable.DtRatingBar_rating_un_star_img, R.drawable.ic_un_star);

mBuilder = new RatingView.Builder()

.context(mContext)

.width(childViewWidth)

.height(childViewHeight)

.paddingLeft(childViewPaddingLeft)

.paddingRight(childViewPaddingRight)

.paddingBottom(childViewPaddingBottom)

.paddingTop(childViewPaddingTop)

.star(childViewStarImg)

.halfStar(childViewHalfStarImg)

.unStar(childViewUnStarImg);

typedArray.recycle();

setEnabled(false);// 默认不让滑动

initView();

}

实现一个评分改变的回调接口

public interface OnRatingChangeListener {

/**

* on rating change

*

* @param rating rating

* @param stars stars sum

*/

void onChange(float rating, int stars);

}

对触摸事件的处理,复写onTouchEvent方法

@Override

public boolean onTouchEvent(MotionEvent event) {

if (isEnabled()) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

performClick();

break;

case MotionEvent.ACTION_UP:

case MotionEvent.ACTION_CANCEL:

break;

default:

break;

}

// 布局方向的判断,如果是水平方向的,判断x

if (getOrientation() == LinearLayout.HORIZONTAL) {

int width = getWidth();

float x = event.getX();

// 对x的大小限制,最大为view的宽度,最小为0

x = x > width ? width : x;

x = x < 0 ? 0 : x;

mRating = x / mChildWidth;

} else {

// 垂直方向,判断y

int height = getHeight();

float y = event.getY();

y = y > height ? height : y;

y = y < 0 ? 0 : y;

mRating = y / mChildHeight;

}

// 得分的转换,因为我们只需要两位数的精确度,而且需要判断是否支持半星

mRating = getRatingValue(mRating);

if (mOnRatingChangeListener != null) {

mOnRatingChangeListener.onChange(mRating, mStars);

}

updateView();

return true;

} else {

return false;

}

}

对评分精度的转换

private float getRatingValue(float rating) {

// half

int half = RATE / 2;

rating = rating * RATE;

int xx = (int) (rating % RATE);

int yy = (int) (rating / RATE);

if (xx > 0) {

if (mSupportHalf) {

// support half

if (xx <= half) {

// <= half , plus 0.5

rating = (float) (yy + 0.5);

} else {

// > half , plus 1

rating = yy + 1;

}

} else {

// if not support half ,plus 1

rating = yy + 1;

}

} else {

rating = yy;

}

return rating;

}

RatingView

这里我们所设置的大小,包括宽高和padding,都是像素px,而不是dp。因为我们得到的设计稿一般标注都为px。这里的转换,我们需要转两次而不是一次。因为第一次是px转dp,这应该是设计稿对应的dp值,第二次是转换,从dp转px才是我们需要的px值。

状态

一共分成了三种状态:

private static final int STATE_UN_STAR = 0;// 没星

private static final int STATE_HALF_STAR = 1;// 半星

private static final int STATE_STAR = 2;// 一星

获得状态

/**

* @param position position

* @param rating rating

* @return status

* {@link #STATE_STAR,#STATE_HALF_STAR,#STATE_UN_STAR}

*/

private int getState(int position, float rating) {

position++;

float dis = rating - position;

if (dis >= 0) {

return STATE_STAR;

} else {

if (dis >= -0.5) {

return STATE_HALF_STAR;

} else {

return STATE_UN_STAR;

}

}

}

根据状态,获取对应的图片

/**

* get status

*

* @param position position

* @param rating rating

* @return image id

*/

private int getImageRes(int position, float rating) {

int id = R.drawable.ic_un_star;

switch (getState(position, rating)) {

case STATE_UN_STAR:

id = getUnStarImageId();

break;

case STATE_HALF_STAR:

id = getHalfStarImageId();

break;

case STATE_STAR:

id = getStarImageId();

break;

default:

break;

}

return id;

}

FINAL

至此大概的流程就写完了整个DtRatingView的过程。其实并不复杂,只是在写的过程中,可以学习到很多东西。毕竟自己动手后得到了一些成果。

android字体ratingbar,Android 自定义View之自定义评分选择器RatingBar相关推荐

  1. android字体好看,Android:更好的自定义字体方案

    摘要: 在一个应用中,我需要在所有的UI组件中使用客户提供的字体.这听起来似乎是个很稀松平常的任务,不是吗?是的,我当时也是这么想的.然后我震惊了,Android竟然没有提供一个简单优雅的方式来做这件 ...

  2. android 字体编程,Android编程之Calligraphy:Android 自定义字体库

    Calligraphy是android 自定义字体库 添加依赖 Download from Maven Central (.jar) OR Java dependencies { compile 'u ...

  3. android 自定义view 高度,自定义View之宽高的设置,全网最详解

    今天给大家带来的是自定义View,然后如何设置他的宽高,经常用自定义view的程序猿肯定都知道我们在给自定义view设置wrap_content或者match_parent,view都会占满全屏,就想 ...

  4. android 自定义加载动画效果,Android 自定义View修炼-自定义加载进度动画LoadingImageView...

    一.概述 本自定义View,是加载进度动画的自定义View,继承于ImageView来实现,主要实现蒙层加载进度的加载进度效果. 支持水平左右加载和垂直上下加载四个方向,同时也支持自定义蒙层进度颜色. ...

  5. android 字体百分比,android 解决百分比布局适配时Textview的字体Textsize比例缩放问题...

    在使用百分比布局的过程中,大家可能会遇到一个问题,Textview的控件大小是由百分比分数算出来的,但是字体大小Textsize却没法确定.于是我想到继承textview写一个自定义的PercentT ...

  6. 自定义View和自定义ViewGroup一步到位

    1.自定义View 首先我们要明白,为什么要自定义View?主要是Android系统内置的View无法实现我们的需求,我们需要针对我们的业务需求定制我们想要的View.自定义View我们大部分时候只需 ...

  7. android字体行距,android textview设置字体的行距和字间距

    字间距 textView有一个属性android:textScaleX是调节字间距的,它的值是一个float型.查看源代码,默认textView 此属性是使用的是: android.internal. ...

  8. android字体行距,android中怎么调整字体的间距和行间距

    在网页中都是很轻松的就可以调整间距的.在android中,我个人并没有去设置过. 下面就来说说android中的间距问题. 原文:http://blog.csdn.net/fancylovejava/ ...

  9. 自定义View之自定义支付宝密码输入控件

    效果如图上边(录像文件被压缩有些失真) 1.可以设置密码位数 2.每个格子能输入一位的数字 3.背景框.分割线.圆点颜色可以设置 4.位数输入满后可直接进行提示或后续操作 首先设置下需要的属性attr ...

最新文章

  1. mysql运维工资_MySQL运维踩坑
  2. Python搭建Keras CNN模型破解网站验证码
  3. docker 使用python 镜像运行python脚本
  4. Asp.net网站的自动部署-sqlserver数据库的自动部署
  5. 不通过寄存器确定数据的长度 + 案例
  6. c++用什么软件编程_为什么要学习“C”编程语言?
  7. 安卓学习笔记14:安卓手势操作编程
  8. 【英语学习】【English L06】U06 Banking L1 How can I save money?
  9. CRMEB制作docker-compose
  10. 【寒江雪】Go实现单例模式
  11. win7 windows update 无法更新错误代码80072EF
  12. net域名和com域名在属性和价值上有什么不同?
  13. JQ彩色3D纸片折叠动画
  14. 如何在高德地图windowInfo弹窗中使用VUE组件
  15. 吉德林法则 (Kidlin's Law)的真实案例(2)
  16. 【Scratch】《零基础入门学习Scratch》(小甲鱼)笔记二
  17. 5. SpringSecurity用户认证源码 与 实现短信验证码(自定义SpringSecurity组件)
  18. 转 CRT 上传 下载
  19. 盘点世界十大末日预言
  20. CSS-动态计算高度

热门文章

  1. 读《精通正则表达式》-- 网上 js 正则基础教程没有涉及的一些知识
  2. 人工智能方向毕业设计_毕业季|广州美术学院视觉设计学院毕业设计展
  3. HDU2112 HDU Today【Floyd算法】
  4. 北大操作系统陈向群第六章知识点
  5. [整理]PCB阻抗控制
  6. PHP实现文字写入图片功能
  7. 《送给八年以前两年以后的自己》
  8. 移动适配(引入js知识)
  9. OCR--服务器端身份证识别系统的原理及应用
  10. java图形化Swing教程(二)