接到一个需求就是通过首字母的选择达到一个筛选的效果,经研究决定效果仿照手机通讯录的选择,可以点击,可以滑动选择,找了很多资料都是竖向的,用于手机上的,我们的产品是横屏设备,需要横向的,鉴于功能简单,自己写一个,可以用于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);
}
}
以上是所有横向字母选择控件的实现代码,希望能够帮助到有需要的人。
网友评论