简单的通讯录实现方法

来源:互联网 发布:uv淘宝论坛 编辑:程序博客网 时间:2024/05/21 06:14

1.AddressAdapter


public class AddressAdapter extends BaseAdapter {
    private Context context;
    private List<Address> addresses;


    private Map<String, Integer> indexMap = new HashMap<>();


    public AddressAdapter(Context context, List<Address> addresses) {
        this.context = context;
        this.addresses = addresses;
    }


    public void setIndex() {
        indexMap.clear();
        for (int i = 0; i < addresses.size(); i++) {
            // 遍历数据,得到首字母
            String index = PinyinUtils.getFirstLetter(addresses.get(i).getName());
            // 如果索引map中不包含这个字母,就添加进索引map,key是字母,value是第一次出现的位置
            if (!indexMap.containsKey(index)) {
                indexMap.put(index, i);
            }
        }
    }


    /**
     * 获取字母在列表中的索引值(第一次出现的位置)
     * @param letter
     * @return
     */
    public int getIndex(String letter) {
        if (!indexMap.containsKey(letter)){
            return -1;
        }
        return indexMap.get(letter);
    }


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


    @Override
    public Object getItem(int position) {
        return addresses.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) {
            holder = new ViewHolder();
            convertView = View.inflate(context, R.layout.item_address, null);
            holder.txtTitle = (TextView) convertView.findViewById(R.id.txt_address_title);
            holder.txtName = (TextView) convertView.findViewById(R.id.txt_address_name);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        // 拿到当前条目
        String str = addresses.get(position).getName();
        // 取当前条目的首字母
        String first = PinyinUtils.getFirstLetter(str);
        if (indexMap.get(first) == position) {
            holder.txtTitle.setVisibility(View.VISIBLE);
            holder.txtTitle.setText(first);
        } else {
            holder.txtTitle.setVisibility(View.GONE);
        }
        holder.txtName.setText(addresses.get(position).getName());
        return convertView;
    }


    class ViewHolder {
        TextView txtTitle;
        TextView txtName;
    }
}

2.

public class AddressFlowAdapter extends BaseAdapter implements StickyListHeadersAdapter {
    private Context context;
    private List<Address> addresses;


    private Map<String, Integer> indexMap = new HashMap<>();


    public AddressFlowAdapter(Context context, List<Address> addresses) {
        this.context = context;
        this.addresses = addresses;
    }


    public void setIndex() {
        indexMap.clear();
        for (int i = 0; i < addresses.size(); i++) {
            // 遍历数据,得到首字母
            String index = PinyinUtils.getFirstLetter(addresses.get(i).getName());
            // 如果索引map中不包含这个字母,就添加进索引map,key是字母,value是第一次出现的位置
            if (!indexMap.containsKey(index)) {
                indexMap.put(index, i);
            }
        }
    }


    /**
     * 获取字母在列表中的索引值(第一次出现的位置)
     * @param letter
     * @return
     */
    public int getIndex(String letter) {
        if (!indexMap.containsKey(letter)){
            return -1;
        }
        return indexMap.get(letter);
    }


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


    @Override
    public Object getItem(int position) {
        return addresses.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) {
            holder = new ViewHolder();
            convertView = View.inflate(context, R.layout.item_address_title, null);
            holder.txtName = (TextView) convertView.findViewById(R.id.txt_address_name);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        holder.txtName.setText(addresses.get(position).getName());
        return convertView;
    }


    @Override
    public View getHeaderView(int position, View convertView, ViewGroup parent) {
        ViewHolderHeader holder = null;
        if (convertView == null) {
            holder = new ViewHolderHeader();
            convertView = View.inflate(context, R.layout.item_address_header, null);
            holder.txtTitle = (TextView) convertView.findViewById(R.id.txt_address_header);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolderHeader) convertView.getTag();
        }
        holder.txtTitle.setText(PinyinUtils.getFirstLetter(addresses.get(position).getName()));
        return convertView;
    }


    @Override
    public long getHeaderId(int position) {
        return PinyinUtils.getFirstLetter(addresses.get(position).getName()).charAt(0);
    }


    class ViewHolder {
        TextView txtName;
    }


    class ViewHolderHeader {
        TextView txtTitle;
    }
}


