因为项目需求通讯录样式的列表
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