通讯录列表

因为项目需求通讯录样式的列表

1.带有模糊搜索

2.带有字母索引

                                                 

思路:首先是定义一个右侧的导航条母,然后是显示字母的list view 最后添加搜索内容

定义一个右侧导航条目

/**
 * Created by wjs on 2017/11/7.
 * 右侧的导航栏
 */
public class SideBar extends View {
    private Paint paint = new Paint();
    private int height,width;// 获取对应高度.宽度
    private int singleHeight;// 获取每一个字母的高度
    private int choose = -1;// 选中
    private int oldChoose = choose;
    private String[] index_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 int index_y;
    private float y;
    private TextView mTextDialog;
    // 触摸事件
    private OnTouchChangedListener onTouchChanged;

    public void setTextView(TextView mTextDialog) {
        this.mTextDialog = mTextDialog;
    }
    public SideBar(Context context) {
        super(context);
    }

    public SideBar(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SideBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        height = getHeight();
        width = getWidth();
        singleHeight = height / index_string.length;
        for (int i = 0; i < index_string.length; i++){
            paint.setColor(Color.rgb(33, 65, 98));//给画笔设置颜色值
            paint.setTypeface(Typeface.DEFAULT_BOLD);//
            paint.setAntiAlias(true);//设置画笔是否抗锯齿
            paint.setTextSize(20);
            // 选中的状态
            if (i == choose) {
                paint.setColor(Color.parseColor("#3399ff"));
                paint.setFakeBoldText(true);
            }
            // x坐标等于中间-字符串宽度的一半.
            float xPos = width / 2 - paint.measureText(index_string[i]) / 2;
            //y坐标等于n+1个字母的高度
            float yPos = singleHeight * i + singleHeight;
            canvas.drawText(index_string[i], xPos,yPos ,paint);
            paint.reset();// 重置画笔
        }

    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        OnTouchChangedListener listener = onTouchChanged;
        // 点击y坐标
        y = event.getY();
        // 点击y坐标所占总高度的比例*b数组的长度就等于点击b中的个数.
        index_y = (int) (y / getHeight() * index_string.length);
        switch (event.getAction()){
            case MotionEvent.ACTION_UP:
                setBackgroundDrawable(new ColorDrawable(0x00000000));
                choose = -1;//
                invalidate();
                if (mTextDialog != null) {
                    mTextDialog.setVisibility(View.INVISIBLE);
                }
            break;
            default:
                // 设置右侧字母列表[A,B,C,D,E....]的背景颜色
                setBackgroundResource(R.drawable.sidebar_background);
                if (oldChoose != index_y) {
                    if (index_y >= 0 && index_y < index_string.length) {
                        if (listener != null) {
                            listener.onTouchChanged(index_string[index_y]);
                        }
                        if (mTextDialog != null) {
                            mTextDialog.setText(index_string[index_y]);
                            mTextDialog.setVisibility(View.VISIBLE);
                        }

                        choose = index_y;
                        invalidate();
                    }
                }
                break;
        }

        return true;
    }
    /**
     * 向外公开的方法
     *
     * @param onTouchChanged
     */
    public void setOnTouchingLetterChangedListener(OnTouchChangedListener onTouchChanged) {
        this.onTouchChanged = onTouchChanged;
    }
    /**
     * 接口
     *
     * @author coder
     *
     */

    public interface OnTouchChangedListener {
        public void onTouchChanged(String s);
    }
}

list view不用定义就要list view就好。adapter需要处理一下

/**
 * Created by wjs on 2017/11/7.
 * 人名
 */
public class SearchAdapter extends BaseAdapter {
    private List<nameData.ListEntity> list = null;
    private Context context;

    public SearchAdapter(Context context, List<nameData.ListEntity> list) {
        this.context = context;
        this.list = list;
    }
    /**
     * 当ListView数据发生变化时,调用此方法来更新ListView
     *
     * @param list
     */
    public void updateListView(List<nameData.ListEntity> list) {
        this.list = list;
        notifyDataSetChanged();
    }
    @Override
    public int getCount() {
        if (list.size() > 0) {
            return list.size();
        } else {
            return 0;
        }

    }

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

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

    @Override
    public View getView(int position, View view, ViewGroup viewGroup) {
        ViewHolder viewHolder = null;

        if (view == null) {
            viewHolder = new ViewHolder();
            view = LayoutInflater.from(context).inflate(R.layout.item_listview, viewGroup, false);
            viewHolder.name = (TextView) view.findViewById(R.id.name);
            viewHolder.iv = (ImageView) view.findViewById(R.id.iv);
            viewHolder.tvLetter = (TextView) view.findViewById(R.id.catalog);
            view.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) view.getTag();
        }

        // 根据position获取分类的首字母的Char ascii值
        int section = getSectionForPosition(position);
        // 如果当前位置等于该分类首字母的Char的位置 ,则认为是第一次出现
        if (position == getPositionForSection(section)) {
            viewHolder.tvLetter.setVisibility(View.VISIBLE);
            viewHolder.tvLetter.setText(list.get(position).getSortLetters());
        } else {
            viewHolder.tvLetter.setVisibility(View.GONE);
        }

        viewHolder.name.setText(list.get(position).getNickname());
        Glide.with(context)
                .load(R.mipmap.ic_launcher)
                .into(viewHolder.iv);

