一点红开奖网一肖中特免费公开资:簡單易用的星級控件

[復制鏈接]
來自: MrlLee 分類: Android精品源碼 上傳時間: 2016-10-9 10:36:43
Tag:resources , Failed , commit , latest , 星級

項目介紹:


[Java] 查看源文件 復制代碼
在開發電商項目中經常都會遇到一些星級評分控件的需求,有需求就必然有開發。廢話不多說,沒圖沒真相,上圖:


image



[Java] 查看源文件 復制代碼
先吐槽幾句,使用官方提供SatingBar各種蛋疼,圖片無法自定義,適配也是麻煩的事情。


確定需求:




  • 可以控制子item之間的邊距

  • 自定義選中圖片和未選中圖片

  • 擺放縱向或者橫向

  • 可選擇選中數量



基本繪制流程:




  • 1 自定義屬性




<declare-styleable name="StarBarView">

<attr name="space_width" format="dimension" />

<attr name="star_width" format="dimension" />

<attr name="star_height" format="dimension" />

<attr name="star_max" format="integer" />

<attr name="star_rating" format="float" />

<attr name="star_hollow" format="reference" />

<attr name="star_solid" format="reference" />

<attr name="star_isIndicator" format="boolean" />

<attr name="star_orientation" format="enum">
<enum name="vertical" value="1" />
<enum name="horizontal" value="0" />
attr>
declare-styleable>



  • 2 構造函數中獲取自定義屬性值



    //星星水平排列
public static final int HORIZONTAL = 0;
//星星垂直排列
public static final int VERTICAL = 1;
//實心圖片
private Bitmap mSolidBitmap;
//空心圖片
private Bitmap mHollowBitmap;
private Context context;
//最大的數量
private int starMaxNumber;
private float starRating;
private Paint paint;
private int mSpaceWidth;//星星間隔
private int mStarWidth;//星星寬度
private int mStarHeight;//星星高度
private boolean isIndicator;//是否是一個指示器(用戶無法進行更改)
private int mOrientation;

public StarBarView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public StarBarView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
paint = new Paint();
this.context = context;
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.StarBarView, defStyle, 0);
mSpaceWidth = a.getDimensionPixelSize(R.styleable.StarBarView_space_width, 0);
mStarWidth = a.getDimensionPixelSize(R.styleable.StarBarView_star_width, 0);
mStarHeight = a.getDimensionPixelSize(R.styleable.StarBarView_star_height, 0);
starMaxNumber = a.getInt(R.styleable.StarBarView_star_max, 0);
starRating = a.getFloat(R.styleable.StarBarView_star_rating, 0);
mSolidBitmap = getZoomBitmap(BitmapFactory.decodeResource(context.getResources(), a.getResourceId(R.styleable.StarBarView_star_solid, 0)));
mHollowBitmap = getZoomBitmap(BitmapFactory.decodeResource(context.getResources(), a.getResourceId(R.styleable.StarBarView_star_hollow, 0)));
mOrientation = a.getInt(R.styleable.StarBarView_star_orientation, HORIZONTAL);
isIndicator = a.getBoolean(R.styleable.StarBarView_star_isIndicator, false);
a.recycle();
}



  • 3 獲取圖片bitmap,設置寬高



/**
* 獲取縮放圖片
*
* @param bitmap
* @return
*/
public Bitmap getZoomBitmap(Bitmap bitmap) {
if (mStarWidth == 0 || mStarHeight == 0) {
return bitmap;
}
// 獲得圖片的寬高
int width = bitmap.getWidth();
int height = bitmap.getHeight();

// 設置想要的大小
int newWidth = mStarWidth;
int newHeight = mStarHeight;
// 計算縮放比例
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// 取得想要縮放的matrix參數
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
// 得到新的圖片
Bitmap newbm = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
return newbm;
}



  • 4 onMeasure函數測量子控件大小,然后設置當前控件大小



@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mOrientation == HORIZONTAL) {
//判斷是橫向還是縱向,測量長度
setMeasuredDimension(measureLong(widthMeasureSpec), measureShort(heightMeasureSpec));
} else {
setMeasuredDimension(measureShort(widthMeasureSpec), measureLong(heightMeasureSpec));
}
}

private int measureLong(int measureSpec) {
int result;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);

if ((specMode == MeasureSpec.EXACTLY)) {
result = specSize;
} else {
result = (int) (getPaddingLeft() + getPaddingRight() + (mSpaceWidth + mStarWidth) * (starMaxNumber));
if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(result, specSize);
}
}
return result;
}

private int measureShort(int measureSpec) {
int result;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);

if (specMode == MeasureSpec.EXACTLY) {
result = specSize;
} else {
result = (int) (mStarHeight + getPaddingTop() + getPaddingBottom());
if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(result, specSize);
}
}
return result;
}



  • 5 確定好數據后開始描繪bitmap到Canvas上



@Override
protected void onDraw(Canvas canvas) {
if (mHollowBitmap == null || mSolidBitmap == null) {
return;
}
//繪制實心進度
int solidStarNum = (int) starRating;
//繪制實心的起點位置
int solidStartPoint = 0;
if (mOrientation == HORIZONTAL)
for (int i = 1; i <= solidStarNum; i++) {
canvas.drawBitmap(mSolidBitmap, solidStartPoint, 0, paint);
solidStartPoint = solidStartPoint + mSpaceWidth + mSolidBitmap.getWidth();
}
else
for (int i = 1; i <= solidStarNum; i++) {
canvas.drawBitmap(mSolidBitmap, 0, solidStartPoint, paint);
solidStartPoint = solidStartPoint + mSpaceWidth + mSolidBitmap.getHeight();
}
//虛心開始位置
int hollowStartPoint = solidStartPoint;
//多出的實心部分起點
int extraSolidStarPoint = hollowStartPoint;
//虛心數量
int hollowStarNum = starMaxNumber - solidStarNum;
if (mOrientation == HORIZONTAL)
for (int j = 1; j <= hollowStarNum; j++) {
canvas.drawBitmap(mHollowBitmap, hollowStartPoint, 0, paint);
hollowStartPoint = hollowStartPoint + mSpaceWidth + mHollowBitmap.getWidth();
}
else
for (int j = 1; j <= hollowStarNum; j++) {
canvas.drawBitmap(mHollowBitmap, 0, hollowStartPoint, paint);
hollowStartPoint = hollowStartPoint + mSpaceWidth + mHollowBitmap.getWidth();
}
//多出的實心長度
int extraSolidLength = (int) ((starRating - solidStarNum) * mHollowBitmap.getWidth());
Rect rectSrc = new Rect(0, 0, extraSolidLength, mHollowBitmap.getHeight());
Rect dstF = new Rect(extraSolidStarPoint, 0, extraSolidStarPoint + extraSolidLength, mHollowBitmap.getHeight());
canvas.drawBitmap(mSolidBitmap, rectSrc, dstF, paint);
}



  • 6 最后通過onTouchEvent方法去監聽事件



@Override
public boolean onTouchEvent(MotionEvent event) {
if (!isIndicator) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (mOrientation == HORIZONTAL) {
float TotalWidth = starMaxNumber * (mStarWidth + mSpaceWidth);
if (event.getX() <= TotalWidth) {
float newStarRating = (int) event.getX() / (mStarWidth + mSpaceWidth) + 1;
setStarRating(newStarRating);
}
}else{
float TotalHeight = starMaxNumber * (mStarHeight + mSpaceWidth);
if (event.getY() <= TotalHeight) {
float newStarRating = (int) event.getY() / (mStarHeight + mSpaceWidth) + 1;
setStarRating(newStarRating);
}
}
break;
case MotionEvent.ACTION_MOVE:
// float starTotalWidth = starMaxNumber * (mStarWidth + mSpaceWidth);
// if (event.getX() <= starTotalWidth) {
// float newStarRating = (int) event.getX() / (mStarWidth + mSpaceWidth) + 1;
// setStarRating(newStarRating);
// }
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_CANCEL:
break;
}
}
return super.onTouchEvent(event);
}


如何使用:




  • xml布局



<com.caption.starbarexample.widget.StarBarView
android:id="@+id/sbv_starbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_margin="10dp"
app:space_width="1dp"
app:star_height="25dp"
app:star_hollow="@mipmap/ic_star_yellow_normal"
app:star_isIndicator="false"
app:star_max="5"
app:star_orientation="horizontal"
app:star_rating="2"
app:star_solid="@mipmap/ic_star_yellow_selected"
app:star_width="25dp" />



  • 代碼添加



    //拿到當前星星數量
mStarbar.getStarRating();

相關源碼推薦:

我來說兩句
所有評論(261)
是個寶寶 2016-10-9 10:47:32
不錯不錯,樓主辛苦了。。。
回復
lshdashuaibi 2016-10-9 11:12:02
精華內容,樓主V5!
回復
ricktians 2016-10-9 11:28:44
apkbus好的內容真的很多~贊
回復
w00214777 2016-10-9 11:44:44
感謝大神~
回復
tang0516 2016-10-9 11:56:27
很實用,感謝
回復
Mr_Zhao 2016-10-9 12:30:55
感謝分享,樓主V5~
回復
suzhouliuyan 2016-10-9 13:12:27
支持,感謝,祝巴士越來越好~
回復
領先的中文移動開發者社區
18620764416
7*24全天服務
意見反?。[email protected]

掃一掃關注我們

Powered by Discuz! X3.2© 2001-2019 Comsenz Inc.( 粵ICP備15117877號 )