版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_25815655/article/details/80376589
先上个效果图:
1,我用的fragment
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.dami.student.ui.chatui.adapter.ContactsExpandableListAdapter;
import com.dami.student.R;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import com.dami.student.entity.AccountInformation;
import android.widget.ExpandableListView;
import com.dami.student.entity.ClassEntity;
import com.dami.student.entity.ClassMembers;
import com.dami.student.net.database.OperationDB;
import com.dami.student.net.socket.SendDataSocketInterface;
import com.dami.student.net.socket.SocketService;
import com.dami.student.net.utils.BusinessCallbackBase;
import com.dami.student.net.utils.BusinessCallbackInterfaceUtil;
import com.dami.student.net.utils.CommandPackage;
import com.dami.student.net.utils.LogUtil;
import com.dami.student.ui.chatui.adapter.SortClassMemberAdapter;
import com.dami.student.ui.chatui.ui.activity.PrivateChatActivity;
import com.dami.student.ui.chatui.util.CharacterParser;
import com.dami.student.ui.chatui.util.ClearEditText;
import com.dami.student.ui.chatui.util.PinyinComparator;
import android.widget.ExpandableListView.OnChildClickListener;
public class ContactsFragmentExpandableListView extends Fragment {
private boolean isDebug = true;
private String TAG = "ContactsFragmentExpandableListView";
private ContactsEntityBusinessCallback mContactsEntityBusinessCallback;
private View contactsFragmentView;
private Context mContext;
private List<List<?>> mGroupMemberList = new ArrayList<List<?>>();
//群组名称
private String[] mGroup = new String[] { "家庭群", "班级群"};
private List<AccountInformation> mAccountInformationList = new ArrayList<AccountInformation>();
private ExpandableListView mExpandableListView;
private List<ClassMembers> mClassMembersList;
private ContactsExpandableListAdapter mContactsExpandableListAdapter;
public ClearEditText mClearEditText;
private ClassEntity mClassEntity;
private int sequence;
private byte[] data;
private boolean flag;
/**
* 汉字转换成拼音的类
*/
private CharacterParser characterParser;
/**
* 根据拼音来排列ListView里面的数据类
*/
private PinyinComparator pinyinComparator;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
contactsFragmentView = inflater.inflate(R.layout.fragment_contacts_expandablelistview,
container, false);
findViewById();
inIt();
return contactsFragmentView;
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
BusinessCallbackInterfaceUtil.remove(mContactsEntityBusinessCallback);
}
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
// 根据a-z进行排序
//mClassMembersList = filledData(mClassMembersList);
mGroupMemberList.clear();
LogUtil.i(TAG, "wdh handleMessage"+mAccountInformationList);
mGroupMemberList.add(mAccountInformationList);
mGroupMemberList.add(mClassMembersList);
mContactsExpandableListAdapter.updateExpandableListView(mGroup,mGroupMemberList);
for (int i = 0; i < mClassMembersList.size(); i++) {
OperationDB.getInstance(mContext).setClassMenberEntity(
mClassMembersList.get(i));
}
break;
default:
break;
}
};
};
private void findViewById() {
// TODO Auto-generated method stub
mExpandableListView = (ExpandableListView) contactsFragmentView
.findViewById(R.id.group_expandableListView);
mClearEditText = (ClearEditText) getActivity().findViewById(
R.id.filter_edit);
}
private void inIt() {
// TODO Auto-generated method stub
// 实例化汉字转拼音类
characterParser = CharacterParser.getInstance();
pinyinComparator = new PinyinComparator();
mContext = getActivity();
mClassEntity = OperationDB.getInstance(mContext).QueryClassEntity();
mAccountInformationList.addAll(0, OperationDB.getInstance(mContext).getUserData(0));
mAccountInformationList.addAll(1, OperationDB.getInstance(mContext).getUserData(1));
mGroupMemberList.add(mAccountInformationList);
if (mClassEntity.className != null) {
mClassMembersList = filledData(OperationDB.getInstance(mContext)
.QueryClassMenberEntity(1,mClassEntity.classId,mClassEntity.classId));
if (null != mClassMembersList && mClassMembersList.size() != 0) {
mGroupMemberList.add(mClassMembersList);
}
}
LogUtil.i(TAG, "wdh mGroupMemberList "+mGroupMemberList.size());
LogUtil.i(TAG, "wdh mGroupMemberList "+mGroupMemberList);
mContactsExpandableListAdapter = new ContactsExpandableListAdapter(mContext,
mGroup,mGroupMemberList);
mExpandableListView.setAdapter(mContactsExpandableListAdapter);
mExpandableListView.setGroupIndicator(null);
mExpandableListView.setOnChildClickListener(new OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
// TODO Auto-generated method stub
Object object = mGroupMemberList.get(groupPosition).get(childPosition);
LogUtil.i(TAG, "wdh --onChildClick---- "+object);
Intent intent = new Intent(mContext, PrivateChatActivity.class);
if (object instanceof ClassMembers) {
intent.putExtra("object", (ClassMembers)object);
startActivity(intent);
}else if (object instanceof AccountInformation) {
ClassMembers classMembers = new ClassMembers();
AccountInformation mAccountInformation = (AccountInformation)object;
classMembers.setMemberId(mAccountInformation.getUserId());
classMembers.setName(mAccountInformation.getUserName());
classMembers.setPhone(mAccountInformation.getPhoneNum());
classMembers.setHeadImg(mAccountInformation.getHeadPortrait());
classMembers.setRelation(mAccountInformation.getRelation());
intent.putExtra("object", classMembers);
startActivity(intent);
}
return false;
}
});
mContactsEntityBusinessCallback = new ContactsEntityBusinessCallback();
BusinessCallbackInterfaceUtil
.setCallBack(mContactsEntityBusinessCallback);
// 根据输入框输入值的改变来过滤搜索
mClearEditText.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
// 当输入框里面的值为空,更新为原来的列表,否则为过滤数据列表
filterData(s.toString());
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
LogUtil.i(TAG, "wdh mClassEntity.classId =" + mClassEntity.classId);
sequence = SocketService.getSequence();
data = CommandPackage.getInstance().queryClass(sequence,
mClassEntity.classId, 0);
flag = SendDataSocketInterface.sendCallBack(data, 0);
if (isDebug) {
Log.i(TAG,
"===wdh==getDeviceId====="
+ OperationDB.getInstance(getActivity())
.getDeviceId() + "sequence==" + sequence
+ "==flag====" + flag + " mClassEntity.classId "
+ mClassEntity.classId);
}
}
/**
* 为ListView填充数据
*
* @param date
* @return
*/
private List<ClassMembers> filledData(List<ClassMembers> classMembersList) {
if (classMembersList.size() > 0) {
for (int i = 0; i < classMembersList.size(); i++) {
classMembersList.get(i).setName(
classMembersList.get(i).getName());
// 汉字转换成拼音
String pinyin = characterParser.getSelling(classMembersList
.get(i).getName());
String sortString = pinyin.substring(0, 1).toUpperCase();
// 正则表达式,判断首字母是否是英文字母
if (sortString.matches("[A-Z]")) {
classMembersList.get(i).setSortLetters(
sortString.toUpperCase());
} else {
classMembersList.get(i).setSortLetters("#");
}
}
}
return classMembersList;
}
/**
* 根据输入框中的值来过滤数据并更新ListView
*
* @param filterStr
*/
private void filterData(String filterStr) {
if (null == mClassMembersList || mClassMembersList.size() < 1) {//无数据,不搜索
return;
}
List<ClassMembers> filterDateList = new ArrayList<ClassMembers>();
if (TextUtils.isEmpty(filterStr)) {
filterDateList = mClassMembersList;
} else {
filterDateList.clear();
for (ClassMembers classMembers : mClassMembersList) {
String name = classMembers.getName();
if (name.indexOf(filterStr.toString()) != -1
|| characterParser.getSelling(name).startsWith(
filterStr.toString())) {
filterDateList.add(classMembers);
}
}
}
// 根据a-z进行排序
Collections.sort(filterDateList, pinyinComparator);
mGroupMemberList.add(mClassMembersList);
mContactsExpandableListAdapter.updateExpandableListView(mGroup,mGroupMemberList);
}
class ContactsEntityBusinessCallback extends BusinessCallbackBase {
@Override
public void onClassMenbers(int result,
ArrayList<ClassMembers> contactsList, int sequence) {
// TODO Auto-generated method stub
super.onClassMenbers(result, contactsList, sequence);
Log.i(TAG, "wdh ===contactsList.size()===" + contactsList.size());
if (0 == result) {
if (isDebug)
Log.i(TAG, "wdh contactsList:" + contactsList);
mClassMembersList = contactsList;
Message message = Message.obtain();
message.what = 1;
mHandler.sendMessage(message);
}
}
}
}
2,adapter,当然是继承BaseExpandableListAdapter
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.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import com.dami.student.net.socket.SocketService;
import com.dami.student.entity.AccountInformation;
import com.bumptech.glide.Glide;
import android.content.Intent;
import android.net.Uri;
import com.dami.student.R;
import com.dami.student.net.utils.LogUtil;
import com.dami.student.entity.ClassMembers;
import com.dami.student.ui.chatui.widget.CircleImageView;
public class ContactsExpandableListAdapter extends BaseExpandableListAdapter
implements OnClickListener {
private String Tag = "ContactsExpandableListAdapter";
private String[] mGroup;// 大组组名
private List<List<?>> mGroupMemberList; // 小组List,群组成员,可以使不同list,例如List<联系人>,List<家庭群>都可以放里面
private Context mContext;
private LayoutInflater mInflater;
private int mGroupPosition;
public ContactsExpandableListAdapter(Context context, String[] group,
List<List<?>> groupMemberList) {
this.mContext = context;
this.mGroup = group;
this.mGroupMemberList = groupMemberList;
}
public void updateExpandableListView(String[] group,
List<List<?>> groupMemberList) {
this.mGroup = group;
this.mGroupMemberList = groupMemberList;
notifyDataSetChanged();
}
//得到大组成员总数
@Override
public int getGroupCount() {
// TODO Auto-generated method stub
return mGroup.length;
}
//得到小组成员的数量
@Override
public int getChildrenCount(int groupPosition) {
// TODO Auto-generated method stub
return mGroupMemberList.get(groupPosition).size();
}
//得到大组成员对象
@Override
public Object getGroup(int groupPosition) {
// TODO Auto-generated method stub
return mGroup[groupPosition];
}
//得到小组成员对象
@Override
public Object getChild(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return mGroupMemberList.get(groupPosition).get(childPosition);
}
//得到大组成员对象id
@Override
public long getGroupId(int groupPosition) {
// TODO Auto-generated method stub
return groupPosition;
}
//得到小组成员对象id
@Override
public long getChildId(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return childPosition;
}
/**
* Indicates whether the child and group IDs are stable across changes to the
* underlying data.
* 表明大組和小组id是否稳定的更改底层数据。
* @return whether or not the same ID always refers to the same object
* @see Adapter#hasStableIds()
*/
@Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return false;
}
// 设置子列表是否可选中,保存groupPosition以便child里面的item里面的button写点击事件
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
LogUtil.i(Tag, "wdh groupPosition ="+groupPosition);
mGroupPosition = groupPosition;
return true;
}
//得到大组成员的view
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolderGroup groupHolder;
if (null == convertView) {
convertView = mInflater.from(mContext).inflate(
R.layout.expandableliseview_grorp_item, parent, false);
groupHolder = new ViewHolderGroup();
groupHolder.group_name_tv = (TextView) convertView
.findViewById(R.id.group_name_TV);
groupHolder.open_close_group_IM = (ImageView) convertView
.findViewById(R.id.open_close_group_IM);
convertView.setTag(groupHolder);
} else {
groupHolder = (ViewHolderGroup) convertView.getTag();
}
groupHolder.open_close_group_IM.setImageResource(isExpanded ? R.drawable.open_group:R.drawable.close_group);
groupHolder.group_name_tv.setText(mGroup[groupPosition]);
return convertView;
}
//得到小组成员的view
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolderChild childHolder;
if (null == convertView) {
convertView = mInflater.from(mContext).inflate(
R.layout.item_class_member, parent, false);
childHolder = new ViewHolderChild();
childHolder.tvTitle = (TextView) convertView
.findViewById(R.id.title);
childHolder.contactsPic = (CircleImageView) convertView
.findViewById(R.id.contactsPic);
childHolder.sendShortMessageIB = (ImageButton) convertView
.findViewById(R.id.send_short_message_IB);
childHolder.phoneIB = (ImageButton) convertView
.findViewById(R.id.phone_IB);
convertView.setTag(childHolder);
} else {
childHolder = (ViewHolderChild) convertView.getTag();
}
childHolder.sendShortMessageIB.setTag(R.id.send_short_message_IB,
childPosition);
childHolder.sendShortMessageIB.setOnClickListener(this);
childHolder.phoneIB.setTag(R.id.phone_IB, childPosition);
childHolder.phoneIB.setOnClickListener(this);
LogUtil.i(Tag, "wdh ------groupPosition "+groupPosition);
Object object = mGroupMemberList.get(groupPosition).get(childPosition);
LogUtil.i(Tag, "wdh ------object "+object);
if (null != object) {
if (object instanceof ClassMembers) {
if (null == ((ClassMembers) object).getHeadImg()) {
childHolder.contactsPic
.setImageResource(R.drawable.group_member_icon_default);
} else {
childHolder.contactsPic
.setImageResource(R.drawable.group_member_icon_default);
}
if (((ClassMembers) object).getRelation() != null
&& ((ClassMembers) object).getRelation().trim().length() > 0) {
childHolder.tvTitle.setText(((ClassMembers) object).getName()
+ " -- " + ((ClassMembers) object).getRelation());
} else {
childHolder.tvTitle.setText(((ClassMembers) object).getName());
}
} else if (object instanceof AccountInformation) {
Glide.with(mContext).load(SocketService.FILE_UPLOAD_URL+((AccountInformation) object).getHeadPortrait()).error
(mContext.getResources().getDrawable(R.drawable.group_member_icon_default)).into(childHolder.contactsPic);
if (((AccountInformation) object).getRelation() != null
&& ((AccountInformation) object).getRelation().trim().length() > 0) {
childHolder.tvTitle.setText(((AccountInformation) object).getUserName()
+ " -- " + ((AccountInformation) object).getRelation());
} else {
childHolder.tvTitle.setText(((AccountInformation) object).getUserName());
}
}
}
return convertView;
}
//大组成员
private static class ViewHolderGroup {
TextView group_name_tv;
ImageView open_close_group_IM;
}
//小组成员
final static class ViewHolderChild {
TextView tvLetter;
CircleImageView contactsPic;
TextView tvTitle;
ImageButton sendShortMessageIB;
ImageButton phoneIB;
}
//小组成员里面的button
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
int position = 0;
switch (v.getId()) {
case R.id.send_short_message_IB:
position = (int)v.getTag(R.id.send_short_message_IB);
LogUtil.i(Tag, "wdh 位置 sendShortMessageIB" +
v.getTag(R.id.send_short_message_IB));
Object object = mGroupMemberList.get(mGroupPosition).get(position);
Uri uri = null;
if (object instanceof ClassMembers) {
uri =Uri.parse("smsto:" + ((ClassMembers)object).getPhone());
}else if (object instanceof AccountInformation) {
uri =Uri.parse("smsto:" + ((AccountInformation)object).getPhoneNum());
}
if (null != uri) {
Intent shortMessageIntent = new Intent(Intent.ACTION_VIEW, uri);
mContext.startActivity(shortMessageIntent);
}
break;
case R.id.phone_IB:
LogUtil.i(Tag, "wdh 位置 phoneIB" + v.getTag(R.id.phone_IB));
position = (int)v.getTag(R.id.phone_IB);
Object phoneObject = mGroupMemberList.get(mGroupPosition).get(position);
Intent callIntent = null;
if (phoneObject instanceof ClassMembers) {
callIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" +((ClassMembers)phoneObject).getPhone()));
}else if (phoneObject instanceof AccountInformation) {
callIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" +((AccountInformation)phoneObject).getPhoneNum()));
}
if (null != callIntent) {
mContext.startActivity(callIntent);
}
break;
default:
break;
}
}
}
3,fragment布局fragment_contacts_expandablelistview.xml
<?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"
android:background="@color/white">
<ExpandableListView
android:id="@+id/group_expandableListView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:dividerHeight="1dp"
android:divider="#E0E0E0" />
</LinearLayout>
4,这个是大的分组的布局expandableliseview_grorp_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="40dp"
android:gravity="center_vertical" >
<ImageView
android:id="@+id/open_close_group_IM"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="13dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
/>
<TextView
android:id="@+id/group_name_TV"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/open_close_group_IM"
android:layout_marginLeft="12dp"
android:textSize="15sp"
android:layout_centerVertical="true"
android:textColor="#333333"/>
</RelativeLayout>
5,小的分组的布局,就是item布局item_class_member.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="47dp"
android:gravity="center_vertical"
android:descendantFocusability="blocksDescendants"
android:orientation="vertical" >
<TextView
android:id="@+id/catalog"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#E0E0E0"
android:textColor="#999999"
android:layout_weight="1.0"
android:paddingLeft="5dip"
android:paddingTop="5dip"
android:paddingBottom="5dip"
android:text="@string/camera_shooting"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="57dp"
android:orientation="horizontal"
android:gravity="center_vertical">
<com.dami.student.ui.chatui.widget.CircleImageView
android:id="@+id/contactsPic"
android:layout_width="41dp"
android:layout_height="41dp"
android:layout_marginLeft="4dp"
android:layout_weight="1">
</com.dami.student.ui.chatui.widget.CircleImageView>
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:textColor="#333333"
android:layout_weight="6"
android:textSize="15sp"
android:text="@string/hold_to_talk"/>
<ImageButton
android:id="@+id/send_short_message_IB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="4dp"
android:focusable="false"
android:clickable="true"
android:scaleType="fitXY"
android:background="@drawable/send_short_message"/>
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.5"/>
<ImageButton
android:id="@+id/phone_IB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false"
android:clickable="true"
android:scaleType="fitXY"
android:background="@drawable/phone"/>
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"/>
</LinearLayout >
</LinearLayout>
参考文章:https://www.aliyun.com/jiaocheng/111569.html
https://blog.csdn.net/xyzz609/article/details/51975416
https://blog.csdn.net/way_ping_li/article/details/7995552