Android简单的可设置间隔评分条的实现
2016-07-26 09:19
441 查看
最近比较忙,有一段时间没有写博客了,之前项目写过一个很简单的评分条,来分享一下:
安卓原生提供了SeekBar可拖动的评分条,不过有的时候并不怎么好用,当只需要去显示评分条(比如几颗星的评分)的情况下,不需要拖动,SeekBar本身没有方法去设置单项之间的间隔,比较普遍的做法就是去修改一下图片,在图片两边适当添加一些距离.用起来不是特别舒服,所以自己实现一下.
先设置一下自定义属性attr:
MarkView:
需要注意的是在下边两个地方中的默认图片需要自己提供一下.
用法也比较简单,只需要在用到的地方调用setStepsNum方法即可.设置评分条单项之间间距可以通过设置控件的mkInterval属性来控制.
安卓原生提供了SeekBar可拖动的评分条,不过有的时候并不怎么好用,当只需要去显示评分条(比如几颗星的评分)的情况下,不需要拖动,SeekBar本身没有方法去设置单项之间的间隔,比较普遍的做法就是去修改一下图片,在图片两边适当添加一些距离.用起来不是特别舒服,所以自己实现一下.
代码实现
代码比较简单,就直接贴一下.先设置一下自定义属性attr:
<!--普通评分条图片--> <attr name="mkNormalDrawable" format="reference"/> <!--选中评分条图片--> <attr name="mkSelectDrawable" format="reference"/> <!--评分项间隔--> <attr name="mkInterval" format="dimension"/> <!--评分项高度--> <attr name="mkHeight" format="dimension"/> <!--评分项宽度--> <attr name="mkWidth" format="dimension"/> <!--评分项宽度--> <attr name="mkSize" format="integer"/> <declare-styleable name="MarkView"> <attr name="mkNormalDrawable"/> <attr name="mkSelectDrawable"/> <attr name="mkInterval"/> <attr name="mkHeight"/> <attr name="mkWidth"/> <attr name="mkSize"/> </declare-styleable>
MarkView:
package com.teda.makerunion.widget; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; import com.teda.makerunion.R; import com.teda.makerunion.utils.LogUtils; /** * 评分条 * Created by junweiliu on 16/6/22. */ public class MarkView extends LinearLayout { /** * 需要创建的评分图片的个数 */ private int childViewCount = 5; /** * 设置圆点间margin */ private int mInterval; /** * 当前选中的位置 */ private int mCurrentPostion = 3; /** * 普通显示的图片 */ private Bitmap normalBp; /** * 选中时显示的图片 */ private Bitmap selectBp; /** * 评分单项宽度 */ private int mWidth; /** * 评分单项高度 */ private int mHeight; public MarkView(Context context) { this(context, null); } public MarkView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MarkView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); // 获取自定义属性 TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MarkView); childViewCount = ta.getInteger(R.styleable.MarkView_mkSize, 5); normalBp = drawableToBitamp(ta.getDrawable(R.styleable.MarkView_mkNormalDrawable)); selectBp = drawableToBitamp(ta.getDrawable(R.styleable.MarkView_mkSelectDrawable)); mInterval = ta.getDimensionPixelOffset(R.styleable.MarkView_mkInterval, 3); mWidth = ta.getDimensionPixelOffset(R.styleable.MarkView_mkWidth, 0); mHeight = ta.getDimensionPixelOffset(R.styleable.MarkView_mkHeight, 0); ta.recycle(); init(); } /** * 初始化数据 */ private void init() { // 处理自定义属性 if (null == normalBp) { normalBp = BitmapFactory.decodeResource(getContext().getResources(), R.mipmap.star_dark); } if (null == selectBp) { selectBp = BitmapFactory.decodeResource(getContext().getResources(), R.mipmap.star_light); } if (0 == mWidth) { mWidth = Math.max(selectBp.getWidth(), normalBp.getWidth()); } if (0 == mHeight) { mHeight = Math.max(selectBp.getWidth(), normalBp.getWidth()); } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int sizeWidth = MeasureSpec.getSize(widthMeasureSpec); int sizeHeight = MeasureSpec.getSize(heightMeasureSpec); // 如果是wrap_content设置为图片宽高,否则设置为父容器宽高 setMeasuredDimension((widthMode == MeasureSpec.EXACTLY) ? sizeWidth : (mWidth + mInterval) * childViewCount , (heightMode == MeasureSpec.EXACTLY) ? sizeHeight : mHeight); } /** * 重绘 * * @param canvas */ @Override protected void dispatchDraw(Canvas canvas) { // 创建指示器圆点 if (getChildCount() < childViewCount && getChildCount() == 0) { for (int i = 0; i < childViewCount; i++) { addView(makeMarkItem()); } } // 设置默认选中指示器 setCurrentSteps(mCurrentPostion); super.dispatchDraw(canvas); } /** * 创建评分项 * * @return */ private View makeMarkItem() { ImageView iv = new ImageView(getContext()); LinearLayout.LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); lp.width = mWidth; lp.height = mHeight; lp.rightMargin = mInterval; iv.setImageBitmap(normalBp); iv.setLayoutParams(lp); return iv; } /** * 设置当前个数 * * @param num */ public void setStepsNum(int num) { this.mCurrentPostion = num; setCurrentSteps(mCurrentPostion); // invalidate(); } /** * 设置当前的选中位置,进行图片替换 * * @param currentSteps */ public void setCurrentSteps(int currentSteps) { for (int i = 0; i < getChildCount(); i++) { if (i < currentSteps) ((ImageView) getChildAt(i)).setImageBitmap(selectBp); else ((ImageView) getChildAt(i)).setImageBitmap(normalBp); } } /** * drawable转bitmap * * @param drawable * @return */ private Bitmap drawableToBitamp(Drawable drawable) { if (null == drawable) { return null; } if (drawable instanceof BitmapDrawable) { BitmapDrawable bd = (BitmapDrawable) drawable; return bd.getBitmap(); } int w = drawable.getIntrinsicWidth(); int h = drawable.getIntrinsicHeight(); Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, w, h); drawable.draw(canvas); return bitmap; } }
需要注意的是在下边两个地方中的默认图片需要自己提供一下.
if (null == normalBp) { normalBp = BitmapFactory.decodeResource(getContext().getResources(), R.mipmap.star_dark); } if (null == selectBp) { selectBp = BitmapFactory.decodeResource(getContext().getResources(), R.mipmap.star_light); }
用法也比较简单,只需要在用到的地方调用setStepsNum方法即可.设置评分条单项之间间距可以通过设置控件的mkInterval属性来控制.
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories