Android自訂View之用觀察者模式寫自訂監聽事件以及常用豎直型字母索引欄的寫法

來源:互聯網
上載者:User

Android自訂View之用觀察者模式寫自訂監聽事件以及常用豎直型字母索引欄的寫法
概述:

目前,豎直索引欄還是很流行的,、美團、手機通訊錄等各種常用軟體都要用到它。

Demo

寫一個自訂View,利用觀察者模式,自訂其中的點擊事件。

public class MySlider extends View {    private int width;    private int height;    private float x;    private float y;    private float letterSize;    private int index = -1;    private char[] letters = {'A','B','C','D','E','F','G',            'H','I','J','K','L','M','N','O','P','Q','R','S','T','U',            'V','W','X','Y','Z','#'};    private Paint mPaintText;    private Paint mPaintTextSel;    public MySlider(Context context) {        super(context);    }    //定義一個介面,作為觀察者    public interface OnItemListener{        public void onItemSelected(int index,String content);    }    //觀察者進行通訊的對象    private OnItemListener listener;    public void setOnItemListener(OnItemListener listener){        this.listener = listener;    }    public MySlider(Context context, AttributeSet attrs) {        super(context, attrs);        mPaintText = new Paint();        mPaintText.setColor(Color.BLACK);        //讓字母置中排列        mPaintText.setTextAlign(Paint.Align.CENTER);        mPaintTextSel = new Paint();        mPaintTextSel.setColor(Color.RED);        mPaintTextSel.setTextAlign(Paint.Align.CENTER);    }    public int getIndex() {        return index;    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);        height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);        setMeasuredDimension(width, height);        //setPaintText務必在此寫,因為運行了onMeasure()後才得到height值        mPaintText.setTextSize(height / 27-20);        mPaintTextSel.setTextSize(height / 27-20);    }    /**     *自訂點擊事件     */    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (event.getAction()){            case MotionEvent.ACTION_MOVE:                //此處故意不加break,只要滑動螢幕上字母就會促發點擊事件            case MotionEvent.ACTION_DOWN:                //得到觸碰點的x,y座標                x = event.getX();                y = event.getY();                //根據座標得到點擊的字母                if(x>width-mPaintText.measureText(A)*2){                    index = (int)(y/(height/27));                    //index可能會大於等於27,會造成letters數組下標越界的錯誤,所以此處先作判斷,防止其大於26                    if(index>=27){                        index = 26;                    }                    Log.d(letter, letters[index] + );                    //調用listener對象的onItemSelected()函數,傳入index                    if(listener!=null) {                        listener.onItemSelected(index,letters[index]+);                    }                    //讓主線程重繪                    invalidate();                    return true;                }                break;            default:                break;        }        return super.onTouchEvent(event);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        letterSize = mPaintText.measureText(A);        for(int i=0;i<27;i++){            //根據index值判斷字母是否被點擊到,被點擊的字母是紅色,否則是黑色            if(index==i) {                //將字母依次向下繪出                canvas.drawText(letters[i] + , width - letterSize, height / 27 * (i + 1), mPaintTextSel);            }else{                canvas.drawText(letters[i] + , width - letterSize, height / 27 * (i + 1), mPaintText);            }        }    }}

主活動的寫法:

public class TimerActivity extends Activity {    private TextView mTextViewLetter;    private MySlider mySlider;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_timer);        mTextViewLetter = (TextView) findViewById(R.id.textView_letter);        mySlider = (MySlider) findViewById(R.id.my_slider);        mySlider.setOnItemListener(new MySlider.OnItemListener() {            @Override            public void onItemSelected(int index, String content) {                //如果點擊到字母,就列印該字母                mTextViewLetter.setText(content);            }        });    }}

activity_timer布局:

        

結果示範:

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.