首先看下自定义viewfastindex的实现

package cn.yuan.yu.view;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.support.v4.view.MotionEventCompat;import android.util.AttributeSet;import android.util.TypedValue;import android.view.MotionEvent;import android.view.View;import cn.yuan.yu.R;/**  * Created by yukuo on 2016/4/7.  * 这是一个自定义的一个快速索引的自定义的控件  */ public class FastIndexBar extends View {    /**  * 上下文  */  private Context context;    /**  * 宽度  */  private int Width;    /**  * 高度  */  private int Height;    /**  * 字体的颜色  */  private int TextColor;    /**  * 字体大小  */  private int TextSize;    /**  * 控件的背景色  */  private int BackgroundColor;    /**  * 单元格高度  */  private float cellHeight;    private static final String[] WORDS = new 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"};    //这是一个画笔    private Paint paint;    //这是一个索引    int index = -1;    //监听器    private OnLetterChangeListener onLetterChangeListener;    /**  * 字母更新监听  */  public interface OnLetterChangeListener {        /**  * 当手指移动或者按下的时候调用的方法  *  * @param letter  */  void onLetterChange(String letter);        /**  * 当手指离开这个控件的时候调用的方法  */  void onUp();    }    public void setOnLetterChangeListener(            OnLetterChangeListener onLetterChangeListener) {        this.onLetterChangeListener = onLetterChangeListener;    }    public FastIndexBar(Context context, AttributeSet attrs) {        this(context, attrs, 0);        this.context = context;    }    public FastIndexBar(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        this.context = context;        init(attrs, defStyleAttr);    }    /**  * 初始化各种属性  */  private void init(AttributeSet attrs, int defStyleAttr) {        /**  * 获得我们所定义的自定义样式属性  */  TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.FastIndexBar, defStyleAttr, 0);        for (int i = 0; i < typedArray.getIndexCount(); i++) {            int attr = typedArray.getIndex(i);            if (attr == R.styleable.FastIndexBar_BackgroundColor) {                BackgroundColor = typedArray.getColor(attr, Color.WHITE);            } else if (attr == R.styleable.FastIndexBar_TextColor) {                TextColor = typedArray.getColor(attr, Color.BLUE);            } else if (attr == R.styleable.FastIndexBar_TextSize) {                TextSize = typedArray.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 10, getResources().getDisplayMetrics()));            }        }        //释放资源        typedArray.recycle();        /**  * 初始化一个画笔  */  paint = new Paint();        paint.setColor(TextColor);//设置画笔的颜色        paint.setTextSize(TextSize);//设置字体的大小    }    /**  * 绘制  *  * @param canvas  */  @Override    protected void onDraw(Canvas canvas) {        for (int i = 0; i < WORDS.length; i++) {            String text = WORDS[i];            float x = (int) (Width * 0.5f - paint.measureText(text) * 0.5f);            Rect bounds = new Rect();            // 把矩形对象赋值            paint.getTextBounds(text, 0, text.length(), bounds);            int textHeight = bounds.height();            float y = (int) (cellHeight * 0.5f + textHeight * 0.5 + cellHeight                    * i);            // 如果当前绘制的字母和按下的字母索引一样, 用灰色的画笔            //  paint.setColor(i == index ? Color.GRAY : Color.BLACK);            canvas.drawColor(BackgroundColor);            canvas.drawText(text, x, y, paint);        }    }    /**  * 控件的手指触摸事件的监听  *  * @param event  * @return  */  @Override    public boolean onTouchEvent(MotionEvent event) {        float y = -1;        //选择的索引        int currentIndex = -1;        switch (MotionEventCompat.getActionMasked(event)) {            case MotionEvent.ACTION_DOWN://按下的时候                y = event.getY();//获得当时按下的y                currentIndex = (int) (y / cellHeight);                if (currentIndex >= 0 && currentIndex < WORDS.length) {                    // 健壮性处理, 在正常范围内                    if (index != currentIndex) {                        // 字母的索引发生了变化                        if (onLetterChangeListener != null) {                            onLetterChangeListener                                    .onLetterChange(WORDS[currentIndex]);                        }                        index = currentIndex;                    }                }                break;            case MotionEvent.ACTION_MOVE://移动的时候                y = event.getY();                currentIndex = (int) (y / cellHeight);                if (currentIndex >= 0 && currentIndex < WORDS.length) {                    // 健壮性处理, 在正常范围内                    if (index != currentIndex) {                        // 字母的索引发生了变化                        if (onLetterChangeListener != null) {                            onLetterChangeListener                                    .onLetterChange(WORDS[currentIndex]);                        }                        index = currentIndex;                    }                }                break;            case MotionEvent.ACTION_UP://离开的时候                index = -1;                if (onLetterChangeListener != null) {                    onLetterChangeListener                            .onUp();                }                break;        }        invalidate();        return true;    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        //单元格宽度        Width = getMeasuredWidth();        Height = getMeasuredHeight();        //单元格高度        cellHeight = Height * 1.0f / WORDS.length;    }}
布局如何应用呢?如下:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <cn.yuan.yu.view.ElasticListView        android:id="@+id/lv_mylistview"        android:layout_width="match_parent"        android:layout_height="match_parent" />    <cn.yuan.yu.view.FastIndexBar        android:id="@+id/fib_demo"        android:layout_width="30dp"        android:layout_height="280dp"        android:layout_alignParentRight="true"        android:layout_centerVertical="true"        app:TextColor="@color/themecolor"        app:TextSize="9sp" />    <TextView        android:id="@+id/tv_tip"        android:layout_width="120dp"        android:layout_height="120dp"        android:layout_centerInParent="true"        android:background="@drawable/text_bg_tip"        android:gravity="center"        android:textColor="@android:color/white"        android:textSize="100sp"        android:visibility="gone" /></RelativeLayout>
定义这个列表的适配器

package cn.yuan.qi.demomodule.adapter;import android.content.Context;import android.text.TextUtils;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.TextView;import java.util.List;import cn.yuan.qi.R;import cn.yuan.yu.bean.PhoneNumber;/**  * Created by yukuo on 2016/4/12.  */ public class PhoneNumberAdapter extends BaseAdapter {    private List<PhoneNumber> list;    private Context context;    public PhoneNumberAdapter(Context context, List<PhoneNumber> list) {        this.list = list;        this.context = context;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        MyHolder myHolder;        if (convertView == null) {            myHolder = new MyHolder();            convertView = View.inflate(context, R.layout.item_fastindex, null);            myHolder.textViewname = (TextView) convertView.findViewById(R.id.tv_item_phone_name);            myHolder.textViewphone = (TextView) convertView.findViewById(R.id.tv_item_phone_number);            myHolder.index = (TextView) convertView.findViewById(R.id.tv_index);            convertView.setTag(myHolder);        } else {            myHolder = (MyHolder) convertView.getTag();        }        // 进行分组, 比较上一个拼音的首字母和自己是否一致, 如果不一致, 就显示tv_index        String currentLetter = list.get(position).getPinyin();        String indexStr = null;        if (position == 0) {            // 1. 如果是第一位            indexStr = currentLetter;        } else {            // 获取上一个拼音            String preLetter = list.get(position-1).getPinyin();            if (!TextUtils.equals(currentLetter, preLetter)) {                // 2. 当跟上一个不同时, 赋值, 显示                indexStr = currentLetter;            }        }        myHolder.index.setVisibility(indexStr == null ? View.GONE  : View.VISIBLE);        myHolder.index.setText(indexStr == null ? "" : list.get(position).getPinyin());        myHolder.textViewname.setText(list.get(position).getName());        myHolder.textViewphone.setText(list.get(position).getNumber());        return convertView;    }    @Override    public int getCount() {        return list.size();    }    @Override    public Object getItem(int position) {        return null;    }    @Override    public long getItemId(int position) {        return 0;    }    class MyHolder {        TextView textViewname;        TextView textViewphone;        TextView index;    }}
条目布局文件

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <TextView        android:id="@+id/tv_index"        android:layout_width="match_parent"        android:layout_height="20dp"        android:background="@color/themecolor"        android:gravity="center_vertical"        android:paddingLeft="10dp"        android:text="A"        android:textColor="@android:color/white"        android:textSize="15sp" />    <LinearLayout        android:layout_width="match_parent"        android:layout_height="50dp"        android:orientation="horizontal">        <TextView            android:id="@+id/tv_item_phone_name"            android:layout_width="100dp"            android:layout_height="match_parent"            android:layout_marginLeft="15dp"            android:gravity="center_vertical" />        <TextView            android:id="@+id/tv_item_phone_number"            android:layout_width="wrap_content"            android:layout_height="match_parent"            android:layout_marginLeft="50dp"            android:gravity="center_vertical" />    </LinearLayout></LinearLayout>
Activity界面业务代码

package cn.yuan.qi.demomodule.activity;import android.os.Bundle;import android.view.View;import android.widget.TextView;import java.util.Collections;import java.util.Comparator;import java.util.List;import butterknife.Bind;import cn.yuan.qi.R;import cn.yuan.qi.common.activity.BaseActivity;import cn.yuan.qi.common.application.QiApplication;import cn.yuan.qi.demomodule.adapter.PhoneNumberAdapter;import cn.yuan.yu.bean.PhoneNumber;import cn.yuan.yu.utils.GetPhoneData;import cn.yuan.yu.view.ElasticListView;import cn.yuan.yu.view.FastIndexBar;/**  * Created by yukuo on 2016/4/4.  */ public class FastIndexOfActivity extends BaseActivity {    @Bind(R.id.lv_mylistview)    ElasticListView lvMylistview;    @Bind(R.id.fib_demo)    FastIndexBar fibDemo;    @Bind(R.id.tv_tip)    TextView tvTip;    private PhoneNumberAdapter phoneNumberAdapter;    private List<PhoneNumber> lists;    @Override    public void initdata(Bundle extras) {        //     WeekGridAdapter weekGridAdapter = new WeekGridAdapter(this);        fibDemo.setOnLetterChangeListener(new FastIndexBar.OnLetterChangeListener() {            @Override            public void onLetterChange(String letter) {                tvTip.setText(letter);                tvTip.setVisibility(View.VISIBLE);                if (lists != null) {                    for (int i = 0; i < lists.size(); i++) {                        if (letter.equals(lists.get(i).getPinyin())) {                            lvMylistview.setSelection(i);                            return;                        }                    }                }            }            @Override            public void onUp() {                tvTip.setVisibility(View.GONE);            }        });        GetPhoneData.getPhoneNumberData(this, new GetPhoneData.OnLoadSuccessListener() {            @Override            public void onSuccess(final List<PhoneNumber> list) {                QiApplication.mainHandler.post(new Runnable() {                    @Override                    public void run() {                        lists = list;                        // 排序                        Collections.sort(list, new Comparator<PhoneNumber>() {                            @Override                            public int compare(PhoneNumber lhs, PhoneNumber rhs) {                                return lhs.getPinyin().compareToIgnoreCase(rhs.getPinyin());                            }                        });                        phoneNumberAdapter = new PhoneNumberAdapter(FastIndexOfActivity.this, list);                        lvMylistview.setAdapter(phoneNumberAdapter);                    }                });            }            @Override            public void onFailure() {            }        });    }    @Override    public int getContentLayout() {        return R.layout.activity_fastindex;    }}
用到的工具类和实体

package cn.yuan.yu.utils;import android.content.ContentResolver;import android.content.Context;import android.database.Cursor;import android.provider.ContactsContract;import java.util.ArrayList;import java.util.List;import cn.yuan.yu.bean.PhoneNumber;/**  * Created by yukuo on 2016/4/12.  * 这是一个获取手机联系人等信息的工具类  */ public class GetPhoneData {    public interface OnLoadSuccessListener {        void onSuccess(List<PhoneNumber> list);        void onFailure();    }    /**  * 这是一个返回一个联系人信息列表集合的方法  *  * @param context 上下文  * @return  */  public static void getPhoneNumberData(final Context context, final OnLoadSuccessListener onLoadSuccessListener) {        new Thread() {            @Override            public void run() {                List<PhoneNumber> list = new ArrayList<PhoneNumber>();                ContentResolver cr = context.getContentResolver();                Cursor cursor = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);                if (cursor != null) {                    while (cursor.moveToNext()) {                        int PhoneName = cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);                        int phoneNumbe = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);                        PhoneNumber phoneNumber = new PhoneNumber();                        //电话号码                        phoneNumber.setNumber(cursor.getString(phoneNumbe));                        L.i("手机号码", cursor.getString(phoneNumbe));                        //名字                        phoneNumber.setName(cursor.getString(PhoneName));                        L.i("名字", cursor.getString(PhoneName));                        list.add(phoneNumber);                    }                    if (onLoadSuccessListener != null) {                        onLoadSuccessListener.onSuccess(list);                    }                } else {                    if (onLoadSuccessListener != null) {                        onLoadSuccessListener.onFailure();                    }                }            }        }.start();    }}
实体

package cn.yuan.yu.bean;import net.sourceforge.pinyin4j.PinyinHelper;/**  * Created by yukuo on 2016/4/12.  * 这是一个联系人的实体类  */ public class PhoneNumber {    private String number;    private String name;    private String email;    /**  * 这是一个存储每个名字首字母的变量  */  private String pinyin;    public String getNumber() {        return number;    }    public void setNumber(String number) {        this.number = number;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;        this.pinyin = getHeadChar(name);    }    public String getEmail() {        return email;    }    public void setEmail(String email) {        this.email = email;    }    public String getPinyin() {        return pinyin;    }    public void setPinyin(String pinyin) {        this.pinyin = pinyin;    }    /**  * 得到首字母  *  * @param str  * @return  */  public String getHeadChar(String str) {        String convert = "";        char word = str.charAt(0);        String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(word);        if (pinyinArray != null) {            convert += pinyinArray[0].charAt(0);        } else {            convert += word;        }        return convert.toUpperCase();    }}
最后的效果图

图片

选中效果

ok祝小伙伴成功吧


更多相关文章

  1. 实现Android(安卓)ListView 自动加载更多内容
  2. Android实时绘制效果(二)
  3. Android(安卓)自定义View——自定义View控件
  4. Android自定义实现圆形播放进度条
  5. Android绘图之绘制太极图
  6. Android(安卓)之 Fast Scroll 、字母索引栏
  7. LXR 索引Android(安卓)源码
  8. Android(安卓)ListView城市列表,按a-z分组字母索引排序
  9. 最新res索引讲解(drawable、layout、values等目录的分辨率和layou

随机推荐

  1. golang适合web开发吗?
  2. 详解 Go 中的不可变类型
  3. Golang 可以反编译吗?
  4. golang是否值得深入学习?
  5. GO语言中=和:=的区别介绍
  6. Go 语言中的 Context 详解
  7. golang是go语言吗?
  8. go语言中一些字符串操作介绍
  9. go语言通过命令方式生成可执行文件
  10. golang如何获取客户端ip?