Hello!各位大神好,这是我的第一篇博客,大二学生初学安卓还不到几个月,所以希望不足之处能够多多指教。
在Android开发中,我们经常会遇到点击,展开,可拓展列表的使用,同时可恶的产品经理还要求你在可拓展列表下增加左滑按钮的功能。那这两个功能如何具体相互结合实现呢?接下来先看一下结果效果图。
怎么样?是不是你想要的呢?
接下来我们分两步来看一下这个功能。
首先是可拓展列表ExpandableListView的功能实现。
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical">
<com.easeplan.com.view.SwipeExpandableListView
android:id="@+id/exlist_lol"
android:childIndicator="@null"
android:groupIndicator="@null"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:childDivider="#ffffff"/>
</LinearLayout>
有注意到,我调用的SwipeExpandableListView是一个用java自定义的布局,由于代码太长我就不发出来了,有需要的小伙伴可在下面留言。
item_exlist_group.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="horizontal"
android:padding="5dp">
<ImageView
android:id="@+id/img_icon1"
android:layout_width="64dp"
android:layout_height="58dp"
android:src="@mipmap/ic_launcher"
android:focusable="false"
android:paddingLeft="6dp"
/>
<TextView
android:id="@+id/tv_group_name"
android:layout_width="match_parent"
android:layout_height="56dp"
android:gravity="center_vertical"
android:paddingLeft="12dp"
android:text="AP"
android:textStyle="bold"
android:textSize="20sp" />
</LinearLayout>
可以看到,在这个布局中,我是设置了一个图片作为头像,还有文字作为标题。而图片可以换成你想要的,但是也可以在java代码中设置。而我是选择了在java代码中设置。
接着是左滑按钮的实现。
item_exlist_item.xml
<?xml version="1.0" encoding="utf-8"?>
<com.easeplan.com.view.SwipeItemLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--子列表布局-->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="270dp"
android:layout_height="59dp"
android:orientation="horizontal"
android:layout_gravity="right"
android:id="@+id/linear">
<!--垂直布局-->
<LinearLayout
android:layout_width="270dp"
android:layout_height="59dp"
android:orientation="vertical"
android:background="@drawable/shape2"
android:id="@+id/id_front">
<TextView
android:id="@+id/tv_name"
android:layout_width="270dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:focusable="true"
android:text="提莫"
android:textSize="18sp"
android:gravity="left"
android:paddingTop="6dp"
android:paddingLeft="9dp"
android:textColor="#ffffff"/>
<TextView
android:layout_width="270dp"
android:layout_height="wrap_content"
android:focusable="true"
android:textSize="10sp"
android:text="提莫"
android:gravity="left"
android:paddingBottom="10dp"
android:paddingLeft="12dp"
android:id="@+id/tv_msg"
android:textColor="#ffffff"/>
</LinearLayout>
</LinearLayout>
</FrameLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent">
<Button
android:id="@+id/stick"
android:text="添加到日程"
android:textColor="#ffffff"
android:textSize="16sp"
android:background="#ff8000"
android:layout_width="100dp"
android:layout_height="match_parent"/>
<Button
android:id="@+id/delete"
android:text="删除"
android:textColor="#ffffff"
android:textSize="16sp"
android:background="#ff0000"
android:layout_width="80dp"
android:layout_height="match_parent"/>
</LinearLayout>
</com.easeplan.com.view.SwipeItemLayout>
分析代码可知,我是在子item里面设置了垂直方向上的两行文字,接着在线性布局中设置了两个按钮。需要注意是,左滑布局我仍然用的是一个自定义的布局,需要的可以在下方留言。
好啦,布局文件就这么多,至于drawable、values文件还有注册文件就自己写吧。
接下来看一下java代码吧。。。
实体类GroupBean.java
public class GroupBean extends LitePalSupport {
private int gId;
private String gName;//主标题名字
public GroupBean(int gId, String gName) {
this.gName = gName;
this.gId=gId;
}
public int getgId() {
return gId;
}
public void setgId(int gId) {
this.gId = gId;
}
public String getgName() {
return gName;
}
public void setgName(String gName) {
this.gName = gName;
}
}
实体类Item.java
public class Item {
private String iName;//文字名字
private String iMsg;//文字信息
public Item() {
}
public Item(String iName,String iMsg) {
this.iName = iName;
this.iMsg=iMsg;
}
public String getiName() {
return iName;
}
public String getiMsg(){return iMsg;}
public void setiName(String iName) {
this.iName = iName;
}
public void setiMsg(String iMsg){this.iMsg=iMsg;}
}
适配器MyBaseExpandableListViewAdapter.java
public class MyBaseExpandableListViewAdapter extends BaseExpandableListAdapter {
private ArrayList<GroupBean> gData;
private ArrayList<ArrayList<Item>> iData;
private Context mContext;
private OnClickListenerEditOrDelete onClickListenerEditOrDelete;
private boolean text_add=false;
public MyBaseExpandableListViewAdapter(ArrayList<GroupBean> gData, ArrayList<ArrayList<Item>> iData, Context mContext) {
this.gData = gData;
this.iData = iData;
this.mContext = mContext;
}
@Override
public int getGroupCount() {
return gData.size();
}
@Override
public int getChildrenCount(int groupPosition) {
return iData.get(groupPosition).size();
}
@Override
public GroupBean getGroup(int groupPosition) {
return gData.get(groupPosition);
}
@Override
public Item getChild(int groupPosition, int childPosition) {
return iData.get(groupPosition).get(childPosition);
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public boolean hasStableIds() {
return false;
}
//返回分组的视图对象
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
ViewHolderGroup groupHolder;
if(convertView == null){
convertView = LayoutInflater.from(mContext).inflate(
R.layout.item_exlist_group, parent, false);
groupHolder = new ViewHolderGroup();
groupHolder.tv_group_name = (TextView) convertView.findViewById(R.id.tv_group_name);//文字
groupHolder.img_group = (ImageView) convertView.findViewById(R.id.img_icon1);//图片
convertView.setTag(groupHolder);
}else{
groupHolder = (ViewHolderGroup) convertView.getTag();
}
//文字与图片显示
groupHolder.img_group.setImageResource(gData.get(groupPosition).getgId());
groupHolder.tv_group_name.setText(gData.get(groupPosition).getgName());
return convertView;
}
//取得显示给定分组给定子位置的数据用的视图
@Override
public View getChildView( final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
final ViewHolderItem itemHolder;
if(convertView == null){
convertView = LayoutInflater.from(mContext).inflate(
R.layout.item_exlist_item, parent, false);
itemHolder = new ViewHolderItem();
itemHolder.tv_name = (TextView) convertView.findViewById(R.id.tv_name);//子列表中上标题
itemHolder.tv_msg = (TextView) convertView.findViewById(R.id.tv_msg);//子列表中下标题
itemHolder.linear=convertView.findViewById(R.id.linear);//整个子列表
itemHolder.delete=(Button)convertView.findViewById(R.id.delete);//删除按钮
itemHolder.add=(Button)convertView.findViewById(R.id.stick);//添加到日程按钮
convertView.setTag(itemHolder);
itemHolder.linear.setOnClickListener(new View.OnClickListener() {//子列表按钮
@Override
public void onClick(View v) {
Intent intent=new Intent(mContext,EventInfoActivity.class);//点击Item可跳转的界面
mContext.startActivity(intent);
}
});
itemHolder.delete.setOnClickListener(new View.OnClickListener() {//删除按钮
@Override
public void onClick(View v) {//删除对话框
AlertDialog alert=new AlertDialog.Builder(mContext).create();
alert.setIcon(R.drawable.ic_notifications_black_24dp);
alert.setTitle("请问您确定要删除吗?");
alert.setButton(DialogInterface.BUTTON_POSITIVE, "确定", new DialogInterface.OnClickListener() {//点击确定删除后
@Override
public void onClick(DialogInterface dialog, int which) {
if (onClickListenerEditOrDelete!=null){
onClickListenerEditOrDelete.OnClickListenerDelete(groupPosition,childPosition);
}
}
});
alert.setButton(DialogInterface.BUTTON_NEGATIVE, "取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
alert.show();
}
});
itemHolder.add.setOnClickListener(new View.OnClickListener() {//添加到日程按钮
@Override
public void onClick(View v) {
Toast.makeText(mContext,"添加成功!",Toast.LENGTH_SHORT).show();
}
});
}else{
itemHolder = (ViewHolderItem) convertView.getTag();
}
//子列表文字显示
itemHolder.tv_name.setText(iData.get(groupPosition).get(childPosition).getiName());
itemHolder.tv_msg.setText(iData.get(groupPosition).get(childPosition).getiMsg());
return convertView;
}
//设置子列表是否可选中
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
//自定义Group类
private static class ViewHolderGroup{
private TextView tv_group_name;
private ImageView img_group;
}
//自定义Item类
private static class ViewHolderItem{
private TextView tv_name;
private TextView tv_msg;
private View linear;
private Button delete;
private Button add;
}
//删除接口
public interface OnClickListenerEditOrDelete{
void OnClickListenerDelete(int groupPosition, int position);
}
public void setOnClickListenerEditOrDelete(OnClickListenerEditOrDelete onClickListenerEditOrDelete1){
this.onClickListenerEditOrDelete=onClickListenerEditOrDelete1;
}
}
碎片Fragment中的代码,具体需要的同学可以改成activity
Fragment_people.java
public class Fragment_people extends Fragment {
private ArrayList<GroupBean> gData = null;//group
private ArrayList<ArrayList<Item>> iData = null;//item列表
private ArrayList<Item> lData = null;//item
private Context mContext;//相当于fragment_people.this
private SwipeExpandableListView exlist_lol;//group
private MyBaseExpandableListViewAdapter myAdapter = null;//item适配器
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.mfragment_people, container, false);
return view;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mContext = getActivity();
exlist_lol = (SwipeExpandableListView) getActivity().findViewById(R.id.exlist_lol);
linear = (View) getActivity().findViewById(R.id.linear);//最近的组织获得实例
delete = (Button) getActivity().findViewById(R.id.delete);//最近的好友获得实例
//TODO:这数据是初始化的,动态到时候需要后台连接
//可拓展列表头部图片和文字定义
gData = new ArrayList<GroupBean>();
iData = new ArrayList<ArrayList<Item>>();
gData.add(new GroupBean(R.mipmap.xiaokui, "学生会秘书处"));
gData.add(new GroupBean(R.mipmap.yingyu, "大学英语—34班"));
gData.add(new GroupBean(R.mipmap.chengxuyuan, "鸣黄柳"));
gData.add(new GroupBean(R.mipmap.xiaohuangren, "bami"));
//学生会秘书处
lData = new ArrayList<Item>();
lData.add(new Item("写策划案", "10月12日-11月05日"));
lData.add(new Item("社团聚会", "10月20日"));
iData.add(lData);//因为子列表有多个,所以需要lData.
//大学英语34班
lData = new ArrayList<Item>();
lData.add(new Item("提交作文", "10月18日"));
lData.add(new Item("阅读第三单元", "10月19日12:00"));
lData.add(new Item("完成PPT", "11月01日-11月05日"));
iData.add(lData);
//鸣黄柳
lData = new ArrayList<Item>();
lData.add(new Item("完成数构作业", "12月21日"));
lData.add(new Item("购买书籍", "12月18日-12月20日"));
iData.add(lData);
//bami
lData = new ArrayList<Item>();
lData.add(new Item("上吉他课", "11月11日"));
lData.add(new Item("去兼职", "11月12日12:00"));
lData.add(new Item("去西门拿快递", "11月11日17:30"));
iData.add(lData);
//添加适配器
myAdapter = new MyBaseExpandableListViewAdapter(gData, iData, mContext);
exlist_lol.setAdapter(myAdapter);
//删除操作
myAdapter.setOnClickListenerEditOrDelete(new MyBaseExpandableListViewAdapter.OnClickListenerEditOrDelete() {
@Override
public void OnClickListenerDelete(int groupPosition, int position) {
Toast.makeText(mContext, "删除成功!", Toast.LENGTH_SHORT).show();
iData.get(groupPosition).remove(position);//删除选中的某列
if (iData.get(groupPosition).size() <= 0) {//如果删除后,该组下没成员,那么移除标题和该组的数据集合
iData.remove(groupPosition);
gData.remove(groupPosition);
}
myAdapter.notifyDataSetChanged();//通知Adapter更新数据
}
});
for (int i = 0; i < iData.size(); i++) {//首次加载就全部打开
exlist_lol.expandGroup(i);
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
super.onCreateOptionsMenu(menu, inflater);
getActivity().getMenuInflater().inflate(R.menu.people_toolbar,menu);
}
/**标题栏监听事件*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
break;
case R.id.people_add:
Intent intent1=new Intent(getActivity(), Contacts_addActivity.class);
startActivity(intent1);
break;
default:
}
return super.onOptionsItemSelected(item);
}
}
注意:以上的图片是自己要添加进drawable文件夹的哦,标题栏的构造也是需要在menu文件夹下定义的哦。
好啦,大概的代码就是这些。代码里面有参考别人的博客,也有自己思考出来,做出来的东西,希望不足之处可以大方指出来呦。。。