        return view;
    }

    final static class ViewHolder {
        TextView name;
        ImageView iv;
        TextView tvLetter;

    }

    /**
     * 根据ListView的当前位置获取分类的首字母的Char ascii值
     */
    public int getSectionForPosition(int position) {
        return list.get(position).getSortLetters().charAt(0);
    }

    /**
     * 根据分类的首字母的Char ascii值获取其第一次出现该首字母的位置
     */
    public int getPositionForSection(int section) {
        for (int i = 0; i < getCount(); i++) {
            String sortStr = list.get(i).getSortLetters();
            char firstChar = sortStr.toUpperCase().charAt(0);
            if (firstChar == section) {
                return i;
            }
        }

        return -1;
    }
}

mainactivity里面处理

public class MainActivity extends AppCompatActivity {

    private String ss = "{\"list\":[{\"is_follow\":0,\"nickname\":\"波多野结衣\",\"user_id\":1,\"avatar\":\"http://image.chaokeli.cn/chocolate/15058077363962.jpg?imageView2/4/w/200\",\"follower_number\":5}],\"total\":3,\"error_code\":0}";

    private SideBar sideBar;
    private TextView dialog;
    private ListView listview;
    private List<nameData.ListEntity> list = new ArrayList<>();//解析出来后的集合
    private SearchAdapter adapter;
    /**
     * 根据拼音来排列ListView里面的数据类
     * 拼音比较器
     */
    private PinyinComparator pinyinComparator = new PinyinComparator();
    /**
     * 汉字转换成拼音的类
     */
    private CharacterParser characterParser;
    private SerchEditText searchEdit;
    private List<nameData.ListEntity> nameDatasList;//排序好的集合

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

    private void initView() {
        sideBar = (SideBar) findViewById(R.id.sidebar);
        dialog = (TextView) findViewById(R.id.dialog);
        listview = (ListView) findViewById(R.id.listview);
        searchEdit = (SerchEditText) findViewById(R.id.search_edit);
        sideBar.setTextView(dialog);
    }

    private void initData() {
        // 实例化汉字转拼音类
        characterParser = CharacterParser.getInstance();

        Gson gson = new Gson();
        nameData nameData = gson.fromJson(ss, nameData.class);
        list.addAll(nameData.getList());
        //汉子转换成拼音
        nameDatasList = zi2pinyi(list);

        // 根据a-z进行排序源数据
        Collections.sort(nameDatasList, pinyinComparator);
        adapter = new SearchAdapter(MainActivity.this, nameDatasList);
        listview.setAdapter(adapter);
        //右侧导航条目的触摸监听
        onSideBarListener();
        // 根据输入框输入值的改变来过滤搜索
        onSearchEditListener();
        //listview点击事件
        onListviewListener();
    }

    /**
     * listview点击事件
     */
    private void onListviewListener() {
        listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
               // Toast.makeText(MainActivity.this,nameDatasList.get(i).getNickname(),Toast.LENGTH_SHORT).show();
            }
        });
    }

    /**
     * 根据输入框输入值的改变来过滤搜索
     */
    private void onSearchEditListener() {
        searchEdit.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

            }

            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
                // 当输入框里面的值为空,更新为原来的列表,否则为过滤数据列表
                filterData(charSequence.toString());
            }

            @Override
            public void afterTextChanged(Editable editable) {

            }
        });
    }

    /**
     * 右侧导航条目的触摸监听
     */
    private void onSideBarListener() {
        sideBar.setOnTouchingLetterChangedListener(new SideBar.OnTouchChangedListener() {
            @Override
            public void onTouchChanged(String s) {
                //点击字母出现在当前页面
                int position = adapter.getPositionForSection(s.charAt(0));
                if (position != -1) {
                    listview.setSelection(position);
                }
            }
        });
    }

    private List<nameData.ListEntity> zi2pinyi(List<nameData.ListEntity> list) {

        for (int i = 0; i < list.size(); i++) {
            // 汉字转换成拼音
            String pinyin = characterParser.getSelling(list.get(i).getNickname());
            String sortString = pinyin.substring(0, 1).toUpperCase();
            // 正则表达式,判断首字母是否是英文字母
            if (sortString.matches("[A-Z]")) {
                list.get(i).setSortLetters(sortString.toUpperCase());
            } else {
                list.get(i).setSortLetters("#");
            }
        }
        return list;
    }

    /**
     * 根据输入框中的值来过滤数据并更新ListView
     *
     * @param filterStr
     */
    private void filterData(String filterStr) {
        List<nameData.ListEntity> list2 = new ArrayList();
        if (TextUtils.isEmpty(filterStr)) {
            list2.addAll(nameDatasList);
        } else {
            list2.clear();
            for (nameData.ListEntity namedata : nameDatasList) {
                String name = namedata.getNickname();
                if (name.indexOf(filterStr.toString()) != -1 ||
                        characterParser.getSelling(name).startsWith(filterStr.toString())) {
                    list2.add(namedata);
                }
            }
        }
        // 根据a-z进行排序
         Collections.sort(list2, pinyinComparator);
        adapter.updateListView(list2);
    }
}

更多详细代码请看demo

demo下载:http://download.csdn.net/download/qq_35698774/10109826

转载表明出处http://write.blog.csdn.net/postedit

qq群:471761982



猜你喜欢

转载自blog.csdn.net/qq_35698774/article/details/78481071