转载请标明出处
Android手机字母A-Z排序侧边索引是非常常见的功能,在此提供快速集成框架.教你用Android studio工具一分钟搞定这个效果.
实现效果:
以及点击F跳转效果
第一步库包导入实现拼音检索功能
-------拼音检索详细见:
compile ‘com.github.promeg:tinypinyin:1.0.0‘// ~80KB同步后后面会下载80k的文件,就可以使用
-------测试一下:
public void go1(View view){//按钮go1点击测试 String str="界面侧边ABc字母检索"; for (char c:str.toCharArray()){ System.out.println("检索返回:"+Pinyin.toPinyin(c));//如果c为汉字,则返回大写拼音;如果c不是汉字,则返回String.valueOf(c) System.out.println("如果c为汉字,则返回true,否则返回false:"+Pinyin.isChinese(c)); }}
结果效果:
第二步构建代码: 1.适配器LvRithtItemAdapter类public class LvRightItemAdapter extends BaseAdapter { private List<DataEntity> mEntities; private Activity context; private LayoutInflater layoutInflater; public LvRightItemAdapter(Activity context,List<DataEntity> entities) { this.context = context; this.mEntities = entities; this.layoutInflater = LayoutInflater.from(context); } @Override public int getCount() { return mEntities.size(); } @Override public DataEntity getItem(int position) { return mEntities.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = layoutInflater.inflate(R.layout.lv_right_item, parent,false); ViewHolder viewHolder = new ViewHolder(); viewHolder.tvLvRightItem = (TextView) convertView.findViewById(R.id.tv_lv_right_item); convertView.setTag(viewHolder); } initializeViews((DataEntity)getItem(position), (ViewHolder) convertView.getTag()); return convertView; } private void initializeViews(DataEntity entity, ViewHolder holder) { //TODO implement holder.tvLvRightItem.setText(String.valueOf(entity.getChar_First())); } protected class ViewHolder { private TextView tvLvRightItem; } }2.自定义MyExpandAdapter代码(这个类只是把没用到的ExpandableListAdapter复写方法存放在这):
public abstract class MyExpandAdapter implements ExpandableListAdapter{ //用抽象方法把下拉子菜单的不用的方法集中在这里,方便观看 //抽象出接口,回调方法,用方法继承就可以定义子菜单 @Override public void registerDataSetObserver(DataSetObserver observer) { } @Override public void unregisterDataSetObserver(DataSetObserver observer) { } @Override public Object getGroup(int groupPosition) { return null; } @Override public Object getChild(int groupPosition, int childPosition) { return null; } @Override public long getGroupId(int groupPosition) { return 0; } @Override public long getChildId(int groupPosition, int childPosition) { return 0; } @Override public boolean hasStableIds() { return false; } @Override public boolean isChildSelectable(int groupPosition, int childPosition) { return false; } @Override public boolean areAllItemsEnabled() { return false; } @Override public boolean isEmpty() { return false; } @Override public void onGroupExpanded(int groupPosition) { } @Override public void onGroupCollapsed(int groupPosition) { } @Override public long getCombinedChildId(long groupId, long childId) { return 0; } @Override public long getCombinedGroupId(long groupId) { return 0; } }3.精简的下拉子菜单自定义SimpleExpAdapter适配器类public class SimpleExpAdapter extends MyExpandAdapter{ private List<DataEntity> mDataEntities; //列表数据存放的集合 private Activity mActivity; private LayoutInflater mLayoutInflater; //布局渲染成一个view public SimpleExpAdapter(List<DataEntity> dataEntities, Activity activity){ mDataEntities = dataEntities; mActivity = activity; mLayoutInflater=mActivity.getLayoutInflater(); } @Override public int getGroupCount() { return mDataEntities.size(); } @Override public int getChildrenCount(int groupPosition) { return mDataEntities.get(groupPosition).getDatas().size(); } @Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { ViewHolder viewHolder=null; if (convertView==null){ viewHolder=new ViewHolder(); convertView=mLayoutInflater.inflate(R.layout.exlv_item_group,parent,false); viewHolder.mTextView= (TextView) convertView.findViewById(R.id.tv_exlv_group); convertView.setTag(viewHolder); }else { viewHolder= (ViewHolder) convertView.getTag(); } viewHolder.mTextView.setText(String.valueOf(mDataEntities.get(groupPosition).getChar_First()));//适配器设置列表数据 return convertView; } @Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { ViewHolder viewHolder=null; if (convertView==null){ viewHolder=new ViewHolder(); convertView=mLayoutInflater.inflate(R.layout.exlv_item_child,parent,false); viewHolder.mTextView= (TextView) convertView.findViewById(R.id.tv_exlv_child); convertView.setTag(viewHolder); }else{ viewHolder= (ViewHolder) convertView.getTag(); } viewHolder.mTextView.setText(mDataEntities.get(groupPosition).getDatas().get(childPosition)); return convertView; } class ViewHolder{//item放置的控件 TextView mTextView; } }4.数据逻辑控制dao包:
public class DataDao { private List<DataEntity> mDataEntities=new ArrayList<>(); public void add(String data){ char data_first=data.toUpperCase().charAt(0); //将首个字母转换为大写字母 if (Pinyin.isChinese(data_first)){ //如果首个字母是中文,则获取汉字首个字母的大写 data_first= Pinyin.toPinyin(data_first).charAt(0); } //确保取得大写的唯一首字母,然后继续执行 for (DataEntity dataEntity:mDataEntities){ if (dataEntity.isSameFirst(data_first)){ dataEntity.addData(data); return; } } DataEntity dataEntity=new DataEntity(); dataEntity.setChar_First(data_first); dataEntity.addData(data); mDataEntities.add(dataEntity); Collections.sort(mDataEntities); } public List<DataEntity> getDataEntities() { System.out.println(mDataEntities.toString()); return mDataEntities; } }5.封装列表数据类:
public class DataEntity implements Comparable<DataEntity>{ private char mChar_First; //定义首字母 private List<String> mDatas=new ArrayList<>(); public boolean isSameFirst(char des){//判断是否与传入的des相等 return des==this.mChar_First; } public void addData(String data){ mDatas.add(data); Collections.sort(mDatas); //排列首字母相同的列表数据 System.out.println(mDatas.toString()); } @Override public int compareTo(DataEntity another) { return this.mChar_First-another.getChar_First(); } public List<String> getDatas() { //存放同首字母的列表数据 return mDatas; } public char getChar_First() { return mChar_First; } public void setChar_First(char char_First) { mChar_First = char_First; } @Override public String toString() { return "DataEntity{" + "mChar_First=" + mChar_First + ", mDatas=" + mDatas + '}'; } }6显示的activity界面类(数据直接在addlistdatas()方法中添加):
public class MainActivity extends AppCompatActivity { ExpandableListView mExlv; DataDao mDataDao=new DataDao(); ListView mLvRight; //右侧的字母栏 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); addListdatas();//填充列表假数据测试,失败经验:数据不能再setadapter之后进行 initListener(); } public void initListener(){ mExlv.setAdapter(new SimpleExpAdapter(mDataDao.getDataEntities(), this)); //全都展开不能回缩 for (int i = 0; i < mDataDao.getDataEntities().size(); i++) { mExlv.expandGroup(i); } mExlv.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() { @Override public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) { return true; } }); mLvRight.setAdapter(new LvRightItemAdapter(this,mDataDao.getDataEntities())); mLvRight.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { mExlv.setSelectedGroup(position); } }); } public void initView(){ mExlv= (ExpandableListView) findViewById(R.id.exlv); mLvRight= (ListView) findViewById(R.id.lv_right); } // public void go1(View view){ //字母检索 // String str="界面侧边ABc字母检索"; // for (char c:str.toCharArray()){ // System.out.println("检索返回:"+Pinyin.toPinyin(c));//如果c为汉字,则返回大写拼音;如果c不是汉字,则返回String.valueOf(c) // System.out.println("如果c为汉字,则返回true,否则返回false:"+Pinyin.isChinese(c)); // } // } public void addListdatas(){ mDataDao.add("拜拜这是b"); mDataDao.add("啊啊这是a"); mDataDao.add("啧啧这是z"); mDataDao.add("烦烦这是f"); mDataDao.add("哥哥这是g"); mDataDao.add("哈哈这是h"); mDataDao.add("看看这是k"); mDataDao.add("啊拜这是ab"); for(int i='a';i<'z';i++){ if (i=='e'||i=='h'){ continue; } mDataDao.add((char) i + "1"); mDataDao.add((char) i + "2"); mDataDao.add((char) i + "3"); } for (int i = 'A'; i <= 'Z'; i++) { if (i == 'E' || i == 'H') { continue; } mDataDao.add((char) i + "1"); mDataDao.add((char) i + "2"); mDataDao.add((char) i + "3"); } }第三步xml界面的构建:1.activity界面的实现:<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".ui.MainActivity"> <ExpandableListView android:id="@+id/exlv" android:groupIndicator="@null" android:layout_width="match_parent" android:layout_height="match_parent" /> <ListView android:id="@+id/lv_right" android:layout_width="20dp" android:divider="@null" android:layout_alignParentRight="true" android:layout_height="match_parent"></ListView> </RelativeLayout>2.exlv_item_child自定义适配器布局(可以根据自己想法更改界面显示)<TextView android:id="@+id/tv_exlv_child" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="50dp" android:background="#bbb" android:gravity="center_vertical" android:paddingLeft="15dp" android:textSize="12sp"> </TextView>3.exlv_item_group自定义适配器布局(可以根据自己想法更改界面显示)
<TextView android:id="@+id/tv_exlv_group" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="20dp" android:background="#fff" android:gravity="center_vertical" android:paddingLeft="15dp" android:textSize="12sp"> </TextView>4.lv_right_item自定义listview适配器布局(可以根据自己想法更改界面显示)
<TextView android:id="@+id/tv_lv_right_item" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="20dp" android:background="#00ffffff" android:gravity="center" android:textSize="12sp"> </TextView>最后原理总结:
-----原理解析
概括:字符串放入 集合 中进行排序
分层结构:
A: a开头名字数据 子菜单名字(字符串排序:Collections.sort( 数据));
所有数据(如电话名字) B:b开头名字数据 子菜单名字(字符串排序:Collections.sort( 数据));
C: c开头数据数据 子菜单名字(字符串排序:Collections.sort( 数据));
.....
在ASll码表中字母大小写位置
-----------implement方法构建精简的下拉子菜单适配器.
注意:用抽象类的方法,让我们想要的适配器实现需要的复写的方法
--------列表数据形式:
时间: 2024-10-29 19:05:36