转载请标明出处
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方法构建精简的下拉子菜单适配器.
--------列表数据形式: