在我们的项目开发过程中,经常会对用户的信息进行分组,即通过组来显示用户的信息,同时通过一定的查询条件来显示查询后的相关用户信息,并且通过颜色选择器来设置列表信息的背景颜色。

其中借鉴xiaanming:http://blog.csdn.net/xiaanming/article/details/12684155

下面来看看项目运行后的效果图以及代码结构图:

下面通过代码来实现整个效果。

1.主界面布局activity_main.xml

<span style="font-size:18px;"><LinearLayout 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"android:orientation="vertical"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin" ><Buttonandroid:id="@+id/my_btn"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="生成部门列表" /><com.example.myexpandabledemo.ClearEditTextandroid:id="@+id/filter_edit"android:layout_width="fill_parent"android:layout_height="60dp"android:layout_marginTop="10dip"android:background="@drawable/search_bar_edit_selector"android:drawableLeft="@drawable/search_bar_icon_normal"android:hint="搜索"android:singleLine="true"android:textSize="15.0dip" /><TextViewandroid:id="@+id/no_search_result_tv"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="未搜索到结果"android:visibility="gone"/><ExpandableListViewandroid:id="@+id/my_expand_lv"android:layout_width="match_parent"android:layout_height="wrap_content" /></LinearLayout></span>

分析:主界面主要有一个Button,一个自定义搜索的ClearEditText,一个无查询结果的TextView,一个列表信息显示ExpandableListView。其中Button主要用来生成列表信息。

2.自定义的ClearEditText的搜索框CliearEditText.java

<span style="font-size:18px;">package com.example.myexpandabledemo;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnFocusChangeListener;
import android.view.animation.Animation;
import android.view.animation.CycleInterpolator;
import android.view.animation.TranslateAnimation;
import android.widget.EditText;public class ClearEditText extends EditText implements  OnFocusChangeListener, TextWatcher { /*** 删除按钮的引用*/private Drawable mClearDrawable; public ClearEditText(Context context) { this(context, null); } public ClearEditText(Context context, AttributeSet attrs) { //这里构造方法也很重要,不加这个很多属性不能再XML里面定义this(context, attrs, android.R.attr.editTextStyle); } public ClearEditText(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init();}private void init() { //获取EditText的DrawableRight,假如没有设置我们就使用默认的图片mClearDrawable = getCompoundDrawables()[2]; if (mClearDrawable == null) { mClearDrawable = getResources() .getDrawable(R.drawable.emotionstore_progresscancelbtn); } mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight()); setClearIconVisible(false); setOnFocusChangeListener(this); addTextChangedListener(this); } /*** 因为我们不能直接给EditText设置点击事件,所以我们用记住我们按下的位置来模拟点击事件* 当我们按下的位置 在  EditText的宽度 - 图标到控件右边的间距 - 图标的宽度  和* EditText的宽度 - 图标到控件右边的间距之间我们就算点击了图标,竖直方向没有考虑*/@Override public boolean onTouchEvent(MotionEvent event) { if (getCompoundDrawables()[2] != null) { if (event.getAction() == MotionEvent.ACTION_UP) { boolean touchable = event.getX() > (getWidth() - getPaddingRight() - mClearDrawable.getIntrinsicWidth()) && (event.getX() < ((getWidth() - getPaddingRight())));if (touchable) { this.setText(""); } } } return super.onTouchEvent(event); } /*** 当ClearEditText焦点发生变化的时候,判断里面字符串长度设置清除图标的显示与隐藏*/@Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) { setClearIconVisible(getText().length() > 0); } else { setClearIconVisible(false); } } /*** 设置清除图标的显示与隐藏,调用setCompoundDrawables为EditText绘制上去* @param visible*/protected void setClearIconVisible(boolean visible) { Drawable right = visible ? mClearDrawable : null; setCompoundDrawables(getCompoundDrawables()[0], getCompoundDrawables()[1], right, getCompoundDrawables()[3]); } /*** 当输入框里面内容发生变化的时候回调的方法*/@Override public void onTextChanged(CharSequence s, int start, int count, int after) { setClearIconVisible(s.length() > 0); } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { } /*** 设置晃动动画*/public void setShakeAnimation(){this.setAnimation(shakeAnimation(5));}/*** 晃动动画* @param counts 1秒钟晃动多少下* @return*/public static Animation shakeAnimation(int counts){Animation translateAnimation = new TranslateAnimation(0, 10, 0, 0);translateAnimation.setInterpolator(new CycleInterpolator(counts));translateAnimation.setDuration(1000);return translateAnimation;}}</span>

搜索框颜色选择器:

<span style="font-size:18px;"><?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:state_focused="true" android:drawable="@drawable/search_bar_edit_pressed"></item><item android:state_pressed="true" android:drawable="@drawable/search_bar_edit_pressed"></item><item android:drawable="@drawable/search_bar_edit_normal"></item>
</selector></span>

3.汉字拼音排序所需要的汉字转拼音:CharacterParser.java

<span style="font-size:18px;">package com.example.myexpandabledemo;/*** Java汉字转换为拼音* */
public class CharacterParser {private static int[] pyvalue = new int[] {-20319, -20317, -20304, -20295, -20292, -20283, -20265, -20257, -20242, -20230, -20051, -20036, -20032,-20026, -20002, -19990, -19986, -19982, -19976, -19805, -19784, -19775, -19774, -19763, -19756, -19751, -19746, -19741, -19739, -19728,-19725, -19715, -19540, -19531, -19525, -19515, -19500, -19484, -19479, -19467, -19289, -19288, -19281, -19275, -19270, -19263, -19261,-19249, -19243, -19242, -19238, -19235, -19227, -19224, -19218, -19212, -19038, -19023, -19018, -19006, -19003, -18996, -18977, -18961,-18952, -18783, -18774, -18773, -18763, -18756, -18741, -18735, -18731, -18722, -18710, -18697, -18696, -18526, -18518, -18501, -18490,-18478, -18463, -18448, -18447, -18446, -18239, -18237, -18231, -18220, -18211, -18201, -18184, -18183, -18181, -18012, -17997, -17988,-17970, -17964, -17961, -17950, -17947, -17931, -17928, -17922, -17759, -17752, -17733, -17730, -17721, -17703, -17701, -17697, -17692,-17683, -17676, -17496, -17487, -17482, -17468, -17454, -17433, -17427, -17417, -17202, -17185, -16983, -16970, -16942, -16915, -16733,-16708, -16706, -16689, -16664, -16657, -16647, -16474, -16470, -16465, -16459, -16452, -16448, -16433, -16429, -16427, -16423, -16419,-16412, -16407, -16403, -16401, -16393, -16220, -16216, -16212, -16205, -16202, -16187, -16180, -16171, -16169, -16158, -16155, -15959,-15958, -15944, -15933, -15920, -15915, -15903, -15889, -15878, -15707, -15701, -15681, -15667, -15661, -15659, -15652, -15640, -15631,-15625, -15454, -15448, -15436, -15435, -15419, -15416, -15408, -15394, -15385, -15377, -15375, -15369, -15363, -15362, -15183, -15180,-15165, -15158, -15153, -15150, -15149, -15144, -15143, -15141, -15140, -15139, -15128, -15121, -15119, -15117, -15110, -15109, -14941,-14937, -14933, -14930, -14929, -14928, -14926, -14922, -14921, -14914, -14908, -14902, -14894, -14889, -14882, -14873, -14871, -14857,-14678, -14674, -14670, -14668, -14663, -14654, -14645, -14630, -14594, -14429, -14407, -14399, -14384, -14379, -14368, -14355, -14353,-14345, -14170, -14159, -14151, -14149, -14145, -14140, -14137, -14135, -14125, -14123, -14122, -14112, -14109, -14099, -14097, -14094,-14092, -14090, -14087, -14083, -13917, -13914, -13910, -13907, -13906, -13905, -13896, -13894, -13878, -13870, -13859, -13847, -13831,-13658, -13611, -13601, -13406, -13404, -13400, -13398, -13395, -13391, -13387, -13383, -13367, -13359, -13356, -13343, -13340, -13329,-13326, -13318, -13147, -13138, -13120, -13107, -13096, -13095, -13091, -13076, -13068, -13063, -13060, -12888, -12875, -12871, -12860,-12858, -12852, -12849, -12838, -12831, -12829, -12812, -12802, -12607, -12597, -12594, -12585, -12556, -12359, -12346, -12320, -12300,-12120, -12099, -12089, -12074, -12067, -12058, -12039, -11867, -11861, -11847, -11831, -11798, -11781, -11604, -11589, -11536, -11358,-11340, -11339, -11324, -11303, -11097, -11077, -11067, -11055, -11052, -11045, -11041, -11038, -11024, -11020, -11019, -11018, -11014,-10838, -10832, -10815, -10800, -10790, -10780, -10764, -10587, -10544, -10533, -10519, -10331, -10329, -10328, -10322, -10315, -10309,-10307, -10296, -10281, -10274, -10270, -10262, -10260, -10256, -10254};public static String[] pystr = new String[] {"a", "ai", "an", "ang", "ao", "ba", "bai", "ban", "bang", "bao", "bei", "ben", "beng", "bi", "bian","biao", "bie", "bin", "bing", "bo", "bu", "ca", "cai", "can", "cang", "cao", "ce", "ceng", "cha", "chai", "chan", "chang", "chao", "che","chen", "cheng", "chi", "chong", "chou", "chu", "chuai", "chuan", "chuang", "chui", "chun", "chuo", "ci", "cong", "cou", "cu", "cuan","cui", "cun", "cuo", "da", "dai", "dan", "dang", "dao", "de", "deng", "di", "dian", "diao", "die", "ding", "diu", "dong", "dou", "du","duan", "dui", "dun", "duo", "e", "en", "er", "fa", "fan", "fang", "fei", "fen", "feng", "fo", "fou", "fu", "ga", "gai", "gan", "gang","gao", "ge", "gei", "gen", "geng", "gong", "gou", "gu", "gua", "guai", "guan", "guang", "gui", "gun", "guo", "ha", "hai", "han", "hang","hao", "he", "hei", "hen", "heng", "hong", "hou", "hu", "hua", "huai", "huan", "huang", "hui", "hun", "huo", "ji", "jia", "jian","jiang", "jiao", "jie", "jin", "jing", "jiong", "jiu", "ju", "juan", "jue", "jun", "ka", "kai", "kan", "kang", "kao", "ke", "ken","keng", "kong", "kou", "ku", "kua", "kuai", "kuan", "kuang", "kui", "kun", "kuo", "la", "lai", "lan", "lang", "lao", "le", "lei", "leng","li", "lia", "lian", "liang", "liao", "lie", "lin", "ling", "liu", "long", "lou", "lu", "lv", "luan", "lue", "lun", "luo", "ma", "mai","man", "mang", "mao", "me", "mei", "men", "meng", "mi", "mian", "miao", "mie", "min", "ming", "miu", "mo", "mou", "mu", "na", "nai","nan", "nang", "nao", "ne", "nei", "nen", "neng", "ni", "nian", "niang", "niao", "nie", "nin", "ning", "niu", "nong", "nu", "nv", "nuan","nue", "nuo", "o", "ou", "pa", "pai", "pan", "pang", "pao", "pei", "pen", "peng", "pi", "pian", "piao", "pie", "pin", "ping", "po", "pu","qi", "qia", "qian", "qiang", "qiao", "qie", "qin", "qing", "qiong", "qiu", "qu", "quan", "que", "qun", "ran", "rang", "rao", "re","ren", "reng", "ri", "rong", "rou", "ru", "ruan", "rui", "run", "ruo", "sa", "sai", "san", "sang", "sao", "se", "sen", "seng", "sha","shai", "shan", "shang", "shao", "she", "shen", "sheng", "shi", "shou", "shu", "shua", "shuai", "shuan", "shuang", "shui", "shun","shuo", "si", "song", "sou", "su", "suan", "sui", "sun", "suo", "ta", "tai", "tan", "tang", "tao", "te", "teng", "ti", "tian", "tiao","tie", "ting", "tong", "tou", "tu", "tuan", "tui", "tun", "tuo", "wa", "wai", "wan", "wang", "wei", "wen", "weng", "wo", "wu", "xi","xia", "xian", "xiang", "xiao", "xie", "xin", "xing", "xiong", "xiu", "xu", "xuan", "xue", "xun", "ya", "yan", "yang", "yao", "ye", "yi","yin", "ying", "yo", "yong", "you", "yu", "yuan", "yue", "yun", "za", "zai", "zan", "zang", "zao", "ze", "zei", "zen", "zeng", "zha","zhai", "zhan", "zhang", "zhao", "zhe", "zhen", "zheng", "zhi", "zhong", "zhou", "zhu", "zhua", "zhuai", "zhuan", "zhuang", "zhui","zhun", "zhuo", "zi", "zong", "zou", "zu", "zuan", "zui", "zun", "zuo"};private StringBuilder buffer;private String resource;private static CharacterParser characterParser = new CharacterParser();public static CharacterParser getInstance() {return characterParser;}public String getResource() {return resource;}public void setResource(String resource) {this.resource = resource;}/** * 汉字转成ASCII码 * * @param chs * @return */private int getChsAscii(String chs) {int asc = 0;try {byte[] bytes = chs.getBytes("gb2312");if (bytes == null || bytes.length > 2 || bytes.length <= 0) {throw new RuntimeException("illegal resource string");}if (bytes.length == 1) {asc = bytes[0];}if (bytes.length == 2) {int hightByte = 256 + bytes[0];int lowByte = 256 + bytes[1];asc = (256 * hightByte + lowByte) - 256 * 256;}} catch (Exception e) {System.out.println("ERROR:ChineseSpelling.class-getChsAscii(String chs)" + e);}return asc;}/** * 单字解析 * * @param str * @return */public String convert(String str) {String result = null;int ascii = getChsAscii(str);if (ascii > 0 && ascii < 160) {result = String.valueOf((char) ascii);} else {for (int i = (pyvalue.length - 1); i >= 0; i--) {if (pyvalue[i] <= ascii) {result = pystr[i];break;}}}return result;}/** * 词组解析 * * @param chs * @return */public String getSelling(String chs) {String key, value;buffer = new StringBuilder();for (int i = 0; i < chs.length(); i++) {key = chs.substring(i, i + 1);if (key.getBytes().length >= 2) {value = (String) convert(key);if (value == null) {value = "unknown";}} else {value = key;}buffer.append(value);}return buffer.toString();}public String getSpelling() {return this.getSelling(this.getResource());}}
</span>

4. 拼音比较类:PinyinComparator.java

<span style="font-size:18px;">package com.example.myexpandabledemo;import java.util.Comparator;public class PinyinComparator implements Comparator<GroupMemberBean> {public int compare(GroupMemberBean o1, GroupMemberBean o2) {if (o1.getSortLetters().equals("@")|| o2.getSortLetters().equals("#")) {return -1;} else if (o1.getSortLetters().equals("#")|| o2.getSortLetters().equals("@")) {return 1;} else {return o1.getSortLetters().compareTo(o2.getSortLetters());}}}
</span>

5. 显示列表信息的名字以及其拼音首字母 GrouMemberBean.java

<span style="font-size:18px;">package com.example.myexpandabledemo;public class GroupMemberBean {private String name;   //显示的数据private String sortLetters;  //显示数据拼音的首字母public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSortLetters() {return sortLetters;}public void setSortLetters(String sortLetters) {this.sortLetters = sortLetters;}
}
</span>

6.ExpandaleListView 适配器MyExpandableAdapter.java

<span style="font-size:18px;">package com.example.myexpandabledemo;import java.util.List;import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;public class MyExpandableAdapter extends BaseExpandableListAdapter {private Context mContext;private List<GroupMemberBean> mGroup;private List<List<GroupMemberBean>> mChild;private LayoutInflater mInflater;public MyExpandableAdapter(Context mContext,List<GroupMemberBean> mGroup,List<List<GroupMemberBean>> mChild){this.mContext = mContext;this.mGroup = mGroup;this.mChild = mChild;this.mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);}/*** 当ListView数据发生变化时,调用此方法来更新ListView* * @param list*/public void updateListView(List<GroupMemberBean> mGroup,List<List<GroupMemberBean>> mChild) {this.mGroup = mGroup;this.mChild = mChild;notifyDataSetChanged();}@Overridepublic int getGroupCount() {// TODO Auto-generated method stubreturn mGroup.size();}@Overridepublic int getChildrenCount(int groupPosition) {// TODO Auto-generated method stubreturn mChild.get(groupPosition).size();}@Overridepublic Object getGroup(int groupPosition) {// TODO Auto-generated method stubreturn mGroup.get(groupPosition);}@Overridepublic Object getChild(int groupPosition, int childPosition) {// TODO Auto-generated method stubreturn mChild.get(groupPosition).get(childPosition);}@Overridepublic long getGroupId(int groupPosition) {// TODO Auto-generated method stubreturn groupPosition;}@Overridepublic long getChildId(int groupPosition, int childPosition) {// TODO Auto-generated method stubreturn childPosition;}@Overridepublic boolean hasStableIds() {// TODO Auto-generated method stubreturn false;}@Overridepublic View getGroupView(int groupPosition, boolean isExpanded,View convertView, ViewGroup parent) {// TODO Auto-generated method stubGroupHolderView groupHolderView;if(convertView == null){groupHolderView = new GroupHolderView();convertView = (View) mInflater.inflate(R.layout.activity_group, null);groupHolderView.groupTv = (TextView) convertView.findViewById(R.id.my_group_tv);convertView.setTag(groupHolderView);}else{groupHolderView = (GroupHolderView) convertView.getTag();}groupHolderView.groupTv.setText(mGroup.get(groupPosition).getName());return convertView;}@Overridepublic View getChildView(final int groupPosition, final int childPosition,boolean isLastChild, View convertView, ViewGroup parent) {// TODO Auto-generated method stubChildHolderView childHolderView;if(convertView == null){childHolderView = new ChildHolderView();convertView = (View) mInflater.inflate(R.layout.activity_child, null);childHolderView.childIv = (ImageView) convertView.findViewById(R.id.my_child_iv);childHolderView.childTv = (TextView) convertView.findViewById(R.id.my_child_tv);childHolderView.childLl = (LinearLayout) convertView.findViewById(R.id.my_child_ll);convertView.setTag(childHolderView);}else{childHolderView = (ChildHolderView) convertView.getTag();}childHolderView.childTv.setText(mChild.get(groupPosition).get(childPosition).getName());childHolderView.childLl.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v) {// TODO Auto-generated method stubToast.makeText(mContext, "group:" + mGroup.get(groupPosition).getName() + "->child:" + mChild.get(groupPosition).get(childPosition).getName(), Toast.LENGTH_SHORT).show();}});return convertView;}@Overridepublic boolean isChildSelectable(int groupPosition, int childPosition) {// TODO Auto-generated method stubreturn false;}class GroupHolderView{TextView groupTv;}class ChildHolderView{ImageView childIv;TextView childTv;LinearLayout childLl;}}</span>

分析:

GroupHolderView:用于显示组信息

ChildHolderView:用于显示组下成员信息。包括一个LinearLayout,一个ImageView,一个TextVIew

private List<GroupMemberBean> mGroup; 包含组的所有List信息
private List<List<GroupMemberBean>> mChild;包含所有的组下成员信息

<span style="font-size:18px;">  public void updateListView(List<GroupMemberBean> mGroup,List<List<GroupMemberBean>> mChild) {this.mGroup = mGroup;this.mChild = mChild;notifyDataSetChanged();}</span>

根据传入的mGroup,mChild来更新列表信息。

7.GroupHolderView类所对应的activity_group.xml

<span style="font-size:18px;"><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><TextViewandroid:id="@+id/my_group_tv"android:layout_width="wrap_content"android:layout_height="50dp" android:paddingLeft="50dp"android:gravity="center_vertical"/></LinearLayout></span>

8.ChildHolderView类所对应的activity_child.xml

<span style="font-size:18px;"><?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/my_child_ll"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@drawable/my_child_selector"android:orientation="horizontal" ><ImageViewandroid:id="@+id/my_child_iv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/ic_launcher" /><TextViewandroid:id="@+id/my_child_tv"android:layout_width="wrap_content"android:layout_height="wrap_content" /></LinearLayout></span>

分析:根据android:background="@drawable/my_child_selector" 颜色选择器来设置每个列表行(选中或正常)的背景色。

9.颜色选择器my_child_selector.xml

<span style="font-size:18px;"><?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:state_focused="true" android:drawable="@color/press_color"></item><item android:state_pressed="true" android:drawable="@color/press_color"></item><item android:drawable="@color/normal_color"></item>
</selector></span>

10.主界面实现代码:MainActivity.java

<span style="font-size:18px;">package com.example.myexpandabledemo;import java.util.ArrayList;
import java.util.Collections;
import java.util.List;import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ExpandableListView;
import android.widget.TextView;public class MainActivity extends Activity {private Button myBtn;private ExpandableListView myExpandLv;private ClearEditText myClearEt;private TextView noSearchResultTv;private MyExpandableAdapter myAdapter;private List<GroupMemberBean> groupBeanList;private List<List<GroupMemberBean>> childBeanList = new ArrayList<List<GroupMemberBean>>();/*** 汉字转换成拼音的类*/private CharacterParser characterParser;/*** 根据拼音来排列ListView里面的数据类*/private PinyinComparator pinyinComparator;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);init();}private void init() {noSearchResultTv = (TextView)this.findViewById(R.id.no_search_result_tv);myExpandLv = (ExpandableListView) this.findViewById(R.id.my_expand_lv);// 实例化汉字转拼音类characterParser = CharacterParser.getInstance();pinyinComparator = new PinyinComparator();groupBeanList = filledData(this.getResources().getStringArray(R.array.depart));List<GroupMemberBean> tempOne = filledData(this.getResources().getStringArray(R.array.child_one));List<GroupMemberBean> tempTwo = filledData(this.getResources().getStringArray(R.array.child_two));// 根据a-z进行排序源数据Collections.sort(groupBeanList, pinyinComparator);Collections.sort(tempOne, pinyinComparator);Collections.sort(tempTwo, pinyinComparator);for (int i = 0; i < groupBeanList.size(); i++) {if (i % 2 == 0) {childBeanList.add(tempOne);} else {childBeanList.add(tempTwo);}}//用于生成列表信息myBtn = (Button) this.findViewById(R.id.my_btn);myBtn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubmyAdapter = new MyExpandableAdapter(MainActivity.this,groupBeanList, childBeanList);myExpandLv.setAdapter(myAdapter);myExpandLv.expandGroup(0);}});myClearEt = (ClearEditText) this.findViewById(R.id.filter_edit);myClearEt.addTextChangedListener(new TextWatcher() {@Overridepublic void beforeTextChanged(CharSequence s, int start, int count,int after) {// TODO Auto-generated method stub}@Overridepublic void onTextChanged(CharSequence s, int start, int before,int count) {// TODO Auto-generated method stubfilterData(s.toString());}@Overridepublic void afterTextChanged(Editable s) {// TODO Auto-generated method stub}});}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {// Handle action bar item clicks here. The action bar will// automatically handle clicks on the Home/Up button, so long// as you specify a parent activity in AndroidManifest.xml.int id = item.getItemId();if (id == R.id.action_settings) {return true;}return super.onOptionsItemSelected(item);}/*** 为ListView填充数据* * @param date* @return*/private List<GroupMemberBean> filledData(String[] date) {List<GroupMemberBean> mSortList = new ArrayList<GroupMemberBean>();for (int i = 0; i < date.length; i++) {GroupMemberBean sortModel = new GroupMemberBean();sortModel.setName(date[i]);// 汉字转换成拼音String pinyin = characterParser.getSelling(date[i]);String sortString = pinyin.substring(0, 1).toUpperCase();// 正则表达式,判断首字母是否是英文字母if (sortString.matches("[A-Z]")) {sortModel.setSortLetters(sortString.toUpperCase());} else {sortModel.setSortLetters("#");}mSortList.add(sortModel);}return mSortList;}/*** 根据输入框中的值来过滤数据并更新ListView* * @param filterStr*/private void filterData(String filterStr) {List<GroupMemberBean> groupFilterList = new ArrayList<GroupMemberBean>();List<GroupMemberBean> tempFilterList;List<List<GroupMemberBean>> childFilterList = new ArrayList<List<GroupMemberBean>>();if (TextUtils.isEmpty(filterStr)) {groupFilterList = groupBeanList;childFilterList = childBeanList;noSearchResultTv.setVisibility(View.GONE);} else {groupFilterList.clear();childFilterList.clear();for (int i = 0; i < groupBeanList.size(); i++) {//标记departGroup是否加入元素boolean isAddGroup = false;tempFilterList = new ArrayList<GroupMemberBean>();GroupMemberBean sortModel = groupBeanList.get(i);String name = sortModel.getName();// depart有字符直接加入if (name.indexOf(filterStr.toString()) != -1|| characterParser.getSelling(name).startsWith(filterStr.toString())) {if (!groupFilterList.contains(sortModel)) {groupFilterList.add(sortModel);isAddGroup = true;}}for (int j = 0; j < childBeanList.get(i).size(); j++) {GroupMemberBean sortChildModel = childBeanList.get(i).get(j);String childName = sortChildModel.getName();// child有字符直接加入,其父也加入if (childName.indexOf(filterStr.toString()) != -1|| characterParser.getSelling(childName).startsWith(filterStr.toString())) {tempFilterList.add(sortChildModel);if (!groupFilterList.contains(groupBeanList.get(i))) {groupFilterList.add(groupBeanList.get(i));isAddGroup = true;}}}Collections.sort(tempFilterList, pinyinComparator);if (isAddGroup) {childFilterList.add(tempFilterList);}}// 根据a-z进行排序Collections.sort(groupBeanList, pinyinComparator);}if (myAdapter != null) {myAdapter.updateListView(groupFilterList, childFilterList);if (TextUtils.isEmpty(filterStr)) {for (int i = 0; i < groupFilterList.size(); i++) {if (i == 0) {myExpandLv.expandGroup(i);continue;}myExpandLv.collapseGroup(i);}} else {//搜索的结果全部展开for (int i = 0; i < groupFilterList.size(); i++) {myExpandLv.expandGroup(i);}}}//如果查询的结果为0时,显示为搜索到结果的提示if(groupFilterList.size() == 0){noSearchResultTv.setVisibility(View.VISIBLE);}else{noSearchResultTv.setVisibility(View.GONE);}}
}
</span>

分析:

<span style="font-size:18px;">      myBtn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubmyAdapter = new MyExpandableAdapter(MainActivity.this,groupBeanList, childBeanList);myExpandLv.setAdapter(myAdapter);myExpandLv.expandGroup(0);}});</span>

