自定義view之仿滴滴選擇人數(shù)的SlideTab拖動(dòng)選擇器

這里只實(shí)現(xiàn)了邏輯掖蛤,如果你需要可以自己把圖片換了杀捻,設(shè)置一下圖片的寬高,我這里只是用了兩個(gè)點(diǎn)表示意思

一款用于選擇的slidebar仿滴滴選擇人數(shù)的效果,自己加了兩個(gè)樣式蚓庭,可拖動(dòng)和點(diǎn)擊(還有一點(diǎn)文字居中的小問(wèn)題致讥,讀者可以自行修改)

還是老規(guī)矩先看效果

1、


gif1.gif

2器赞、

gif2.gif

3垢袱、

gif3.gif

4、特別說(shuō)明要達(dá)到4這種效果港柜,就要把代碼中的那個(gè)兩個(gè)todo的位置代碼按todo處理一下

gif.gif

其實(shí)看過(guò)效果请契,第一感覺就是不難,無(wú)非就是監(jiān)聽手勢(shì)滑動(dòng)繪制view

相信看過(guò)之前我兩篇自定義view的人都知道我自定義view的步驟了

1潘懊、分析需要的自定義屬性
2姚糊、創(chuàng)建類這里繼承view
3、創(chuàng)建attrs定義屬性
4授舟、完成自定義view所擁有的功能
這里我就不再一步一步創(chuàng)建了

先貼上自定義屬性

<declare-styleable name="LSlideView">
        <attr name="round_radius" format="integer"/>
        <!--一下兩個(gè)屬性文章中沒有用到救恨,但是個(gè)人覺得必須要的,分別對(duì)應(yīng)不同狀態(tài)的顏色-->
        <attr name="select_color" format="color"/>
        <attr name="normal_color" format="color"/>

        <attr name="line_width" format="integer"/>
        <!--<attr name="text_width" format="integer"/>-->
        <attr name="margin_top" format="integer"/>
        <!--這兩個(gè)屬性是用來(lái)指定slidebar下面繪制的bitmap释树,文章中我是用的小圓點(diǎn)來(lái)指代的肠槽,但是像滴滴就是用車座位圖標(biāo)來(lái)顯示,記得這四個(gè)屬性是搭配的-->
        <attr name="normal_bitmap" format="reference"/>
        <attr name="select_bitmap" format="reference"/>
       <attr name="bitmap_width" format="integer"/>
        <attr name="bitmap_height" format="integer"/>

        <attr name="stytle_drag_view" format="enum">
            <enum name="FILL" value="1"/>
            <enum name="EMPTY" value="2"/>
        </attr>
        <attr name="is_draw_down_bitmap" format="boolean"/>
    </declare-styleable>

布局文件

<com.example.laer.myapplication.LSlideView
        android:id="@+id/dv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="100px"
        android:clickable="true"http://這里記得加上奢啥,要不然不走onTeach秸仙,暫未明白為啥,知道的可以給我說(shuō)一下
        app:normal_bitmap="@drawable/normal"
        app:select_bitmap="@drawable/select"
        app:round_radius="60"
        app:line_width="20"
        app:margin_top="50"
        app:stytle_drag_view="EMPTY"
        app:is_draw_down_bitmap="false"/>

activity中獲取選中為位置的方法

LSlideView dv = (LSlideView) findViewById(R.id.dv);
        dv.setCallBack(new LSlideView.CallBack() {
            @Override
            public void onCallBack(int postion) {
                Toast.makeText(MainActivity.this,postion+"",Toast.LENGTH_SHORT).show();
            }
        });

下面我就不再具體講view中的代碼了桩盲,直接貼代碼寂纪,如果有需要我說(shuō)的,可以留言


/**
 * 注:使用該控件時(shí)記得在布局文件中添加android:clickable="true"
 * 否則onTeach無(wú)效
 * Created by laer on 2016/10/31.
 */

public class LSlideView extends View {

    private Paint roundPaint;
    private Paint textPaint;
    private Paint line_paint;

    private Bitmap normal_bt;
    private Bitmap select_bt;

