自定義RatingBar控制元件,實現可自定義星星(或專案所需圖片)的寬高,告別使用warp_content導致控制元件大小不可控
阿新 • • 發佈:2019-01-09
之前做過的一款app中涉及到RatingBar控制元件,基本上來說都會要求用圖片來替代, 即使同樣是星星(可能是覺得系統自帶的比較醜吧,不過我覺得還好啊)。 當時就覺得很難去做適配,UI給的圖片沒法去控制寬高,只能使用warp_content來做, 可是這樣會導致控制元件很大,即使是用了maxHeight和minHeight來控制,這只是控制了RatingBar的寬高, 對於RatingBar裡的子控制元件(姑且這麼說吧,有知道的可以告訴我)是沒有效果的。 當時想著自定義來解決,後來專案要求不是那麼嚴格吧,就沒有處理。如果還是那麼做的話會超出螢幕範圍, 沒辦法,只能自己搞定咯。 這是自定義控制元件
package com.lg.customstarview;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
/**
* 簡單實現星級評選控制元件:內部填充多個ImageView
* 繼承LinearLayout 設定水平方向
*/
public class CustomStarView extends LinearLayout {
private int mImageWidth = 20; //圖片設定預設的寬度
private int mImageHeight = 20; //圖片設定預設的高度
private int mDefaultImageId = R.mipmap.ic_launcher;
private int mClickImageId = R.mipmap.ic_launcher;
private int mMargin = 5; //圖片之間預設的margin
private int mStarNum = 5; //星星預設的個數
private int mStarChoose = 3; //預設預設是三顆星
private boolean isClick = true;
private OnStarItemClickListener mStarItemClickListener;
public CustomStarView(Context context, AttributeSet attrs) {
super(context, attrs);
initData(context, attrs);
}
public CustomStarView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initData(context, attrs);
}
/**
* 初始化資料
*
* @param context
* @param attrs
*/
private void initData(Context context, AttributeSet attrs) {
this.setOrientation(HORIZONTAL); //設定水平
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
R.styleable.StarView, 0, 0);
int n = a.getIndexCount();
for (int i = 0; i < n; i++) {
int attr = a.getIndex(i);
switch (attr) {
case R.styleable.StarView_mImageWidth:
mImageWidth = (int) a.getDimension(attr, mImageWidth);
break;
case R.styleable.StarView_mImageHeight:
mImageHeight = (int) a.getDimension(attr, mImageHeight);
break;
case R.styleable.StarView_mDefaultImageId:
mDefaultImageId = a.getResourceId(attr, mDefaultImageId);
break;
case R.styleable.StarView_mClickImageId:
mClickImageId = a.getResourceId(attr, mClickImageId);
break;
case R.styleable.StarView_mMargin:
mMargin = (int) a.getDimension(attr, mMargin);
break;
case R.styleable.StarView_mStarNum:
mStarNum = a.getInt(attr, mStarNum);
break;
case R.styleable.StarView_mStarChoose:
mStarChoose = a.getInt(attr, mStarChoose);
break;
}
}
a.recycle();
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
setStarNum(mStarNum); //設定個數
}
/**
* 設定星星數量
* 呼叫該方法可以手動設定星星數量
* @param number
*/
public void setStarNum(int number) {
// if (number <= 0) {
// try {
// throw new Exception("設定的資料不能小於等於零");
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
this.removeAllViews(); //清空所有view
if(number == 0){
for (int i = 0; i < 5; i++) {
ImageView imageView = new ImageView(getContext());
final LayoutParams layoutParams = new LayoutParams(mImageWidth, mImageHeight);
layoutParams.leftMargin = mMargin;
layoutParams.rightMargin = mMargin;
imageView.setLayoutParams(layoutParams);
this.addView(imageView);
imageView.setImageResource(mDefaultImageId);
// setStarOnClick(imageView, i);
}
}else {
for (int i = 0; i < number; i++) {
ImageView imageView = new ImageView(getContext());
final LayoutParams layoutParams = new LayoutParams(mImageWidth, mImageHeight);
layoutParams.leftMargin = mMargin;
layoutParams.rightMargin = mMargin;
imageView.setLayoutParams(layoutParams);
this.addView(imageView);
imageView.setImageResource(mDefaultImageId);
// setStarOnClick(imageView, i);
}
setCurrentChoose(mStarChoose); //設定當前選擇
}
}
/**
* 設定點選事件
*
* @param imageView
* @param i
*/
private void setStarOnClick(final ImageView imageView, final int i) {
if (imageView != null) {
imageView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
resetDefaultImage();
setCurrentChoose(i+1);
if (mStarItemClickListener != null) {
mStarItemClickListener.onItemClick(imageView, i);
}
}
});
}
}
/**
* 設定當前選擇
*
* @param index
*/
private void setCurrentChoose(int index) {
if(isClick){
for (int i = 0; i < index; i++) {
ImageView imageView = (ImageView) getChildAt(i);
imageView.setImageResource(mClickImageId);
}
}
}
/**
* 重置預設為預設的圖片
*/
private void resetDefaultImage() {
int cNum = getChildCount();
for (int i = 0; i < cNum; i++) {
ImageView imageView = (ImageView) getChildAt(i);
imageView.setImageResource(mDefaultImageId);
}
}
public int getImageWidth() {
return mImageWidth;
}
public void setImageWidth(int mImageWidht) {
this.mImageWidth = mImageWidht;
}
public int getImageHeight() {
return mImageHeight;
}
public void setImageHeight(int mImageHeight) {
this.mImageHeight = mImageHeight;
}
public int getDefaultImageId() {
return mDefaultImageId;
}
public void setDefaultImageId(int resouceId) {
this.mDefaultImageId = mDefaultImageId;
}
public int getClickImageId() {
return mClickImageId;
}
public void setClickImageId(int mClickImageId) {
this.mClickImageId = mClickImageId;
}
public OnStarItemClickListener getStarItemClickListener() {
return mStarItemClickListener;
}
public void setmStarItemClickListener(OnStarItemClickListener mStarItemClickListener) {
this.mStarItemClickListener = mStarItemClickListener;
}
/**
* 星星點選事件
*/
public interface OnStarItemClickListener {
public void onItemClick(View view, int pos);
}
}`
自定義空間設計到的style,放在styles目錄下即可
<!--自定星級控制元件-->
<declare-styleable name="StarView">
<attr name="mImageWidth" format="dimension"/>
<attr name="mImageHeight" format="dimension" />
<attr name="mDefaultImageId" format="reference" />
<attr name="mClickImageId" format="reference" />
<attr name="mMargin" format="dimension" />
<attr name="mStarNum" format="integer" />
<attr name="mStarChoose" format="integer" />
</declare-styleable>
佈局檔案在這裡
<com.lg.customstarview.CustomStarView
android:layout_alignParentRight="true"
android:layout_marginLeft="5dp"
android:layout_marginRight="10dp"
android:id="@+id/start_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
fresco:mClickImageId="@drawable/medal_selected"
fresco:mDefaultImageId="@drawable/medal"
fresco:mImageHeight="20dp"
fresco:mImageWidth="20dp"
fresco:mMargin="2dp"
fresco:mStarChoose="3"
fresco:mStarNum="5" />