Android用來替代RatingBar的自定義ImageRatingView

項目地址:https://github.com/qingtenglv/ImageRatingView
因為android自帶的RatingBar用起來不是很方便泣洞,于是決定自己寫一個替代品。歡迎大家去github issue奠蹬。

控件介紹:

示意圖
<declare-styleable name="ImageRatingView">
        //設(shè)置評分最大值
        <attr name="maxCount" format="integer" />  
         //設(shè)置評分之間的跨度哮笆,示意圖中為0.5
        <attr name="minStep" format="float" />      
        //設(shè)置評分時的圖片 
        <attr name="frontImage" format="reference"/>   
        //設(shè)置未評分的圖片(需和評分的圖片等寬等高)
        <attr name="backImage" format="reference"/>   
        //圖片之間的間隔
        <attr name="spanSize" format="dimension"/>    
        //默認(rèn)評分
        <attr name="rating" format="float"/>       
        //是否可觸摸評分
        <attr name="touchable" format="boolean"/>    
        //設(shè)定圖片的寬(layout_width設(shè)置為wrap_content即可)
        <attr name="imageWidth" format="dimension"/>   
        //設(shè)定圖片的高(layout_height設(shè)置為wrap_content即可)   
        <attr name="imageHeight" format="dimension"/>  
    </declare-styleable>

在代碼中支持設(shè)定默認(rèn)評分以及獲取評分来颤,還可以通過設(shè)置OnRatingChangedListener來監(jiān)聽評分的變化。

基本思路:

利用canvas.drawBitmap(bitmap,src,dst,paint)來繪制評分的圖標(biāo)稠肘。照圖上來講分三部分進(jìn)行繪制:①繪制前三個黃色的星星福铅、②繪制后面三個白色的星星、③第四個星星單獨繪制项阴。

代碼實現(xiàn):

  • 繪制前三個黃色的星星
private void drawFront(Canvas canvas) {
        //src是指圖片要顯示的部分滑黔,這里為顯示整個星星。
        Rect src = new Rect(0, 0, mFront.getWidth(), mFront.getHeight());
        for (int i = 0; i < (int) mRating; i++) {
            int left = i * (mBitmapDstWidth + mSpanSize);
            int right = (i + 1) * mBitmapDstWidth + i * mSpanSize;
            //dst指圖片在view中顯示的位置,這里動態(tài)計算出每個星星的坐標(biāo)位置略荡。
            Rect dst = new Rect(left, 0, right, mBitmapDstHeight);
            canvas.drawBitmap(mFront, src, dst, null);
        }
    }
  • 繪制后三個白色的星星
private void drawBack(Canvas canvas) {
        Rect src = new Rect(0, 0, mFront.getWidth(), mFront.getHeight());
        //和繪制前三個的主要區(qū)別是這里的起始值不同
        for (int i = (int) (mRating + 1); i < mMaxCount; i++) {
            //mBitmapDstWidth是圖片指定的寬度
            int left = i * (mBitmapDstWidth + mSpanSize);
            int right = (i + 1) * mBitmapDstWidth + i * mSpanSize;
            Rect dst = new Rect(left, 0, right, mBitmapDstHeight);
            canvas.drawBitmap(mBack, src, dst, null);
         }
     }
  • 繪制第四個星星
