自定义RatingBar
最近公司项目里增加了一个评价功能模块,就要用到咱们最常见的ratingBar了,大家都知道系统自带的ratingBar有多丑,所以打算自定义,然后翻看资料,说是在drawable里写个.xml文件,例如这样:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background" android:drawable="@drawable/startnormal"/>
<item android:id="@android:id/progress" android:drawable="@drawable/startslected"/>
</layer-list>
然后在布局文件里android:progressDrawable="@drawable/rating_style",运行试试,恩,还不错,等等下面的流苏是什么鬼??
换个图片试试,恩这次好了,可是在不同分辨率的手机上
显示的大小不一致,恩,可能还是图片的问题,可是公司美工不给出适配各个手机分辨率的图,如果你们公司图片给好几套,那么这个方法是可行的,可以满足开发需求。
我选择了自定义控件来解决,效果图如下(模拟器有点卡,真机运行效果还不错):
下面来说说思路,我选择的是组合控件方法来实现这个自定义控件,也就是利用在linearlayout中摆放imageview,实现步骤是:
1.为每一个星星设置drawable,并且计算出每个星星的起始位置并保存在集合中;
2.重写onTouchEvent方法,
当手指按下时:记录按下的横坐标downX,将所有星星设置为未选中状态,然后判断所有星星的起始坐标是否小于downX,如果小于则将星星改为选中状态;
当手指滑动时:记录每次滑动到的横坐标moveX,如果moveX大于当前最后一个选中状态星星的坐标,则是向右滑动,否则向左滑动,然后根据滑动距离除上
每两颗星星之间的滑动距离计算出滑动了几颗星星,然后改变星星的对应状态;
听起来很简单是不是?
下面就是实现代码+注释
<declare-styleable name="CustomRatingBar"> <attr name="crating" format="integer"/> <attr name="cstartDrawable" format="reference"/> <attr name="cselectedDrawable" format="reference"/> <attr name="cspace" format="dimension"/> <attr name="cisIndicator" format="boolean"/> <attr name="cstartNum" format="integer"/> </declare-styleable>
package com.example.ratingbar; import android.content.Context; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.Log; import android.util.SparseIntArray; import android.util.TypedValue; import android.view.Gravity; import android.view.MotionEvent; import android.widget.ImageView; import android.widget.LinearLayout; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; /** * Created by pactera on 2017/5/11. * 自定义ratingbar,系统自带的ratingbar很难控制图片大小,希望自定义的控件可以根据图片大小设置控件大小 * ,并且可以实现点击选中以及滑动选中的功能 */ public class CustomRatingBar extends LinearLayout {/**星星的个数*/ private int num; /**未选中的星星图片*/ private Drawable startDrawable; /**选中的星星图片*/ private Drawable selectedDrawable; /**选中的星星个数*/ private int rating; /**星星的间隔*/ private float space; /**是否是指示器,即是否可选*/ private boolean indicator; /**盛放星星的imageview的集合*/ private ArrayList<ImageView> startContains; /**盛放星星位置的集合*/ private ArrayList<Integer> locations; /**每一个星星控件的布局参数*/ private LayoutParams params; public CustomRatingBar(Context context, AttributeSet attrs) {super(context, attrs); init(context, attrs); }/**从布局文件中读取数据*/ private void init(Context context, AttributeSet attrs) {setOrientation(LinearLayout.HORIZONTAL); setGravity(Gravity.CENTER_VERTICAL); TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.CustomRatingBar); num = arr.getInteger(R.styleable.CustomRatingBar_cstartNum, 5); startDrawable = arr.getDrawable(R.styleable.CustomRatingBar_cstartDrawable); selectedDrawable = arr.getDrawable(R.styleable.CustomRatingBar_cselectedDrawable); rating = arr.getInt(R.styleable.CustomRatingBar_crating,0); space = arr.getDimension(R.styleable.CustomRatingBar_cspace, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,10,getResources().getDisplayMetrics())); indicator = arr.getBoolean(R.styleable.CustomRatingBar_cisIndicator,false); arr.recycle(); startContains = new ArrayList<>(); locations = new ArrayList<>(); params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); params.leftMargin = (int) space;//设置左边距 int locationLeft = 0; for (int i=0; i<num; i++) {ImageView iv = new ImageView(context); if (i < rating) {iv.setImageDrawable(selectedDrawable);//设置选中背景 } else {iv.setImageDrawable(startDrawable);//设置未选中背景 }iv.setLayoutParams(params); addView(iv); startContains.add(iv); locationLeft = (int) (i*startDrawable.getIntrinsicWidth() + (i+1)*space); // Log.i("zhangdi","locationLeft="+locationLeft+", intrinsicwidth="+startDrawable.getIntrinsicWidth()); locations.add(locationLeft);//设置每个星星左侧的位置坐标 }}private float downX; private float moveX; @Override public boolean onTouchEvent(MotionEvent event) {if (indicator) {return true; }switch (event.getAction()) {case MotionEvent.ACTION_DOWN:downX = event.getX(); Log.i("zhangdi","downX="+downX); handleDown(downX); break; case MotionEvent.ACTION_MOVE:moveX = event.getX() - downX; Log.i("zhangdi","moveX="+moveX+", x="+event.getX()); if (Math.abs(moveX) > (startDrawable.getIntrinsicWidth()/2)) {handleMove(event.getX()); }break; case MotionEvent.ACTION_UP:break; }return true; }/**按下时判断按的位置*/ private void handleDown(float downX) {rating = 0; for (ImageView iv: startContains) {//所有星星重置为未选状态 iv.setImageDrawable(startDrawable); }//遍历所有星星的位置,将星星设置为选中状态并且设置rating的值直到星星所在位置大于按下位置为止 for (int i=0; i<startContains.size(); i++) {if (locations.get(i) > downX) {break; }startContains.get(i).setImageDrawable(selectedDrawable); if (rating < (num - 1)) {//注意不要让下标越界 rating++; }}}/**滑动控件设置是否选中*/ private void handleMove(float moveX) {int move = 0; int unit = 0; Drawable drawable = null; Log.i("zhangdi","rating="+rating); if (moveX > locations.get(rating)) {//向右滑动 //startDrawable.getIntrinsicWidth()/2+space为一颗星星与下一颗的距离,移动距离除上两个星星间的距离, // 计算出移动了几颗星星 move = (int) ((moveX-locations.get(rating))/(startDrawable.getIntrinsicWidth()/2+space)); Log.i("zhangdi","向右滑move="+move); unit = 1; drawable = selectedDrawable; } else {//向左滑动 move = (int) ((moveX-locations.get(rating)-startDrawable.getIntrinsicWidth()/2)/(startDrawable.getIntrinsicWidth()/2+space)); Log.i("zhangdi","向左滑move="+move); unit = -1; drawable = startDrawable; }//根据滑动过了几颗星星设置星星的背景图片和rating if (move != 0) {for (int i = 0; i < Math.abs(move); i++) {startContains.get(rating).setImageDrawable(drawable); if (unit > 0 && rating < (num - 1)) {rating += unit; }else if (unit < 0 && rating >0) {rating += unit; }}}} }
使用方法
<com.example.ratingbar.CustomRatingBar android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="120dp" app:cstartDrawable="@drawable/rating_star" app:cselectedDrawable="@drawable/rating_star_select" app:cisIndicator="false" android:layout_marginLeft="10dp" app:crating="3"/>
自定义RatingBar相关推荐
- Android中自定义RatingBar实现星星大小,数量,间距等的设置
前言 系统中自带的RatingBar使用起来非常不方便,并且无法调整合适大小,于是自定义一个可自己调节星星数量,大小,间距等属性的RatingBar Demo展示图片: 布局代码如下: //(la ...
- Android 自定义RatingBar实现
Android开发中,经常要实现星星的评分效果如下图,所以今天就记录下来,以便他人使用. 1.自定义RatingBar代码: package com.example.myapplicationtest ...
- android ratingbar样式,自定义RatingBar的样式
写星座运势,难免要写RatingBar. 用法: 1.属性 android:numStars : 星星个数 android:rating : 默认点亮的星星星星个数 android:stepSize ...
- Android 自定义RatingBar设置步长没起作用
在项目中使用到了RatingBar控件,在自定义RatingBar的样式后,设置stepSize 没起作用. <RatingBarandroid:id="@+id/ratingBar& ...
- 自定义RatingBar,更方便指定星星的图标、大小,间距
首先要说下为什么大google给我们提供的有系统RatingBar,我们还要自定义呢? 在项目中经常会用到评价类的页面,像商城.o2o类的订单都需要进行评价,那么星级评分是必不可少的.设计师们设计的漂 ...
- android 星级评论,Android自定义RatingBar(星级评分控件)
1.首先在Drawable下建立five_rating_bar.xml android:id="@android:id/background" android:drawable=& ...
- 红橙Darren视频笔记 自定义RatingBar touch事件学习 dp转px listener监听
效果图: 一 需求分析 我们需要实现评分的控件 那么主要有几步 1.绘制出评分控件 2.响应用户的触摸改变星星数 3.控件发生星星变化时通知监听者 二 自定义属性 需要属性: 星星总数 选中星星的图片 ...
- Android中RatingBar的自定义效果
Android中RatingBar的自定义效果 有时候android系统提供给我们的ratingbar效果并不达到我们的要求,这个时候就可以自定义自己喜欢的ratingbar. 从上面的效果可以看出, ...
- RatingBar的自定义
RatingBar的实现其实是很简单的,只要在xml布局文件中写就行了 范例: 在主布局文件中,只需要写<RatingBar/>即可 main.xml 1 <RelativeLayo ...
- Android——RatingBar(评价条)相关知识总结贴
android用户界面之RatingBar教程实例汇总 http://www.apkbus.com/android-51346-1-1.html Android 中文 API (40) -- Rati ...
最新文章
- can口通信的软件测试,CAN通信控制程序的仿真与测试
- 利用Gearman,搭建异步分布式计算平台
- 【图像超分辨率论文】BasicVSR++: Improving Video Super-Resolution with Enhanced Propagation and Alignment
- python内置类型_Python内置对象类型
- 天线下倾角示意图_常用天线和无源器件技术参数汇总
- active mq topic消费后删除_RabbitMQ的常见队列模型:simple、work、fanout、direct、topic等等...
- 广电总局:坚决抵制含有暴力血腥等不良情节动画片上网播出
- 查找内容grep命令
- ceph客户端使用_Ceph 基础篇 认证
- CODESYS官方教程“您的第一个CODESYS程序”的一些注解
- 深入浅出MySQL规范
- Cookie、Session的使用及区别
- DDD的哲学意味(上)
- Android Paint 色彩一些偏知识
- 快车解密php,PHP迅雷、快车、旋风下载专用链转换代码
- MAC——本机域名[localhost]配置
- 基于ssm的导师交流系统
- spring默认redis连接库lettuce性能优化,突破性能天花板,获得官方建议方式2倍吞吐量
- 机器学习数据集(持续更新)
- HDU-5514-Frogs
热门文章
- 怎么查看ingress的规则_Prometheus PormQL语法及告警规则写法
- php jpeg不支持,php jpeg不支持怎么办
- python学生可以学吗_如何劝学生别浪费时间学Python
- python爬虫如何连接数据库_Python爬虫框架和数据库连接
- verilog设计一个补码加减法运算器_一文搞懂:计算机中为什么用补码来存储数据?...
- ElementUI:table获取复选中的数据
- cartographer探秘第四章之代码解析(八) --- 生成地图
- 深度学习实现工业零件的缺陷检测
- DBSCAN(自适应密度聚类)算法解析
- WebLogic 11g重置用户密码