一个关于通讯录人员名单按照字母顺序的快速查,其实很简单

1、一般的通讯,右边一个字母菜单,中间一个浮显框,然后就是listView来显示人员的姓名,电话等信息,其实,没有太大的逻辑,自定义字母菜单如下;


package dss.com.contactsector.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ListView;
import android.widget.TextView;

import dss.com.contactsector.R;
import dss.com.contactsector.adapter.ContactAdapter;


public class Sidebar extends View{
   private Paint paint;
   private TextView header;
   private float height;
   private ListView mListView;
   private Context context;
   
   public void setListView(ListView listView){
      mListView = listView;
   }
   

   public Sidebar(Context context, AttributeSet attrs) {
      super(context, attrs);
      this.context = context;
      init();
   }

   private String[] sections = 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 void init(){
      paint = new Paint(Paint.ANTI_ALIAS_FLAG);
      paint.setColor(Color.DKGRAY); //画笔的颜色
      paint.setTextAlign(Align.CENTER); //居中
      //paint.setTextSize(DensityUtil.sp2px(context, 10));
      paint.setTextSize(40);    //大小
   }
   
   //绘制字母菜单
   @Override
   protected void onDraw(Canvas canvas) {
      super.onDraw(canvas);
      //居中字母的文字
      float center = getWidth() / 2;
      //按照屏幕的高度等分每个字母
      height = getHeight() / sections.length;
      //绘制每个字母
      for (int i = sections.length - 1; i > -1; i--) {
         canvas.drawText(sections[i], center, height * (i+1), paint);
      }
   }

   //根据Y的坐标来计算相对字母集合的的索引值
   private int sectionForPoint(float y) {
      int index = (int) (y / height);
      if(index < 0) {
         index = 0;
      }
      if(index > sections.length - 1){
         index = sections.length - 1;
      }
      return index;
   }


   //设置浮现框的字体
   private void setHeaderTextAndscroll(MotionEvent event){
       if (mListView == null) {
              //check the mListView to avoid NPE. but the mListView shouldn't be null
              //need to check the call stack later
          System.out.println("-----------listView为null");
              return;
          }
      String headerString = sections[sectionForPoint(event.getY())];
      System.out.println("-----------点击了" + headerString);
      Log.e("----setHeaderTextAndscroll: --", headerString);
      header.setText(headerString);
      ContactAdapter adapter = (ContactAdapter) mListView.getAdapter();
      String[] adapterSections = (String[]) adapter.getSections();
      try {
         for (int i = adapterSections.length - 1; i > -1; i--) {
            if(adapterSections[i].equals(headerString)){
               String letter = adapterSections[i];
               //根据字母来查找名单的正真的位置
               mListView.setSelection(adapter.getPositionForSection(letter));
               break;
            }
         }
      } catch (Exception e) {
         Log.e("setHeaderTextAndscroll", e.getMessage());
      }
      
   }


   //触摸时间的监听
   @Override
   public boolean onTouchEvent(MotionEvent event) {
      switch (event.getAction()) {
      case MotionEvent.ACTION_DOWN:{
         if(header == null){
            // TODO
            header = (TextView) ((View)getParent()).findViewById(R.id.floating_header);
         }
         setHeaderTextAndscroll(event);
         header.setVisibility(View.VISIBLE);
         setBackgroundResource(R.drawable.sidebar_background_pressed);
         return true;
      }
      case MotionEvent.ACTION_MOVE:{
         setHeaderTextAndscroll(event);
         return true;
      }
      case MotionEvent.ACTION_UP:
         header.setVisibility(View.INVISIBLE);
         setBackgroundColor(Color.TRANSPARENT);
         return true;
      case MotionEvent.ACTION_CANCEL:
         header.setVisibility(View.INVISIBLE);
         setBackgroundColor(Color.TRANSPARENT);
         return true;
      }
      return super.onTouchEvent(event);
   }

}

然后就是 listView中适配器的关于位置查找的逻辑了

package dss.com.contactsector.adapter;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import dss.com.contactsector.R;
import dss.com.contactsector.bean.User;


/**
 * 简单的好友Adapter实现
 * 
 */
public class ContactAdapter extends BaseAdapter {

    private  Context context;
    private  List<User> contactList = new ArrayList<>();
    private List<String> letterList;
    private List<Integer> positionList;
    private Map<Integer, String> letterMap;

    public ContactAdapter(Context context, List<User> contactList){
        this.context = context;
        this.contactList = contactList;
        letterList = new ArrayList<>();
        positionList = new ArrayList<>();
    }
    @Override
    public int getCount() {
        if (contactList == null && contactList.size()==0){
            return 0;
        }
        return contactList.size();
    }

    @Override
    public Object getItem(int i) {
        return contactList.get(i);
    }

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