private void drawLastFront(Canvas canvas) {
        //先畫front部分即黃色的部分
        //rating小數(shù)點前的值色查。
        int rating = (int) mRating;
        //算出rating小數(shù)點后的值,圖中實例為0.5
        float frontPart = mRating - rating;
        int frontWidth = (int) (frontPart * mFront.getWidth());
        //這里src的寬度就是圖片的一半
        Rect srcFront = new Rect(0, 0, frontWidth, mFront.getHeight());
        //位置的起始值和之前的一樣
        int leftFront = rating * (mBitmapDstWidth + mSpanSize);
        //區(qū)別在結(jié)束值撞芍,按照圖中實例來理解就是3.5*圖片的寬度+3*圖片之間的間隔
        int rightFront = (int) (mRating* mBitmapDstWidth + rating * mSpanSize);
        Rect dstFront = new Rect(leftFront, 0, rightFront, mBitmapDstHeight);
        canvas.drawBitmap(mFront, srcFront, dstFront, null);

        //back部分即白色的部分
        int backWidth = (int) (frontPart * mFront.getWidth());
        Rect srcBack = new Rect(backWidth, 0, mFront.getWidth(), mFront.getHeight());
        //位置的起始值即剛才畫前半部分的結(jié)束值
        int leftBack = (int) (mRating * mBitmapDstWidth + rating * mSpanSize);
        int rightBack = (rating + 1) * mBitmapDstWidth + rating * mSpanSize;
        Rect dstBack = new Rect(leftBack, 0, rightBack, mBitmapDstHeight);
        canvas.drawBitmap(mBack, srcBack, dstBack, null);
    }

其他細(xì)節(jié):

因為本控件支持設(shè)定最小評分的跨度,例如設(shè)置step為0.5跨扮,如果這時傳進(jìn)來3.3分序无,就要四舍五入到3.5。代碼如下:

 private void correctedRatingValue() {
        if (mRating > mMaxCount) {
            mRating = mMaxCount;
        } else if (mRating < 0) {
            mRating = 0;
        }
        //最后一個跨度 進(jìn)行四舍五入的判斷
        float after = mRating % mMinStep > mMinStep / 2 ? mMinStep : 0;
        //除去最后個跨度
        float front = mRating - mRating % mMinStep;
        mRating = after +front;
    }

但在觸摸控件評分時上面的算法就不能用了衡创,舉個例子例如我觸摸得到的評分是3.1帝嗡,那么按照上面的算法會得到3分,最后就顯示為3個星星璃氢。這樣顯示就很怪異哟玷,因為正常情況你的手指觸摸在了星星上就表示這個星星會亮,因此這時候要換一種算法:

 private void correctedRatingValueForTouch() {
        if (mRating % mMinStep == 0)
            return;
        mRating = mRating - mRating % mMinStep + mMinStep;
    }

最后

歡迎大家使用一也,有問題可以在github或者簡書留言巢寡!謝謝

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市椰苟,隨后出現(xiàn)的幾起案子抑月,更是在濱河造成了極大的恐慌,老刑警劉巖舆蝴,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谦絮,死亡現(xiàn)場離奇詭異,居然都是意外死亡洁仗,警方通過查閱死者的電腦和手機(jī)层皱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赠潦,“玉大人叫胖,你說我怎么就攤上這事∷拢” “怎么了臭家?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長方淤。 經(jīng)常有香客問我钉赁,道長,這世上最難降的妖魔是什么携茂? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任你踩,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘带膜。我一直安慰自己吩谦,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布膝藕。 她就那樣靜靜地躺著式廷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪芭挽。 梳的紋絲不亂的頭發(fā)上滑废,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天,我揣著相機(jī)與錄音袜爪,去河邊找鬼蠕趁。 笑死,一個胖子當(dāng)著我的面吹牛辛馆,可吹牛的內(nèi)容都是我干的俺陋。 我是一名探鬼主播,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼昙篙,長吁一口氣:“原來是場噩夢啊……” “哼腊状!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起苔可,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤寿酌,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后硕蛹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體醇疼,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年法焰,在試婚紗的時候發(fā)現(xiàn)自己被綠了秧荆。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡埃仪,死狀恐怖乙濒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情卵蛉,我是刑警寧澤颁股,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站傻丝,受9級特大地震影響甘有,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜葡缰,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一亏掀、第九天 我趴在偏房一處隱蔽的房頂上張望忱反。 院中可真熱鬧,春花似錦滤愕、人聲如沸温算。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽注竿。三九已至,卻和暖如春魂贬,著一層夾襖步出監(jiān)牢的瞬間巩割,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工随橘, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人锦庸。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓机蔗,卻偏偏與公主長得像,于是被迫代替她去往敵國和親甘萧。 傳聞我的和親對象是個殘疾皇子萝嘁,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,700評論 2 354

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