原文:https://blog.csdn.net/uyy203/article/details/54912969
先上动态效果图
利用一个自定义View ,和其中的dispatchTouchEvent 拦截触摸事件实现
SideBar.java
package xyz.slideviewgettext;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import java.util.List;
/**
* Created by xyz on 2017/2/5.
*/
public class SideBar extends View {
private List<String> letterList;
private Paint paint;
public SideBar(Context context,List<String> list){
this(context,(AttributeSet) null);
this.letterList=list;
}
public SideBar(Context context, AttributeSet attributeSet){
this(context,attributeSet,0);
}
public SideBar(Context context,AttributeSet attributeSet,int defStyle){
super(context,attributeSet,defStyle);
init();
}
private void init(){
setBackgroundColor(0x000000);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int height=getHeight();//获取view的高度
int width=getWidth();//获取view的宽度
int singleHeight=height/letterList.size();//获取每一个字母所占的高度
int textHight= getFontAboveBaseLineHeight(35);
paint=new Paint();
for(int i=0;i<letterList.size();i++){
paint.setColor(0xff606060);
paint.setTypeface(Typeface.DEFAULT_BOLD);
paint.setAntiAlias(true);
paint.setTextSize(35);
//文字x轴坐标
float xPos=width/2-paint.measureText(letterList.get(i))/2;
//文字y轴坐标
// float yPos=(singleHeight*(i)) + (2*singleHeight/3);
float yPos=(singleHeight*i)+((singleHeight+textHight)/2);
canvas.drawText(letterList.get(i),xPos,yPos,paint);
paint.reset();//重置画笔
}
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
int action=event.getAction();
final float x=event.getX();
final float y=event.getY();
// 点击y坐标所占总高度的比例*b数组的长度就等于点击b中的个数.
final int index=(int)((y/getHeight())*letterList.size());
if(x<0||x>getWidth()||y<0||y>getHeight()) {
action = MotionEvent.ACTION_UP;
}
switch (action) {
case MotionEvent.ACTION_UP:
setBackgroundColor(0x000000);
if (onTouchBarListener != null) {
onTouchBarListener.onTouch(null, -1, false);
}
invalidate();
break;
default:
setBackgroundColor(0xffffffff);
if (onTouchBarListener != null) {
onTouchBarListener.onTouch(letterList.get(index), index, true);
}
invalidate();
break;
}
return true;//要实现触摸式的动态效果,必须返回true,使得事件能够被拦截
}
//获得字体baseLine以上的高度
//若需要了解关于单行文本高度分析详情请看 http://blog.csdn.net/uyy203/article/details/54926753
public int getFontAboveBaseLineHeight(float fontSize)
{
Paint paint = new Paint();
paint.setTextSize(fontSize);
Paint.FontMetrics fm = paint.getFontMetrics();
return (int)(Math.ceil(- fm.ascent));
}
//外部设置列表数据方法,重绘view
public void setLetterList(List<String> list){
this.letterList=list;
invalidate();
}
//外部调用接口,以便让外部获得当前触摸到的字母
private OnTouchBarListener onTouchBarListener;
public interface OnTouchBarListener{
void onTouch(String letter,int pos,boolean state);
}
public void setOnTouchBarLisstener(OnTouchBarListener l){
this.onTouchBarListener=l;
}
}
MainActivity.java
package xyz.slideviewgettext;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class MainActivity extends Activity {
public List<String> letterList;
public static String[] INDEX_STRING = {
"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",
"#"
};
public static String[] Afterstring = {
"1", "2", "3", "4", "5", "6", "7", "8", "9",
"@"
};
private RelativeLayout rlayout;
private static int WC= ViewGroup.LayoutParams.WRAP_CONTENT;
private static int MP=ViewGroup.LayoutParams.MATCH_PARENT;
private SideBar sideBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
// setContentView(R.layout.activity_main);
letterList=new ArrayList<String>();
letterList= Arrays.asList(INDEX_STRING);
//整体布局
rlayout=new RelativeLayout(getBaseContext());
RelativeLayout.LayoutParams rp=new RelativeLayout.LayoutParams(MP,MP);
setContentView(rlayout,rp);
//屏幕中间显示的文本,会将当前触摸到的字母显示出来
final TextView text=new TextView(getBaseContext());
rp=new RelativeLayout.LayoutParams(WC,WC);
rp.addRule(RelativeLayout.CENTER_IN_PARENT);
text.setTextSize(100);
text.setTextColor(0xff606060);
rlayout.addView(text,rp);
//包裹侧边导航栏view的布局
final RelativeLayout sideLayout=new RelativeLayout(getBaseContext());
rp=new RelativeLayout.LayoutParams(80,letterList.size()*60);
rp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
rp.addRule(RelativeLayout.CENTER_VERTICAL);
rlayout.addView(sideLayout,rp);
//包裹侧边导航栏view
sideBar=new SideBar(getBaseContext(),letterList);
rp=new RelativeLayout.LayoutParams(WC,WC);
sideLayout.addView(sideBar,rp);
sideBar.setOnTouchBarLisstener(new SideBar.OnTouchBarListener() {
@Override
public void onTouch(String letter, int pos,boolean state) {
if(state)
text.setText(letter);
else
text.setText("");
}
});
//改变list内容 重绘view
Button button =new Button(getBaseContext());
rp=new RelativeLayout.LayoutParams(WC,WC);
button.setText("点我");
rlayout.addView(button,rp);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
letterList= Arrays.asList(Afterstring);
sideBar.setLetterList(letterList);
}
});
}
}
若需要了解关于单行文本高度分析详情请看 https://www.jianshu.com/p/aab850e29b6c