3.

public class AddressUtil {


    public static class AddressCompartor implements Comparator<Address> {


        @Override
        public int compare(Address o1, Address o2) {
            String o1f = PinyinUtils.getFirstLetter(o1.getName());
            String o2f = PinyinUtils.getFirstLetter(o2.getName());
            if (o1f.equals("#")) {
                return 1;
            } else if (o2f.equals("#")) {
                return -1;
            } else {
                return o1f.compareTo(o2f);
            }
        }
    }
}

4.

public class FlowListActivity extends AppCompatActivity {
    private StickyListHeadersListView lvAddress;
    private SlideBar sbRight;
    private TextView txtLetter;


    private List<Address> addresses;
    private AddressFlowAdapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_flow_list);
        lvAddress = (StickyListHeadersListView) findViewById(R.id.slv_address);
        sbRight = (SlideBar) findViewById(R.id.sb_right);
        txtLetter = (TextView) findViewById(R.id.txt_letter);
        sbRight.setText(txtLetter);


        addresses = Address.getAddresses();
        Collections.sort(addresses, new AddressUtil.AddressCompartor());


        adapter = new AddressFlowAdapter(this, addresses);
        adapter.setIndex();
        lvAddress.setAdapter(adapter);


        // 给SlideBar设置触摸监听事件
        sbRight.setListener(new SlideBar.OnTouchDownListener() {
            @Override
            public void onTouch(String letter) {
                int index = adapter.getIndex(letter);
                if (index != -1) {
                    // listview设置当前的位置
                    lvAddress.setSelection(index);
                }
            }
        });
    }
}

5.

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";


    private ListView lvAddress;
    private SlideBar sbRight;
    private TextView txtLetter;


    private List<Address> addresses;
    private AddressAdapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lvAddress = (ListView) findViewById(R.id.lv_address);
        sbRight = (SlideBar) findViewById(R.id.sb_right);
        txtLetter = (TextView) findViewById(R.id.txt_letter);
        sbRight.setText(txtLetter);


        addresses = Address.getAddresses();
        Collections.sort(addresses, new AddressUtil.AddressCompartor());


        adapter = new AddressAdapter(this, addresses);
        adapter.setIndex();
        lvAddress.setAdapter(adapter);


        // 给SlideBar设置触摸监听事件
        sbRight.setListener(new SlideBar.OnTouchDownListener() {
            @Override
            public void onTouch(String letter) {
                int index = adapter.getIndex(letter);
                if (index != -1) {
                    // listview设置当前的位置
                    lvAddress.setSelection(index);
                }
            }
        });
    }
}

6.

public class PinyinUtils {
    /**
     * 返回首字母,大写
     * @param str
     * @return
     */
    public static String getFirstLetter(String str) {
        if (TextUtils.isEmpty(str)) {
            return "";
        }
        // 得到一个字符串的拼音的大写
        String pinyinStr = getPinyin(str).toUpperCase();
        // 取拼音字符串的第一个字母
//        String first = pinyinStr.substring(0, 1).toLowerCase();
//        if (first.matches("[a-z]")) {
//
//        } else {
//
//        }
        char firstCahr = pinyinStr.charAt(0);
        // 不是A-Z字母
        if (firstCahr > 90 || firstCahr < 65) {
            return "#";
        }else{ // 代表是A-Z
            return String.valueOf(firstCahr);
        }


    }


    /**
     * 得到一个字符串的拼音读音
     *
     * @param chineseStr
     * @return
     */
    public static String getPinyin(String chineseStr) {
        StringBuffer sb = new StringBuffer();
        // 将汉字拆分成一个个的char
        char[] chars = chineseStr.toCharArray();
        // 遍历汉字的每一个char
        for (int i = 0; i < chars.length; i++) {


            try {
                // 汉字的所有读音放在一个pinyins数组
                String[] pinyins = PinyinHelper.toHanyuPinyinStringArray(chars[i], getDefaultFormat());
                if (pinyins == null) {
                    sb.append(chars[i]);
                } else {
                    sb.append(pinyins[0]);
                }
            } catch (BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination) {
                badHanyuPinyinOutputFormatCombination.printStackTrace();
            }
        }
        return sb.toString();
    }