    @Override
    public View getView(int i, View converView, ViewGroup viewGroup) {
        ViewHolder viewHolder = null;
        if (converView == null){
            converView=View.inflate(context, R.layout.item_contactor_list,null);
            viewHolder = new ViewHolder();
            viewHolder.name= (TextView) converView.findViewById(R.id.name);
            viewHolder.firstLitter = (TextView) converView.findViewById(R.id.firstLitter);
            converView.setTag(viewHolder);
        }else{
            viewHolder = (ViewHolder) converView.getTag();
        }
        //首字母,
        String firstLetter = contactList.get(i).getFirstLetter();
        //入托是第一个条目,首字母必须显示
        if (i==0){
            viewHolder.firstLitter.setVisibility(View.VISIBLE);
            viewHolder.firstLitter.setText(firstLetter);
            viewHolder.name.setText(contactList.get(i).getName());
        }else{
            //如果不是第一个条目,如果首字母和上一个条目的首字母相同,就不显示,不同,就显示
            if (contactList.get(i).getFirstLetter().equals(contactList.get(i-1).getFirstLetter())){
                viewHolder.firstLitter.setVisibility(View.GONE);
                viewHolder.name.setText(contactList.get(i).getName());
            }else{
                viewHolder.firstLitter.setVisibility(View.VISIBLE);
                viewHolder.firstLitter.setText(firstLetter);
                viewHolder.name.setText(contactList.get(i).getName());
            }
        }
        return converView;
    }


    public class ViewHolder{
        public TextView name;
        public TextView firstLitter;
    }

    //将所有的首字母形成一个字母的数组
    public String[] getSections() {
        letterMap = new HashMap<>();
        for (int i = 0;i<contactList.size();i++){
            String letter = contactList.get(i).getFirstLetter();
            if (!letterMap.containsValue(letter)){
                letterMap.put(i,letter);
                letterList.add(letter);
            }
        }
        for (int i = 0; i <letterList.size() ; i++) {
            System.out.print(letterList.get(i) + "");
        }
        return  letterList.toArray(new String[letterList.size()]);
    }

    //根据首字母,来查询在列表中的实际出现的位置
    public int getPositionForSection(String i) {
        for (Map.Entry<Integer, String> entry : letterMap.entrySet()) {
            if (i.equals(entry.getValue())) {
                return entry.getKey();
            }
        }
        return 0;
    }

}

MainActivity的布局文件:相对布局

xml version="1.0" encoding="utf-8"?>
xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="dss.com.contactsector.MainActivity">

            android:id="@+id/contact_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    

            android:id="@+id/side_bar"
        android:layout_alignParentRight="true"
        android:layout_width="20dp"
        android:layout_height="match_parent" />

            android:textSize="20dp"
        android:gravity="center"
        android:text="索引"
        android:textColor="#ff0000"
        android:id="@+id/floating_header"
        android:background="#00ff00"
        android:layout_centerInParent="true"
        android:layout_width="80dp"
        android:layout_height="80dp" />



MainActivity的逻辑;

package dss.com.contactsector;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ListView;

import java.util.ArrayList;
import java.util.List;

import dss.com.contactsector.adapter.ContactAdapter;
import dss.com.contactsector.bean.User;
import dss.com.contactsector.view.Sidebar;

public class MainActivity extends AppCompatActivity {

    private List<User>  contactList = new ArrayList<>();
    private ListView contactListView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        initView();
        initAdapter();
    }

    private void initAdapter() {
        contactListView.setAdapter(new ContactAdapter(this,contactList));
    }

    private void initView() {
        //初始化listView 和  字母菜单
        contactListView = (ListView) findViewById(R.id.contact_list);
        Sidebar menu_bar = (Sidebar) findViewById(R.id.side_bar);
        //一定要将字母菜单和listView进行关联
        menu_bar.setListView(contactListView);
    }

    private void initData() {
        //这里模拟数据,关于数据的排序集合首字母的排序直接使用第三的就好
        for (int i = 0;i <5;i++){
            User user = new User();
            user.setFirstLetter("A");
            user.setName("阿"+ i );
            contactList.add(user);
        }


        for (int i = 0;i <4;i++){
            User user = new User();
            user.setFirstLetter("B");
            user.setName("步"+ i );
            contactList.add(user);
        }

        for (int i = 0;i <4;i++){
            User user = new User();
            user.setFirstLetter("C");
            user.setName("常"+ i );
            contactList.add(user);
        }

        for (int i = 0;i <3;i++){
            User user = new User();
            user.setFirstLetter("H");
            user.setName("胡"+ i );
            contactList.add(user);
        }
        for (int i = 0;i <13;i++){
            User user = new User();
            user.setFirstLetter("L");
            user.setName("陆"+ i );
            contactList.add(user);
        }

        for (int i = 0;i <13;i++){
            User user = new User();
            user.setFirstLetter("K");
            user.setName("柯"+ i );
            contactList.add(user);
        }

        for (int i = 0;i <13;i++){
            User user = new User();
            user.setFirstLetter("W");
            user.setName("吴"+ i );
            contactList.add(user);
        }

        for (int i = 0;i <12;i++){
            User user = new User();
            user.setFirstLetter("Z");
            user.setName("张"+ i );
            contactList.add(user);
        }
    }
}

适配器的布局:

xml version="1.0" encoding="utf-8"?>
xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

            android:id="@+id/firstLitter"
        android:textSize="20dp"
        android:textColor="#ff0000"
        android:background="#00ff00"
        android:paddingLeft="20dp"
        android:gravity="center_vertical"
        android:text="首字母"
        android:layout_width="match_parent"
        android:layout_height="30dp" />


            android:id="@+id/name"
        android:textSize="20dp"
        android:paddingLeft="20dp"
        android:gravity="center_vertical"
        android:text="姓名"
        android:textColor="#000000"
        android:layout_width="match_parent"
        android:layout_height="40dp" />




完工,主要有一个关于集合拼音的排序使用的模拟数据,


你可能感兴趣的:(android)