用于生成列表信息

<span style="font-size:18px;">private List<GroupMemberBean> filledData(String[] date) </span>

根据 res->array定义的字符数组,转化为List<GroupMemberBean>

<span style="font-size:18px;">private void filterData(String filterStr) {</span>

根据查询条件更新列表信息,
重点:1.如果查询的条件为空,直接更新列表初始状态;

假如:filterStr = “g”;

2.如果查询的结果为空,直接给出“未搜索到结果”提示;

3.如果Group中包含filterStr,GroupMemberBean sortModel 直接加入groupFilterList,并标记已加入isAddGroup = true;

如果Child中包含filterStr,定义临时的tempFilterList,GroupMemberBean sortChildModel加入到childFilterList,如果groupFilterList不包含其父组,并将其父加入到groupFilterList,并标记已加入isAddGroup=true;

最后如果isAddGroup=true,将tempFilterList加入到childFilterList。

4.通过myAdapter.updateListView(groupFilterList, childFilterList),更新列表信息。

其上为本博文的所有内容。

源代码下载:

http://download.csdn.net/detail/a123demi/7623975

详细讲解ExpandableListView显示和查询仿QQ分组列表用户信息相关推荐

  1. 仿QQ分组列表(UITableView)

    // // ViewController.m // 仿QQ分组列表 // // Created by lanqs on 15/1/26. // Copyright (c) 2015年 Tanqihon ...

  2. android仿qq分组列表效果

    推荐一个程序员开发.学习的好网站,www.it123.top 欢迎大家转发收藏. 效果图如下: 源码免费下载地址:http://download.csdn.net/detail/xuweilinjij ...

  3. android qq分组展开,Android仿qq分组管理的第三方库

    本文实例为大家分享了Android仿qq分组管理的第三方库,供大家参考,具体内容如下 下面先看效果 我们点击展开与折叠分组的功能在库里面是已经封装好的,只能把它已入到项目中,就可以直接用了,十分的方便 ...

  4. iOS之仿QQ好友列表展开收缩效果的实现

    使用UICollectionView实现 思路 很明显整体它是一个列表,它的分组是一个列表,它里面的好友列表也是一个列表,所以就可以使用组头来设置分组列表,使用cell设置好友列表: 当点击组头的时候 ...

  5. android 仿qq好友动态,Android UI仿QQ好友列表分组悬浮效果

    本文实例为大家分享了Android UI仿QQ好友列表分组悬浮效果的具体代码,供大家参考,具体内容如下 楼主是在平板上測试的.图片略微有点大,大家看看效果就好 接下来贴源代码: PinnedHeade ...

  6. iOS仿QQ分组效果

    本篇主要讲解仿QQ分组效果的实现,通过本遍的学习,估计都可以自己去实现了(老司机可以),在这里只说仿QQ分组的效果,代码简单,逻辑清晰.其他的功能的可以自行添加,好了,进入主题吧. 效果图 下面的是其 ...

  7. android 仿qq好友列表分组效果及联系人分组效果

     历史记录仿QQ好友列表的动态效果 以及联系人的分组效果 QQ朋友分组的功能做的不错,大家都很认可,那么到底他的分组并且滑动的时候,标题能停留在顶部是如何实现的呢?今天从网上搜索了一下资料,自己运行了 ...

  8. html仿qq最小化怎么实现,JS仿QQ好友列表展开、收缩功能(第一篇)

    JS仿QQ好友列表展开.收缩功能(第一篇) 发布时间:2020-10-17 14:20:03 来源:脚本之家 阅读:96 作者:erdouzhang 效果图如下所示: html: 我的好友 张三 李四 ...

  9. 仿QQ好友列表,QListWidget!

    仿QQ好友列表, 设计逻辑: 设计qqItem类,再添加到widget中: 设计时布局等可以直接在ui中设计:内容设计通过代码实现: qqItem.cpp #include "qqitem. ...

最新文章

  1. easyui英文提示变中文
  2. 火星上的甲烷从哪里来,科学家用算法给出了答案
  3. powerpoint文字教程
  4. 天池 在线编程 寻找比周围都大的点(模拟)
  5. python语言在大数据分析处理领域应用广泛_在大数据分析/挖掘领域,哪些编程语言应用最多...
  6. element的表格index自定义_vue+element-ui实现表格编辑的三种实现方式
  7. Android 系统性能优化(47)---Traceview
  8. 拳王虚拟项目公社:闲鱼操作虚拟资源的案例拆解,教你玩转闲鱼虚拟资源,货源+方法
  9. 单机千万并发连接实战(修订版)
  10. 博科:物理与虚拟网络的统一管理
  11. openssl/ssl.h,No such file or directory
  12. python怎么设置为中文-python如何设置中文界面
  13. Java练习题11.2 方法的重载
  14. 关于C语言常量需要注意的点
  15. (Android) 日志打印 Log的使用
  16. Newifi路由刷机R6830
  17. 为你的整轨APE音乐制作CUE文件(图文)
  18. 0基础可不可以学大数据
  19. C语言字母排序不分大小写,求助C语言字母不分大小写排序
  20. 算术右移与逻辑右移的转换

热门文章

  1. NVIDIA JETSON TX2 开发板刷机
  2. 安卓CountDownTimer实现全民夺宝抢购倒计时和短信验证码倒计时
  3. 基于MIPS的五级流水线微处理器(CPU)设计、modelsim仿真通过、verilog编写
  4. 产品经理适合创业,项目经理适合打工
  5. CONTINUE...?
  6. 伪造免费 WiFi 盗你账号密码
  7. 如何查看笔记本南桥温度/AIDA64查看南桥温度
  8. msf生成linux shellcode,使用MSF打造各种ShellCode
  9. 【临时重发】复旦大学 在职软件工程硕士(双证)2017年入学考试 参考书推荐...
  10. 企业是否要做软件许可证授权管理