Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android自定義View之用觀察者模式寫自定義監聽事件以及常用豎直型字母索引欄的寫法

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

編輯:關於Android編程

概述:

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

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布局:



    

    

結果演示:
這裡寫圖片描述

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved