Android 仿微信通讯录的字母快速检索控件

先上效果图

效果图

右边的就是自定义的View,显示从A到#的字符,按下后中间会显示一个弹窗,以便知道当前按下的是哪个字符,左上角的是接口回调的字符,就是Activity接收到的字符


先看工程目录结构

工程目录结构

AlphaSearchView.java:就是我们要实现的自定义View

bg_corner_black_helftran.xml:弹窗的半透明圆角背景

pop_alphasearch.xml:弹窗的布局文件


接下来看各个文件


1.bg_corner_black_helftran.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="10dp"/>
    <solid android:color="#80000000"/>
</shape>
圆角半径为10dp, 填充颜色为半透明


2.pop_alphasearch.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/tv_text"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:gravity="center"
        android:textColor="@android:color/white"
        android:textSize="35sp"
        android:background="@drawable/bg_corner_black_helftran"/>

</LinearLayout>


3.activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.ffpy.demo.MainActivity"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="hello"
        android:textSize="30sp"
        android:textColor="@android:color/black"/>

    <com.ffpy.demo.AlphaSearchView
        android:id="@+id/alphaSearchView"
        android:layout_width="20dp"
        android:layout_height="match_parent"
        android:layout_alignParentRight="true"/>

</RelativeLayout>

4.AlphaSearchView.java

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.PopupWindow;
import android.widget.TextView;

/**
 * Created by Administrator on 2016/9/3.
 * 通讯录字母检索的自定义控件
 */
public class AlphaSearchView extends View {

    private final int ALPHANUM = 27;    //字符个数
    private final int TEXTSIZE = 30;    //字体大小

    private int itemHeight;                 //每个字符所占的高度
    private OnAlphaClickListener mListener; //回调接口
    private Paint mPaint;                   //画笔
    private PopupWindow pop;                //提示文字的弹窗
    private TextView tv_text;               //弹窗的文字
    private boolean isOnTouch;              //是否已按下

    public AlphaSearchView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setTextSize(TEXTSIZE);
        initPop(context);
    }

    /**
     * 初始化弹窗
     */
    private void initPop(Context context) {
        View view = LayoutInflater.from(context).inflate(R.layout.pop_alphasearch, null);
        pop = new PopupWindow(view);
        pop.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
        pop.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
        tv_text = (TextView) view.findViewById(R.id.tv_text);
    }

    /**
     * 设置监听器
     */
    public void setOnAlphaClickListener(OnAlphaClickListener l){
        mListener = l;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //按下状态有灰色背景,松开状态没有背景
        if (isOnTouch) {
            mPaint.setColor(Color.GRAY);
            //绘制背景
            canvas.drawRect(0, 0, getWidth(), getHeight(), mPaint);
        }

        //字体颜色,按下状态为白色,松开状态为灰色
        if (isOnTouch) {
            mPaint.setColor(Color.WHITE);
        }else {
            mPaint.setColor(Color.BLACK);
        }
        //字体大小
        for (int i = 0; i < ALPHANUM; i++){
            //要画的字符
            Character c;
            if (i == 26) c = '#';
            else c = (char) ('A' + i);

            //获取字符的宽高
            Rect bound = new Rect();
            mPaint.getTextBounds(c.toString(), 0, 1, bound);

            //绘制字符
            canvas.drawText(c.toString(), (getWidth() - bound.width()) / 2, itemHeight * (i + 1) - (itemHeight - bound.height()) / 2, mPaint);
        }
    }

    @Override
   protected void onSizeChanged(int w, int h, int oldw, int oldh) {
     super.onSizeChanged(w, h, oldw, oldh);
     //计算每一个字符所占的高度
     itemHeight = getHeight() / ALPHANUM;
   }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE) {
            isOnTouch = true;
            char c = getOnTouchAlpha((int) event.getY());
            if (c != '\0') {
                //显示弹窗
                showPop(c);
                //回调接口
                if (mListener != null) {
                    mListener.onClick(c);
                }
            }
        }else if (event.getAction() == MotionEvent.ACTION_UP){
            isOnTouch = false;
            //隐藏弹窗
            hidePop();
        }
        invalidate();
        return true;
    }

    /**
     * 显示弹窗
     */
    private void showPop(Character c){
        tv_text.setText(c.toString());
        pop.showAtLocation(this, Gravity.CENTER, 0, 0);
    }

    /**
     * 隐藏弹窗
     */
    private void hidePop(){
        pop.dismiss();
    }

    /**
     * 获取触摸到的字符
     * @param y 相对于控件按下的y坐标
     * @return 对应的字符
     */
    private char getOnTouchAlpha(int y){
        int index = y / itemHeight;
        if (index < 0) return '\0';
        char c;
        if (index < 26){
            c = (char) ('A' + index);
        }else {
            c = '#';
        }
        return c;
    }

    /**
     * 按下的字母改变时回调的接口
     */
    public interface OnAlphaClickListener {
        /**
         * @param c 按下的字母
         */
        void onClick(Character c);
    }
}



5.MainActivity.java

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends Activity {

    private TextView tv;
    private AlphaSearchView alphaSearchView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tv = (TextView) findViewById(R.id.tv);
        alphaSearchView = (AlphaSearchView) findViewById(R.id.alphaSearchView);

        //设置回调监听
        alphaSearchView.setOnAlphaClickListener(new AlphaSearchView.OnAlphaClickListener() {
            @Override
            public void onClick(Character c) {
                tv.setText(c.toString());
            }
        });
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值