    private int widthView;//當(dāng)前view的寬度
    private int r;//圓的半徑
    private int line_width;//線的寬度
    private int margin_round;//每個(gè)圓之間的間距
    private int stopX;//當(dāng)前結(jié)束繪制線的結(jié)束點(diǎn)的x坐標(biāo)
    private int postion;//當(dāng)前選中的位置
    private int normal_color;//默認(rèn)的顏色赌结,暫未使用捞蛋,后期如果需要使用到可以自己添加
    private int select_color;//選中的顏色
    private int width_bitmap;// bitmap的寬
    private int height_bitmap;
    private int margin_top;//下面圖標(biāo)距上面圓的間距
    private int style;//樣式
    private boolean is_draw_down_bitmap;//是否繪制下面的圖片
    private CallBack callBack;

    public void setCallBack(CallBack callBack) {
        this.callBack = callBack;
    }

    public LSlideView(Context context) {
        super(context);
    }

    public LSlideView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context,attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.LSlideView);
        line_width = array.getInt(R.styleable.LSlideView_line_width, 20);
        r = array.getInt(R.styleable.LSlideView_round_radius, 50);
        normal_color=array.getColor(R.styleable.LSlideView_normal_color,Color.GRAY);
        select_color=array.getColor(R.styleable.LSlideView_select_color,Color.BLUE);
        height_bitmap=array.getInt(R.styleable.LSlideView_bitmap_height,40);
        width_bitmap=array.getInt(R.styleable.LSlideView_bitmap_width,60);
        margin_top=array.getInt(R.styleable.LSlideView_margin_top,80);
        style=array.getInt(R.styleable.LSlideView_stytle_drag_view,2);
        is_draw_down_bitmap = array.getBoolean(R.styleable.LSlideView_is_draw_down_bitmap, true);
        BitmapDrawable normal = (BitmapDrawable) array.getDrawable(R.styleable.LSlideView_normal_bitmap);
        BitmapDrawable select_draw = (BitmapDrawable) array.getDrawable(R.styleable.LSlideView_select_bitmap);

        roundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        roundPaint.setStyle(Paint.Style.FILL);

        line_paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        line_paint.setStrokeWidth(line_width);

        textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        textPaint.setFakeBoldText(true);
        textPaint.setTextSize(r);

        normal_bt = Bitmap.createScaledBitmap(normal.getBitmap(), width_bitmap, height_bitmap, true);
        Bitmap select = select_draw.getBitmap();
        select_bt = Bitmap.createScaledBitmap(select,width_bitmap, height_bitmap, true);
        if (height_bitmap==0||width_bitmap==0){
            width_bitmap=2*r;
            height_bitmap=width_bitmap*select.getHeight()/select.getWidth();
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        widthView = MeasureSpec.getSize(widthMeasureSpec);
        margin_round=(widthView-2*r)/4;
        setMeasuredDimension(widthView,r*2+margin_top+height_bitmap);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:

                break;
            case MotionEvent.ACTION_MOVE:
                stopX= (int) event.getX();
                postion = (int) ((event.getX() -r)/ margin_round);
                postInvalidate();
                return true;
            case MotionEvent.ACTION_UP:
                float i = (event.getX() -r)/ margin_round;
                //分離整數(shù)和小數(shù)部分
                int i2= (int) i;//整數(shù)
                if (i2>=3){//防止滑動(dòng)的太遠(yuǎn),導(dǎo)致i2大于3柬姚,導(dǎo)致顯示不正常拟杉,限定了最多到4
                    i2=3;
                }
                float i3=i-i2;//小數(shù)
                if (i3 >0.5){//大于一半,則加1
                    postion=i2+1;
                    stopX=r+margin_round*(i2+1);
                }else{
                    stopX=r+margin_round*i2;
                    postion=i2;
                }
                callBack.onCallBack(postion);
                postInvalidate();
                return true;

        }
        return super.onTouchEvent(event);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
         //繪制默認(rèn)的線
        line_paint.setColor(Color.GRAY);
        canvas.drawLine(r,r,widthView-r,r, line_paint);
       /* 
        *todo 1量承、將這里注釋起來(lái)
       //繪制選中后的藍(lán)色線
        if (postion!=0&&style==1){
            line_paint.setColor(Color.BLUE);
            canvas.drawLine(r,r,stopX,r, line_paint);
        }*/
        roundPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        for (int i = 0; i < 5; i++) {
            //繪制節(jié)點(diǎn)
            float v = textPaint.measureText(i+"");
            int cx = r + margin_round * i;

            if (i==postion&&style==2){//繪制選中后的
                roundPaint.setColor(Color.BLUE);
                canvas.drawCircle(cx,r,r, roundPaint);

                textPaint.setColor(Color.WHITE);
                canvas.drawText(i+"",cx-v/2,r+r/2, textPaint);
                if (is_draw_down_bitmap)
                canvas.drawBitmap(select_bt,cx-width_bitmap/2,2*r+margin_top,line_paint);
            }else if (i==postion&&style==1){//todo 2搬设、將這里的">="改成"=="
                roundPaint.setColor(Color.BLUE);
                canvas.drawCircle(cx,r,r, roundPaint);

                textPaint.setColor(Color.WHITE);
                canvas.drawText(i+"",cx-v/2,r+r/2, textPaint);
                if (is_draw_down_bitmap)
                canvas.drawBitmap(select_bt,cx-width_bitmap/2,2*r+margin_top,line_paint);
            }else {//默認(rèn)的線和圓
                roundPaint.setColor(Color.GRAY);
                canvas.drawCircle(cx,r,r, roundPaint);

                textPaint.setColor(Color.BLACK);
                canvas.drawText(i+"",cx-v/2,r+r/2, textPaint);
                if (is_draw_down_bitmap&&style!=2)
                canvas.drawBitmap(normal_bt,cx-width_bitmap/2,2*r+margin_top,line_paint);
            }
        }
    }
    public interface CallBack{
        void onCallBack(int postion);
    }
}

