转载

老猪带你玩转android自定义控件二——自定义索引栏listview

带索引栏的listview,在android开发非常普遍,方便用户进行字母索引,就像微信通讯录这样:

老猪带你玩转android自定义控件二——自定义索引栏listview

今天,我们就从零到一实现这个具有索引栏的listview.

怎么实现这个控件了,我们应当梳理出一个思路。

①首先应当将字母的索引栏继承与一个控件,通过ondraw方法将字母画出来。

②然后我们应该监听这个字母控件的ontouch事件,来判断用户到底是按了那个字母。

③就是实现这个索引栏与listview的联动,就是将listview滑动到按下字母的位置。

大体流程图如下:

老猪带你玩转android自定义控件二——自定义索引栏listview

有了前面铺垫,我们引出本文重头戏——代码。

首先,索引栏这个控件如何将字母绘制在控件上的代码:

     /**      * 侧边栏显示字母      */     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", "#" };     /**      * 绘制列表控件的方法      * 将要绘制的字母以从上到下的顺序绘制在一个指定区域      * 如果是进行选中的字母就进行高亮显示      */     @Override     protected void onDraw(Canvas canvas) {         // TODO Auto-generated method stub         super.onDraw(canvas);         int height = getHeight();// 获取对应高度         int width = getWidth(); // 获取对应宽度         int singleHeight = height / words.length;// 获取每一个字母的高度          for (int i = 0; i < words.length; i++) {             paint.setColor(Color.rgb(33, 65, 98));             // paint.setColor(Color.WHITE);             paint.setTypeface(Typeface.DEFAULT_BOLD);             paint.setAntiAlias(true);             paint.setTextSize(20f);             // 选中的状态             if (isdown) {                 paint.setColor(Color.parseColor("#ffffff"));                 //paint.setFakeBoldText(true);             }             // x坐标等于中间-字符串宽度的一半.             float xPos = width / 2 - paint.measureText(words[i]) / 2;             float yPos = singleHeight * i + singleHeight;             canvas.drawText(words[i], xPos, yPos, paint);             paint.reset();// 重置画笔         }     } 

通过上述的代码,我们可以得出以下的结论:将要绘制的字母以从上到下的顺序绘制在一个指定区域,每个字母的x坐标是一样的,x坐标即为控件宽度一半。如果当前字母选中的话,就高亮显示。思路如图所示:

老猪带你玩转android自定义控件二——自定义索引栏listview

紧接着,就来到第二步,确定用户到底点击是那个字母,代码如下:

 /**      * 处理触摸事件的方法      * 用户按下时候,整个控件背景变化      * 根据按下y坐标 判断究竟用户按下那个字母      * 当前字母高亮显示 将其字母显示listview中央      */     @Override     public boolean dispatchTouchEvent(MotionEvent event) {         int action = event.getAction();         final float y = event.getY();// 点击y坐标         final int oldChoose = choose;         final ITouchingLetterChangedListener listener = onTouchingLetterChangedListener;         final int c = (int) (y / getHeight() * words.length);// 点击y坐标所占总高度的比例*b数组的长度就等于点击b中的个数.         switch (action) {         case MotionEvent.ACTION_UP:             isdown=false;             setBackgroundResource(android.R.color.transparent);             choose = -1;//             invalidate();             if (textViewDialog != null) {                 textViewDialog.setVisibility(View.INVISIBLE);             }             break;          default:             isdown=true;             setBackgroundResource(R.color.sidebar_bg_color);             if (oldChoose != c) {                 if (c >= 0 && c < words.length) {                     if (listener != null) {                         listener.OnTouchingLetterChanged(words[c]);                     }                     if (textViewDialog != null) {                         textViewDialog.setText(words[c]);                         textViewDialog.setVisibility(View.VISIBLE);                     }                      choose = c;                     invalidate();                 }             }             break;         }         return true;     } 

通过上述的代码,我们可以这样总结:当用户按下的时候,整个控件背景发生变化,根据用户按下的y坐标来确定用户究竟是按下那个字母,并且将按下字母显示屏幕的中央,效果图如下:

老猪带你玩转android自定义控件二——自定义索引栏listview

最终,将listview 移动到按下字母相应位置,代码如下:

 /**          * 根据用户点击那个字母将listview移动到相应位置          */         sidebar.setOnTouchingLetterChangedListener(new ITouchingLetterChangedListener() {              @Override             public void OnTouchingLetterChanged(String cString) {                 int position = -1;                 if (cString.length() > 0) {                     position = myAdapter.getPositionForSection(cString                             .charAt(0));                 }                 if (position != -1) {                     listview.setSelection(position);                 } else if (cString.contains("#")) {                     listview.setSelection(0);                 }             }         }); 

连篇累牍说了这么多,控件大功告成的效果为:

老猪带你玩转android自定义控件二——自定义索引栏listview

源代码地址为:

http://pan.baidu.com/s/1dDMDjhR

正文到此结束
Loading...