先上动态效果图

利用一个自定义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); } }); }}若需要了解关于单行文本高度分析详情请看 http://blog.csdn.net/uyy203/article/details/54926753
新闻热点
疑难解答