自定義view - 仿淘寶評(píng)分控件

1. 思路分析


自定義View步驟:
1>:values__attrs.xml苦囱,自定義屬性;
2>:在第三個(gè)構(gòu)造方法中脾猛,獲取自定義屬性撕彤;
3>:onMeasure:不是必須的;
4>:onDraw:所有繪制的代碼都在寫(xiě)到onDraw方法中猛拴;

思路分析:
1>:從桌面進(jìn)入時(shí)初始化的樣子羹铅;
2>:處理用戶交互部分

2. 代碼如下


1>:attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- 淘寶評(píng)分控件 -->
    <declare-styleable name="RatingBar">
        <!-- 未選中圖片 -->
        <attr name="starNormal" format="reference"/>
        <!-- 選中圖片 -->
        <attr name="starFocus" format="reference"/>
        <!-- 評(píng)分 -->
        <attr name="gradeNumber" format="integer"/>
    </declare-styleable>
</resources>
2>:RatingBar
/**
 * ================================================
 * Email: 2185134304@qq.com
 * Created by Novate 2018/12/30 17:55
 * Version 1.0
 * Params:
 * Description:    仿淘寶評(píng)分控件
 * ================================================
*/

public class RatingBar extends View {

    // 未選中、選中的五角星
    private Bitmap mStarNormalBitmap , mStarFocusBitmap;
    // 默認(rèn)評(píng)分
    private int mGradeNumber = 5 ;
    // 當(dāng)前評(píng)分
    private int mCurrentGrade = 0 ;

    public RatingBar(Context context) {
        this(context,null);
    }

    public RatingBar(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public RatingBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        // 獲取自定義屬性
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RatingBar);
        // 未選中圖片資源id专肪,默認(rèn)傳遞0
        int starNormalId = typedArray.getResourceId(R.styleable.RatingBar_starNormal,0);
        if (starNormalId == 0){
            throw new RuntimeException("請(qǐng)?jiān)O(shè)置屬性 starNormal") ;
        }
        // 用 BitmapFactory 解析資源
        mStarNormalBitmap = BitmapFactory.decodeResource(getResources(),starNormalId);


        // 選中圖片資源id诺苹,默認(rèn)傳遞0
        int starFocusId = typedArray.getResourceId(R.styleable.RatingBar_starFocus,0);
        if (starFocusId == 0){
            throw new RuntimeException("請(qǐng)?jiān)O(shè)置屬性 starFocus") ;
        }
        // 用 BitmapFactory 解析資源
        mStarFocusBitmap = BitmapFactory.decodeResource(getResources(),starFocusId);


        // 評(píng)分分?jǐn)?shù)
        mGradeNumber = typedArray.getInt(R.styleable.RatingBar_gradeNumber,mGradeNumber);