補(bǔ)充說(shuō)明

將 setClickable(true);//令自己可點(diǎn)擊穴店,從而獲取觸摸事件
加到自定義view中即可獲取事件監(jiān)聽,就可以不在xml中添加clickble

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末拿穴,一起剝皮案震驚了整個(gè)濱河市泣洞,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌贞言,老刑警劉巖斜棚,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異该窗,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)蚤霞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門酗失,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人昧绣,你說(shuō)我怎么就攤上這事规肴。” “怎么了夜畴?”我有些...
    開封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵拖刃,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我贪绘,道長(zhǎng)兑牡,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任税灌,我火速辦了婚禮均函,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘菱涤。我一直安慰自己苞也,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開白布粘秆。 她就那樣靜靜地躺著如迟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪攻走。 梳的紋絲不亂的頭發(fā)上殷勘,一...
    開封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音陋气,去河邊找鬼劳吠。 笑死,一個(gè)胖子當(dāng)著我的面吹牛巩趁,可吹牛的內(nèi)容都是我干的痒玩。 我是一名探鬼主播淳附,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蠢古!你這毒婦竟也來(lái)了奴曙?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤草讶,失蹤者是張志新(化名)和其女友劉穎洽糟,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體堕战,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡坤溃,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了嘱丢。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片薪介。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖越驻,靈堂內(nèi)的尸體忽然破棺而出汁政,到底是詐尸還是另有隱情,我是刑警寧澤缀旁,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布记劈,位于F島的核電站,受9級(jí)特大地震影響并巍,放射性物質(zhì)發(fā)生泄漏目木。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一履澳、第九天 我趴在偏房一處隱蔽的房頂上張望嘶窄。 院中可真熱鬧,春花似錦距贷、人聲如沸柄冲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)现横。三九已至,卻和暖如春阁最,著一層夾襖步出監(jiān)牢的瞬間戒祠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工速种, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留姜盈,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓配阵,卻偏偏與公主長(zhǎng)得像馏颂,于是被迫代替她去往敵國(guó)和親示血。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,152評(píng)論 25 707
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)救拉、插件难审、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,105評(píng)論 4 62
  • 大家好, 我是漢家松鼠cg亿絮,漢家松鼠工作室創(chuàng)始人/CEO告喊,《金庸群俠傳X》、《江湖X》制作人派昧。 上一篇寫了我們團(tuán)隊(duì)...
    漢家松鼠閱讀 1,114評(píng)論 1 2
  • 九重山后是什么蒂萎?一片祥和地淀,一份安穩(wěn),還是一份荊棘岖是?不知如何下筆,不懂該如何讓文字穩(wěn)重实苞,拙筆之下確實(shí)難表達(dá)出心虛的萬(wàn)...
    十二柒柒閱讀 292評(píng)論 0 0
  • 時(shí)間過(guò)得飛快黔牵,《通往財(cái)富自由之路》第二季都要開始了聪轿! 還記得一年前那會(huì),訂閱這個(gè)專欄時(shí)的情景猾浦。當(dāng)時(shí)讀了幾篇笑來(lái)老師...
    一切才剛剛開始閱讀 185評(píng)論 1 1