美文网首页
横向字母选择控件(类似手机通讯录)

横向字母选择控件(类似手机通讯录)

作者: Dale_Dawson | 来源:发表于2018-12-28 17:40 被阅读0次

    接到一个需求就是通过首字母的选择达到一个筛选的效果,经研究决定效果仿照手机通讯录的选择,可以点击,可以滑动选择,找了很多资料都是竖向的,用于手机上的,我们的产品是横屏设备,需要横向的,鉴于功能简单,自己写一个,可以用于TV端或者是HD设备的应用。

    效果图:

    gif5新文件.gif

    话不多说,直接上代码吧

    • 以下代码是自定义View的代码
    package com.example.dell.test;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Rect;
    import android.graphics.Typeface;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.View;
    
    /**
     * 创 建 人:zhengquan
     * 创建日期:2018/10/10
     * 修改时间:
     * 修改备注:
     */
    public class WordsNavigation extends View {
        /*绘制的列表导航字母*/
        private String words[] = {"全", "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 wordsPaint;
        /*字母背景画笔*/
        private Paint bgPaint;
        /*每一个字母的宽度*/
        private int itemWidth;
        /*每一个字母的高度*/
        private int itemHeight;
        /*手指按下的字母索引*/
        private int touchIndex = 0;
        /*手指按下的字母改变接口*/
        private onWordsChangeListener listener;
        private onWordsChooseListener chooseListener;
    
        public WordsNavigation(Context context) {
            super(context);
            init();
        }
    
        public WordsNavigation(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
    
        /**
         * 初始化画笔
         */
        private void init() {
            wordsPaint = new Paint();
            wordsPaint.setColor(Color.parseColor("#F7F7F7"));
            wordsPaint.setAntiAlias(true);
            wordsPaint.setTextSize(20);
            wordsPaint.setTypeface(Typeface.DEFAULT_BOLD);
    
            bgPaint = new Paint();
            bgPaint.setAntiAlias(true);
            bgPaint.setColor(Color.parseColor("#1dcdef"));
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            int width = getMeasuredWidth();
    
            itemWidth = width / 28;
            //使得边距好看一些
            int height = getMeasuredHeight();
            itemHeight = height;
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            for (int i = 0; i < words.length; i++) {
                //获取文字的宽高
                Rect rect = new Rect();
                wordsPaint.getTextBounds(words[i], 0, 1, rect);
                int wordWidth = rect.width();
                int wordHeight = rect.height();
                //判断是不是我们按下的当前字母
                if (touchIndex == i) {
                    //绘制文字圆形背景
                    canvas.drawCircle(itemWidth / 2 + i * itemWidth + wordWidth / 2, itemHeight / 2, 20, bgPaint);
                    wordsPaint.setColor(Color.WHITE);
                } else {
                    wordsPaint.setColor(Color.GRAY);
                }
                //绘制字母
                float wordX = itemWidth / 2 + i * itemWidth;
                float wordY = itemHeight / 2 + wordHeight / 2;
                canvas.drawText(words[i], wordX, wordY, wordsPaint);
            }
        }
    
        /**
         * 当手指触摸按下的时候改变字母背景颜色
         */
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                case MotionEvent.ACTION_MOVE:
                    float x = event.getX();
    //                float y = event.getY();
                    //获得我们按下的是那个索引(字母)
                    int index = (int) (x / itemWidth);
                    if (index != touchIndex)
                        touchIndex = index;
                    //防止数组越界
                    if (listener != null && 0 <= touchIndex && touchIndex <= words.length - 1) {
                        //回调按下的字母
                        listener.wordsChange(words[touchIndex]);
                    }
                    invalidate();
                    break;
                case MotionEvent.ACTION_UP:
                    if (chooseListener != null && 0 <= touchIndex && touchIndex <= words.length - 1) {
                        //回调按下的字母
                        chooseListener.wordsChoose(words[touchIndex]);
                    }
                    break;
            }
            return true;
        }
    
        /*设置当前按下的是那个字母*/
        public void setTouchIndex(String word) {
            for (int i = 0; i < words.length; i++) {
                if (words[i].equals(word)) {
                    touchIndex = i;
                    invalidate();
                    return;
                }
            }
        }
    
        /*手指按下了哪个字母的回调接口*/
        public interface onWordsChangeListener {
            void wordsChange(String words);
        }
    
        /*设置手指按下字母改变监听*/
        public void setOnWordsChangeListener(onWordsChangeListener listener) {
            this.listener = listener;
        }
    
        public interface onWordsChooseListener {
            void wordsChoose(String words);
        }
    
        public void setChooseListener(onWordsChooseListener chooseListener) {
            this.chooseListener = chooseListener;
        }
    }
    
    
    • 在Activity.xml中引用
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <com.example.dell.test.WordsNavigation
            android:id="@+id/words"
            android:layout_marginRight="100dp"
            android:layout_marginLeft="100dp"
            android:layout_width="match_parent"
            android:layout_height="50dp" />
    
        <TextView
            android:id="@+id/tv"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:gravity="center"
            android:textSize="40sp"
            android:visibility="gone" />
    </RelativeLayout>
    
    • 在Activity中的使用
    package com.example.dell.test;
    
    import android.os.Bundle;
    import android.os.Handler;
    import android.support.annotation.Nullable;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.TextView;
    import android.widget.Toast;
    
    /**
     * 创 建 人:zhengquan
     * 创建日期:2018/10/10
     * 修改时间:
     * 修改备注:
     */
    public class WordsChooseTest extends AppCompatActivity implements
            WordsNavigation.onWordsChangeListener, WordsNavigation.onWordsChooseListener {
        private WordsNavigation word;
        private Handler handler;
        private TextView tv;
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.wordchoosetest);
            tv = (TextView) findViewById(R.id.tv);
            word = (WordsNavigation) findViewById(R.id.words);
            handler = new Handler();
            word.setOnWordsChangeListener(this);
            word.setChooseListener(this);
        }
    
        @Override
        public void wordsChange(String words) {
            updateWord(words);
        }
    
        @Override
        public void wordsChoose(String words) {
            Toast.makeText(this, "选中了" + words, Toast.LENGTH_SHORT).show();
        }
    
        /**
         * 更新中央的字母提示
         *
         * @param words 首字母
         */
        private void updateWord(String words) {
            tv.setText(words);
            tv.setVisibility(View.VISIBLE);
            //清空之前的所有消息
            handler.removeCallbacksAndMessages(null);
            //1s后让tv隐藏
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    tv.setVisibility(View.GONE);
                }
            }, 500);
        }
    
    
    }
    
    

    以上是所有横向字母选择控件的实现代码,希望能够帮助到有需要的人。

    相关文章

      网友评论

          本文标题:横向字母选择控件(类似手机通讯录)

          本文链接:https://www.haomeiwen.com/subject/pfdelqtx.html