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

2018-12-28  本文已影响0人  Dale_Dawson

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

效果图:

gif5新文件.gif

话不多说,直接上代码吧

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;
    }
}

<?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>
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);
    }


}

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

上一篇下一篇

猜你喜欢

热点阅读