Android中自定义RatingBar
2015-08-16 13:32
471 查看
效果图
运行的效果图
自定义的RatingView
在res\values文件夹下建立attr.xml文件
布局文件
欢迎大神们指教,免费下载代码地址
运行的效果图
自定义的RatingView
package com.example.ratingbar; import java.util.ArrayList; import android.content.Context; import android.content.res.TypedArray; import android.os.Parcel; import android.os.Parcelable; import android.util.AttributeSet; import android.util.TypedValue; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; public class Rating extends ViewGroup { /* * 四张图片 */ private int[] pictures; private ArrayList<TextView> array = new ArrayList<TextView>(); /* * 当前的位置 */ private int position = 0; /* * 總的數據的長度 */ private int length = 0; /* * 间隔 */ private int jiange = 0; // private int xingWidth = 0; private int xingHeight = 0; public Rating(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { this(context, attrs); } public Rating(Context context, AttributeSet attrs, int defStyleAttr) { this(context, attrs); } public Rating(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub pictures = new int[4]; TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Rating); pictures[0] = a.getResourceId(R.styleable.Rating_graySchedule, R.drawable.line_grey); pictures[1] = a.getResourceId(R.styleable.Rating_highSchedule, R.drawable.line_yellow); pictures[2] = a.getResourceId(R.styleable.Rating_grayRating, R.drawable.xing1); pictures[3] = a.getResourceId(R.styleable.Rating_highRating, R.drawable.xing2); jiange = a.getInt(R.styleable.Rating_jiange, (int) TypedValue .applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, getResources() .getDisplayMetrics())); a.recycle(); for (int i = 0; i < 6; i++) { // ImageView imageView = new ImageView(getContext()); TextView textView = new TextView(getContext()); if (i == 0) { textView.setBackgroundResource(pictures[2]); textView.setText(String.valueOf(i)); } else { textView.setBackgroundResource(pictures[0]); } textView.setGravity(Gravity.CENTER); ViewGroup.LayoutParams params = new ViewGroup.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); MarginLayoutParams params2 = new MarginLayoutParams(params); textView.setLayoutParams(params2); addView(textView); array.add(textView); } length = array.size(); } public Rating(Context context) { this(context, null); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // TODO Auto-generated method stub /** * 获得此ViewGroup上级容器为其推荐的宽和高,以及计算模式 */ int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int sizeWidth = MeasureSpec.getSize(widthMeasureSpec); int sizeHeight = MeasureSpec.getSize(heightMeasureSpec); // 计算出所有的childView的宽和高 measureChildren(widthMeasureSpec, heightMeasureSpec); int cCount = getChildCount(); int cWidth = 0; int cHeight = 0; MarginLayoutParams cParams = null; int maxHeight = 0; int maxWidth = 0; // int mW = 0; /** * 根据childView计算的出的宽和高,以及设置的margin计算容器的宽和高,主要用于容器是warp_content时 */ for (int i = 0; i < cCount; i++) { View childView = getChildAt(i); cWidth = childView.getMeasuredWidth(); cHeight = childView.getMeasuredHeight(); cParams = (MarginLayoutParams) childView.getLayoutParams(); if (i == 0) { maxHeight = cHeight + cParams.topMargin + cParams.bottomMargin; mW = cWidth + cParams.leftMargin + cParams.rightMargin; } else { int t1 = cWidth + cParams.leftMargin + cParams.rightMargin; if (t1 > mW) { mW = t1; } int t2 = cHeight + cParams.topMargin + cParams.bottomMargin; if (t2 > maxHeight) { maxHeight = t2; } } xingWidth = mW; xingHeight = maxHeight; maxWidth += cWidth + cParams.leftMargin + cParams.rightMargin; } maxWidth += (length - 1) * jiange; /** * 如果是wrap_content设置为我们计算的值 否则:直接设置为父容器计算的值 */ setMeasuredDimension((widthMode == MeasureSpec.EXACTLY) ? sizeWidth : maxWidth, (heightMode == MeasureSpec.EXACTLY) ? sizeHeight : maxHeight); } @Override public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { return new MarginLayoutParams(getContext(), attrs); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { // TODO Auto-generated method stub int height = getHeight(); int cCount = getChildCount(); int cWidth = 0; int cHeight = 0; MarginLayoutParams cParams = null; int h = 0; /** * 遍历所有childView根据其宽和高,以及margin进行布局 */ for (int i = 0; i < cCount; i++) { View childView = getChildAt(i); cWidth = childView.getMeasuredWidth(); cHeight = childView.getMeasuredHeight(); cParams = (MarginLayoutParams) childView.getLayoutParams(); int cl = 0, ct = 0, cr = 0, cb = 0; cl = cParams.leftMargin + h; ct = (height - cHeight) / 2 - cParams.topMargin; // ct = cParams.topMargin; cr = cl + cWidth + cParams.rightMargin; cb = cHeight + ct; h = cr + jiange; childView.layout(cl, ct, cr, cb); } } @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub if (xingWidth == 0 || xingHeight == 0) { return super.onTouchEvent(event); } int x = (int) event.getX(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: if (!dealPosition(x)) { return super.onTouchEvent(event); } int number = x / (xingWidth + jiange); if (number + 1 > length) { return super.onTouchEvent(event); } else { dealHuaMian(number); // array.get(number).setBackgroundResource(R.drawable.xing1); } break; case MotionEvent.ACTION_UP: break; case MotionEvent.ACTION_MOVE: break; } return super.onTouchEvent(event); } /* * 处理坐标的问题 */ private boolean dealPosition(int x) { int t = x % (jiange + xingWidth); if (t > xingWidth && t < xingWidth + jiange) { return false; } else { return true; } } /* * 处理显示的画面 */ private void dealHuaMian(int p) { if (p < 0) { return; } if (p + 1 > length) { return; } if (p == position) { // 不需要任何处理 } else if (p > position) { // 向前 for (int i = position; i <= p - 1; i++) { TextView textView = array.get(i); textView.setBackgroundResource(pictures[1]); textView.setText(""); } TextView tv = array.get(p); tv.setBackgroundResource(pictures[3]); tv.setText(String.valueOf(p)); } else if (p < position) { // 向后 for (int i = position; i >= p + 1; i--) { TextView textView = array.get(i); textView.setBackgroundResource(pictures[0]); textView.setText(""); } TextView tv = array.get(p); if (p == 0) { tv.setBackgroundResource(pictures[2]); } else { tv.setBackgroundResource(pictures[3]); } tv.setText(String.valueOf(p)); } position = p; } @Override protected Parcelable onSaveInstanceState() { // TODO Auto-generated method stub Parcelable superState = super.onSaveInstanceState(); SavedState ss = new SavedState(superState); ss.state = position; return ss; } @Override protected void onRestoreInstanceState(Parcelable state) { // TODO Auto-generated method stub SavedState ss = (SavedState) state; super.onRestoreInstanceState(ss.getSuperState()); position = ss.state; refreshDate(); } /* * 重新刷新数据 */ private void refreshDate() { for (int i = 0; i < position; i++) { TextView textView = array.get(i); textView.setBackgroundResource(pictures[1]); textView.setText(""); } TextView tv = array.get(position); if (position == 0) { tv.setBackgroundResource(pictures[2]); } else { tv.setBackgroundResource(pictures[3]); } tv.setText(String.valueOf(position)); } static class SavedState extends BaseSavedState { private int state; SavedState(Parcelable superState) { super(superState); } private SavedState(Parcel in) { super(in); state = in.readInt(); } @Override public void writeToParcel(Parcel out, int flags) { super.writeToParcel(out, flags); out.writeInt(state); } public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() { public SavedState createFromParcel(Parcel in) { return new SavedState(in); } public SavedState[] newArray(int size) { return new SavedState[size]; } }; } // 接口 /* * 取得当前的评分数目 */ public int getRatingNumber() { return position; } /* * 设置图像 */ public void setRatingPictures(int p1, int p2, int p3, int p4) { pictures[0] = p1; pictures[1] = p2; pictures[2] = p3; pictures[3] = p4; } }
在res\values文件夹下建立attr.xml文件
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="Rating"> <attr name="grayRating" format="reference" /> <attr name="highRating" format="reference" /> <attr name="graySchedule" format="reference" /> <attr name="highSchedule" format="reference" /> <attr name="jiange" format="integer" /> </declare-styleable> </resources>
布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" android:orientation="vertical" xmlns:app="http://schemas.android.com/apk/res/com.example.ratingbar"> <!-- xmlns:example="http://schemas.android.com/apk/res/com.example.ratingbar" --> <com.example.ratingbar.Rating android:id="@+id/rating1" app:jiange="10" app:graySchedule="@drawable/line_grey" app:highSchedule="@drawable/line_yellow" app:grayRating="@drawable/xing1" app:highRating="@drawable/xing2" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <com.example.ratingbar.Rating android:id="@+id/rating2" app:jiange="10" app:graySchedule="@drawable/line_grey" app:highSchedule="@drawable/line_yellow" app:grayRating="@drawable/xing1" app:highRating="@drawable/xing2" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <com.example.ratingbar.Rating android:id="@+id/rating3" app:jiange="10" app:graySchedule="@drawable/line_grey" app:highSchedule="@drawable/line_yellow" app:grayRating="@drawable/xing1" app:highRating="@drawable/xing2" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <com.example.ratingbar.Rating android:id="@+id/rating4" app:jiange="10" app:graySchedule="@drawable/line_grey" app:highSchedule="@drawable/line_yellow" app:grayRating="@drawable/xing1" app:highRating="@drawable/xing2" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <com.example.ratingbar.Rating android:id="@+id/rating5" app:jiange="10" app:graySchedule="@drawable/line_grey" app:highSchedule="@drawable/line_yellow" app:grayRating="@drawable/xing1" app:highRating="@drawable/xing2" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <com.example.ratingbar.Rating android:id="@+id/rating6" app:jiange="10" app:graySchedule="@drawable/line_grey" app:highSchedule="@drawable/line_yellow" app:grayRating="@drawable/xing1" app:highRating="@drawable/xing2" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
欢迎大神们指教,免费下载代码地址
相关文章推荐
- Android 使用android-support-multidex解决Dex超出方法数的限制问题,让你的应用不再爆棚
- Android 基础:surfaceSurface、SurfaceHolder 及 SurfaceHolder.Callback , 范例说明
- Android的所有权限说明
- Android Studio系列教程四--Gradle基础
- Android Context作用
- Android源码分析之ListView
- Android - 电池状态
- Android的ListView分页功能
- qq登陆
- android 相机图库调用以及裁剪
- android学习笔记1
- Android SQLite 简单使用示例
- android-音乐播放器实现及源码下载(四)
- android-音乐播放器实现及源码下载(三)
- android-音乐播放器实现及源码下载(二)
- android-音乐播放器实现及源码下载(一)
- android体系结构以及源代码阅读环境搭建
- Android进程间通信模型之思考Binder和Service_manager的模型
- Android_Animation Drawable(旋转动画)
- Android EventBus源码解析 带你深入理解EventBus