    /**
     * 设置默认的输出格式
     *
     * @return
     */
    public static HanyuPinyinOutputFormat getDefaultFormat() {
        HanyuPinyinOutputFormat outputFormat = new HanyuPinyinOutputFormat();
        // 去除声调
        outputFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        // 小写
        outputFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
        // 包含Unicode特殊字符
        outputFormat.setVCharType(HanyuPinyinVCharType.WITH_U_UNICODE);
        return outputFormat;
    }
}

7.

public class SlideBar extends View {
    private static final String TAG = "SlideBar";


    private String[] letters = {
            "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 OnTouchDownListener listener;


    private TextView textView;


    private int choose = -1;
    private int oldChoose = -1;


    public void setListener(OnTouchDownListener listener) {
        this.listener = listener;
    }


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


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


    public SlideBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    public void setText(TextView textView) {
        this.textView = textView;
    }


    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        int action = event.getAction();
        // 手指触摸的纵坐标
        float y = event.getY();
        // 计算公式,字母的位置 = y*字母的总个数/总高度
        int pos = (int) (y * letters.length / getHeight());
        oldChoose = choose;
        switch (action) {
            case MotionEvent.ACTION_UP: // 手指抬起
                // 把显示字母的textview隐藏
                if (textView != null) {
                    textView.setVisibility(View.INVISIBLE);
                }
                // 按下的位置设置成-1,未选中
                choose = -1;
                // 刷新,重绘
                invalidate();
                break;
            default: // 手指按下和移动
                // 在边界内,也就是在letters范围之内
                if (pos >= 0 && pos < letters.length) {
                    // 按下的时候显示 显示字母的textview,并且把字母设置成我们按下的位置的字母
                    if (textView != null) {
                        textView.setVisibility(VISIBLE);
                        textView.setText(letters[pos]);
                    }
                    // 手指按下和移动的时候把当前选中的字母传出去
                    if (listener != null) {
                        listener.onTouch(letters[pos]);
                    }
                    // 改变当前选中的字母
                    // 优化,只有当当前选中位置和上次选中的位置不同的时候才重绘
                    if (oldChoose != pos){
                        choose = pos;
                        invalidate();
                    }
                }
                break;
        }
        return true;
    }


    @Override
    protected void onDraw(Canvas canvas) {
        Log.i(TAG, "onDraw: " + new Date(System.currentTimeMillis()));
        super.onDraw(canvas);
        int width = getWidth();
        int height = getHeight();
        int singleHeight = height / letters.length;


        Paint bgPaint = new Paint();
        bgPaint.setColor(Color.parseColor("#44000000"));
        bgPaint.setAntiAlias(true);
        canvas.drawPaint(bgPaint);
        bgPaint.reset();


        for (int i = 0; i < letters.length; i++) {
            Paint paint = new Paint();
            paint.setColor(Color.parseColor("#FFFFFF"));
            paint.setTextSize(30);
            // 字符占的宽度
            float f = paint.measureText(letters[i]);
            float xPos = width / 2 - f / 2;
            float yPos = singleHeight * (i + 1);
            if (i == choose) {
                paint.setColor(Color.parseColor("#FF0000"));
                paint.setFakeBoldText(true);
            }
            canvas.drawText(letters[i], xPos, yPos, paint);
            paint.reset();
        }
    }


    interface OnTouchDownListener {
        void onTouch(String letter);
    }
}


8.

public class Address {
    private int id;
    private String name;


    public int getId() {
        return id;
    }


    public void setId(int id) {
        this.id = id;
    }


    public String getName() {
        return name;
    }


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




    public static List<Address> getAddresses() {
        List<String> list = getAllMember();
        List<Address> addresses = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            Address address = new Address();
            address.setId(i);
            address.setName(list.get(i));
            addresses.add(address);
        }
        return addresses;
    }


    public static List<String> getAllMember() {
        List<String> addresses = new ArrayList<>();
        addresses.add("尹aaa");
        return addresses;
    }
}
原创粉丝点击