Android 通讯录的实现,根据拼音首字母快速索引到名字

本文介绍了一种在Android应用中实现拼音首字母导航的方法。通过自定义View展示右侧的名字首字母,结合ListView实现快速定位。文章详细展示了从布局设计到JavaBean创建的全过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

导入依赖,或者自行百度下载jar包 compile 'com.belerweb:pinyin4j:2.5.0'

一、创建布局

<?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">

    <ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:scrollbars="none"></ListView>

    <com.test.tong.CustomView
        android:id="@+id/customView"
        android:layout_width="30dp"
        android:layout_height="match_parent"
        android:layout_marginBottom="5dp"
        android:layout_marginTop="5dp" />

</LinearLayout>


listView中的Item的布局

<?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/item_word"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#c5bebe"
        android:padding="5dp"
        android:textSize="25sp" />

    <TextView
        android:id="@+id/item_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="5dp"
        android:textSize="20sp" />

</LinearLayout>

二、在ManiActivity中模拟人名,查找控件,设置适配器和一些监听等操作

public class MainActivity extends AppCompatActivity {
    String[] NAMES = new String[]{"宋江", "卢俊义", "吴用",
            "公孙胜", "关胜", "林冲", "秦明", "呼延灼", "花荣", "柴进", "李应", "朱仝", "鲁智深",
            "武松", "董平", "张清", "杨志", "徐宁", "索超", "戴宗", "刘唐", "李逵", "史进", "穆弘",
            "雷横", "李俊", "阮小二", "张横", "阮小五", "张顺", "阮小七", "杨雄", "石秀", "解珍",
            "解宝", "燕青", "朱武", "黄信", "孙立", "宣赞", "郝思文", "韩滔", "彭玘", "单廷珪",
            "魏定国", "萧让", "裴宣", "欧鹏", "邓飞", "燕顺", "杨林", "凌振", "蒋敬", "吕方",
            "郭 盛", "安道全", "皇甫端", "王英", "扈三娘", "鲍旭", "樊瑞", "孔明", "孔亮", "项充",
            "李衮", "金大坚", "马麟", "童威", "童猛", "孟康", "侯健", "陈达", "杨春", "郑天寿",
            "陶宗旺", "宋清", "乐和", "龚旺", "丁得孙", "穆春", "曹正", "宋万", "杜迁", "薛永", "施恩",
            "周通", "李忠", "杜兴", "汤隆", "邹渊", "邹润", "朱富", "朱贵", "蔡福", "蔡庆", "李立",
            "李云", "焦挺", "石勇", "孙新", "顾大嫂", "张青", "孙二娘", "王定六", "郁保四", "白胜",
            "时迁", "段景柱", "易宸锋"};
    
    private ListView listview;
    private CustomView custom;
    private ArrayList<person> list;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listview = (ListView) findViewById(R.id.listview);

        custom = (CustomView) findViewById(R.id.customView);
        list = new ArrayList<>();
        for (int i = 0; i < NAMES.length; i++) {
            list.add(new person(NAMES[i]));
        }
        //设置适配器
        listview.setAdapter(new MyAdaper(list, this));
        //对list集合中的首字母进行排序
        Collections.sort(list, new Comparator<person>() {
            @Override
            public int compare(person o1, person o2) {
                return o1.getHanderWord().compareTo(o2.getHanderWord());
            }
        });

        //自定义接口回调,拿到你点击的拼音导航
        custom.getDownData(new CustomView.DownData() {
            @Override
            public void DownData(String str) {
                //循环判断点击的拼音导航栏和集合中姓名的首字母,如果相同Listview就跳转显示
                for (int i = 0; i < list.size(); i++) {
                    if (list.get(i).getHanderWord().equals(str)) {
                        listview.setSelection(i);
                        break;//此处记得一定要停止循环,否则会下标错乱
                    }
                }
            }
        });
    }
}

三、ListView的适配器

public class MyAdaper extends BaseAdapter {
    private List<person> list;
    private Context context;

    public MyAdaper(List<person> list, Context context) {
        this.list = list;
        this.context = context;
    }

    @Override
    public int getCount() {
        return list.size();
    }

    @Override
    public Object getItem(int position) {
        return list.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView == null) {
            convertView = View.inflate(context, R.layout.item, null);
            holder = new ViewHolder();
            holder.word = (TextView) convertView.findViewById(R.id.item_word);
            holder.name = (TextView) convertView.findViewById(R.id.item_name);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        String handerWord = list.get(position).getHanderWord();
        holder.word.setText(handerWord);//显示首字母导航,A,B,C...
        holder.name.setText(list.get(position).getName());//显示姓名
        //第一个字母显示
        if (position == 0) {
            holder.word.setVisibility(View.VISIBLE);
        } else {
            //然后判断当前姓名的首字母和上一个首字母是否相同,如果相同字母导航条就影藏,否则就显示
            if (handerWord.equals(list.get(position - 1).getHanderWord())) {
                holder.word.setVisibility(View.GONE);
            } else {
                holder.word.setVisibility(View.VISIBLE);
            }
        }
        return convertView;
    }

    class ViewHolder {
        TextView word;
        TextView name;
    }
}

 四、自定义View展示右侧的名字首字母

public class CustomView extends View {
    public static String[] b = {"#", "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"};
    Paint paint = new Paint();

    public CustomView(Context context) {
        super(context);
    }

    public CustomView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //计算每一个字母的高度,总告诉除以字母集合的高度就可以
        int height = (getHeight()) / b.length;
        for (int i = 0; i < b.length; i++) {
            paint.setColor(Color.parseColor("#ff0000"));
            paint.setAntiAlias(true);//设置抗锯齿
            //设置文字大小
            paint.setTextSize(40);
            //设置字体加粗
            paint.setTypeface(Typeface.DEFAULT_BOLD);
            //计算每一个字母VIew的x轴坐标
            float paintX = getWidth() / 2 - paint.measureText(b[i]) / 2;
            //计算每一个字母的高度
            int paintY = height * i + height;
            //绘画出来这个TextView
            canvas.drawText(b[i], paintX, paintY, paint);
            //画完一个以后重置画笔
            paint.reset();
        }
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                int down = (int) (event.getY() / getHeight() * b.length);
                if (down >= 0 && down < b.length) {
                    downData.DownData(b[down]);
                }
                break;
            case MotionEvent.ACTION_MOVE:
                int move = (int) (event.getY() / getHeight() * b.length);
                if (move >= 0 && move < b.length) {
                    downData.DownData(b[move]);
                }
                break;
        }
        return true;
    }

    private DownData downData;

    public void getDownData(DownData downData) {
        this.downData = downData;
    }

    public interface DownData {
        void DownData(String str);
    }
}

 五、创建JavaBean来保存得到的姓名的拼音和拼音的首字母

 
public class person {
    private String name;
    private String pinyin;
    private String handerWord;

    public person(String name) {
        this.name = name;
        char c = name.charAt(0);//拿到姓名的第一个汉字
        this.pinyin = PinyinHelper.toHanyuPinyinStringArray(c)[0];//拿到名字的第一个汉字的拼音
        this.handerWord = pinyin.substring(0, 1).toUpperCase();//汉字拼音的首字母,变成大写
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPinyin() {
        return pinyin;
    }

    public void setPinyin(String pinyin) {
        this.pinyin = pinyin;
    }

    public String getHanderWord() {
        return handerWord;
    }

    public void setHanderWord(String handerWord) {
        this.handerWord = handerWord;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值