先上效果图
右边的就是自定义的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());
}
});
}
}