1. 程式人生 > >自定義RatingBar控制元件,實現可自定義星星(或專案所需圖片)的寬高,告別使用warp_content導致控制元件大小不可控

自定義RatingBar控制元件,實現可自定義星星(或專案所需圖片)的寬高,告別使用warp_content導致控制元件大小不可控

之前做過的一款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" />