        // 釋放資源
        typedArray.recycle();
    }


    /**
     * 測(cè)量
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        // 這里用 mStarNormalBitmap 和 mStarFocusBitmap 是一樣的
        // 寬度 1個(gè)星星寬度*星星個(gè)數(shù)
        int width = mStarFocusBitmap.getWidth()*mGradeNumber;
        // 高度 1個(gè)星星的高度
        int height = mStarFocusBitmap.getHeight();

        // 測(cè)量大小
        setMeasuredDimension(width,height);
    }


    /**
     * 繪制
     */
    @Override
    protected void onDraw(Canvas canvas) {
//        super.onDraw(canvas);
        for (int i = 0; i < mGradeNumber; i++) {
            // i * 星星寬度 1個(gè)星星寬度就是 1*寬度  2個(gè)星星寬度就是 2*寬度 
            int x = i * mStarFocusBitmap.getWidth();

            // 觸摸的時(shí)候 mCurrentGrade的值是不斷變化的势篡,i從0開(kāi)始碍侦,mCurrentGrade從1開(kāi)始
            if (mCurrentGrade > i){
                canvas.drawBitmap(mStarFocusBitmap,x,0,null);
            }else{
                canvas.drawBitmap(mStarNormalBitmap,x,0,null);
            }
        }
    }


    /**
     * 觸摸
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // 移動(dòng)株旷、按下钞瀑、抬起處理邏輯一樣显晶,判斷手指位置唯笙,根據(jù)當(dāng)前位置計(jì)算分?jǐn)?shù),然后刷新
        // 在按下時(shí)候:移動(dòng)、按下辑畦、抬起事件都會(huì)調(diào)用,把下邊的按下分扎、抬起事件注釋?zhuān)梢詼p少onDraw調(diào)用
        switch (event.getAction()){
//            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
//            case MotionEvent.ACTION_UP:

                // getX: 相對(duì)于父控件 getRawX: 相對(duì)于屏幕
                float moveX = event.getX() ;

                // 當(dāng)前分?jǐn)?shù)
                int currentGrade = (int)(moveX/mStarFocusBitmap.getWidth()+1);

                // 范圍問(wèn)題
                if (currentGrade < 0){
                    currentGrade=0;
                }
                if (currentGrade > mCurrentGrade){
                    currentGrade = mCurrentGrade;
                }

                // 分?jǐn)?shù)相同就不要再繪制了宏悦,盡量減少onDraw的調(diào)用
                if (currentGrade == mCurrentGrade){
                    // return true:表示自己處理事件傀蓉,事件不會(huì)向下傳遞
                    return true;
                }

                mCurrentGrade = currentGrade ;

                // 重新繪制
                invalidate();
                 break;
        }
        // return true:表示自己處理事件屡拨,事件不會(huì)向下傳遞
        return true;
    }
}
3>:activity_ratingbar.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.novate.test.customview.RatingBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:starNormal="@drawable/star_normal"
        app:starFocus="@drawable/star_selected"
        app:gradeNumber="5"
        />
</LinearLayout>
4>:RatingBarActivity
public class RatingBarActivity extends AppCompatActivity {
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_ratingbar);
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末呀狼,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子损离,更是在濱河造成了極大的恐慌哥艇,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件僻澎,死亡現(xiàn)場(chǎng)離奇詭異貌踏,居然都是意外死亡十饥,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)祖乳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)逗堵,“玉大人,你說(shuō)我怎么就攤上這事眷昆⊙殉樱” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵亚斋,是天一觀的道長(zhǎng)作媚。 經(jīng)常有香客問(wèn)我,道長(zhǎng)帅刊,這世上最難降的妖魔是什么纸泡? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮厚掷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘冒黑。我一直安慰自己勤哗,他們只是感情好抡爹,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著芒划,像睡著了一般冬竟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上民逼,一...
    開(kāi)封第一講書(shū)人閱讀 51,146評(píng)論 1 297
  • 那天泵殴,我揣著相機(jī)與錄音,去河邊找鬼拼苍。 笑死笑诅,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的疮鲫。 我是一名探鬼主播吆你,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼俊犯!你這毒婦竟也來(lái)了妇多?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤燕侠,失蹤者是張志新(化名)和其女友劉穎者祖,沒(méi)想到半個(gè)月后立莉,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡七问,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年蜓耻,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片烂瘫。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡媒熊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出坟比,到底是詐尸還是另有隱情芦鳍,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布葛账,位于F島的核電站柠衅,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏籍琳。R本人自食惡果不足惜菲宴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一喝峦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧谣蠢,春花似錦眉踱、人聲如沸谈喳。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)吆录。三九已至恢筝,卻和暖如春撬槽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背共啃。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留纵苛,地道東北人攻人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像初婆,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子铺根,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 【Android 自定義View】 [TOC] 自定義View基礎(chǔ) 接觸到一個(gè)類(lèi)访雪,你不太了解他臣缀,如果貿(mào)然翻閱源碼只...
    Rtia閱讀 3,948評(píng)論 1 14
  • 轉(zhuǎn)自:http://www.reibang.com/p/e9d8420b1b9c 自定義View是Android...
    CQ_TYL閱讀 1,837評(píng)論 0 26
  • 6、View的繪制 (1)當(dāng)測(cè)量好一個(gè)View之后脂倦,我們就可以簡(jiǎn)單的重寫(xiě) onDraw()方法蝶押,并在 Canvas...
    b5e7a6386c84閱讀 1,893評(píng)論 0 3
  • 一座荒涼冷落的古園 稀稀落落的葉子 憔悴棋电、枯竭 樹(shù)汁滲漏 疲倦的旅行者 含著一片飄香的玫瑰花瓣 不自覺(jué)地陷入黑暗 ...
    周梓若閱讀 336評(píng)論 0 2
  • 鐵棍山藥是一味珍貴的中藥材,被歷代中醫(yī)學(xué)家所推崇招刨,稱(chēng)贊為長(zhǎng)壽因子沉眶,藥食兼用的良藥佳肴谎倔。作為中藥它可以制成多種丸藥猿推,...
    Angela魏閱讀 663評(píng)論 0 0