①MainActivity的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="match_parent">
<ExpandableListView
android:id="@+id/expandableListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@null"/>
</RelativeLayout>
②MainActivity代码实现
代码比较简单需要注意的就是自动展开二级列表的用法
1>onResume方法中遍历展开二级列表,并且去掉系统自带的下拉箭头
2>在适配器中屏蔽掉group一级列表的点击事件
package com.dcg.researchexpandablelistview;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private List<String> groupArray;
private List<List<String>> childArray;
private ExpandableListView expandableListView;
private ExpandListAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
initView();
}
private void initData() {
groupArray = new ArrayList<String>();
childArray = new ArrayList<List<String>>();
groupArray.add("第一行");
groupArray.add("第二行");
List<String> tempArray = new ArrayList<String>();
tempArray.add("第一条");
tempArray.add("第二条");
tempArray.add("第三条");
for (int index = 0; index < groupArray.size(); ++index) {
childArray.add(tempArray);
}
}
private void initView() {
expandableListView = (ExpandableListView) findViewById(R.id.expandableListView);
adapter = new ExpandListAdapter(MainActivity.this, groupArray, childArray);
expandableListView.setAdapter(adapter);
expandableListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
Toast.makeText(MainActivity.this, "第" + childPosition + "条被点击了", Toast.LENGTH_SHORT).show();
return false;
}
});
}
@Override
protected void onResume() {
super.onResume();
//设置自动展开
//自动展开必须写在onResume方法中,否则会发生错误
for (int i = 0; i < adapter.getGroupCount(); i++) {
expandableListView.expandGroup(i);
}
//将ExpandableListView groupitem中系统自带的下拉箭头图标去掉
expandableListView.setGroupIndicator(null);
}
}
③适配器
package com.dcg.researchexpandablelistview;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
/**
* Created by Gu on 2017/10/26.
*/
public class ExpandListAdapter extends BaseExpandableListAdapter {
private List<String> groupArray;
private List<List<String>> childArray;
private LayoutInflater inflate;
public ExpandListAdapter(Context context, List<String> groupArray, List<List<String>> childArray) {
this.inflate = LayoutInflater.from(context);
this.groupArray = groupArray;
this.childArray = childArray;
}
//返回一级列表的个数
@Override
public int getGroupCount() {
return groupArray == null ? 0 : groupArray.size();
}
//返回每个二级列表的个数
@Override
public int getChildrenCount(int groupPosition) {
//参数groupPosition表示第几个一级列表
return childArray.get(groupPosition) == null ? 0 : childArray.get(groupPosition).size();
}
//返回一级列表的单个item(返回的是对象)
@Override
public Object getGroup(int groupPosition) {
return groupArray.get(groupPosition);
}
//返回二级列表中的单个item(返回的是对象)
@Override
public Object getChild(int groupPosition, int childPosition) {
return childArray.get(groupPosition).get(childPosition);
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
//每个item的id是否是固定?一般为true
@Override
public boolean hasStableIds() {
return true;
}
//【重要】填充一级列表
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
HeadViewHolder headViewHolder = null;
if (convertView == null) {
convertView = inflate.inflate(R.layout.item_group, parent, false);
headViewHolder = new ExpandListAdapter.HeadViewHolder(convertView);
convertView.setTag(headViewHolder);
} else {
headViewHolder = (ExpandListAdapter.HeadViewHolder) convertView.getTag();
}
//设置为groupitem不能点击,实现保持两级list一直展开的状态。
convertView.setClickable(true);
headViewHolder.tv_group.setText(groupArray.get(groupPosition));
return convertView;
}
static class HeadViewHolder {
private TextView tv_group;
public HeadViewHolder(View convertView) {
tv_group = (TextView) convertView.findViewById(R.id.tv_group);
}
}
//【重要】填充二级列表
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
ChildViewHolder childViewHolder = null;
if (convertView == null) {
convertView = inflate.inflate(R.layout.item_child, parent, false);
childViewHolder = new ExpandListAdapter.ChildViewHolder(convertView);
convertView.setTag(childViewHolder);
} else {
childViewHolder = (ExpandListAdapter.ChildViewHolder) convertView.getTag();
}
//childViewHolder.iv_child.setImageResource(resId);
childViewHolder.tv_child.setText(childArray.get(groupPosition).get(childPosition));
return convertView;
}
static class ChildViewHolder {
private ImageView iv_child;
private TextView tv_child;
public ChildViewHolder(View convertView) {
iv_child = (ImageView) convertView.findViewById(R.id.iv_child);
tv_child = (TextView) convertView.findViewById(R.id.tv_child);
}
}
//二级列表中的item是否能够被选中?可以改为true
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
④item布局
item_group
<?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="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tv_group"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_marginLeft="8dp"
android:gravity="center"
android:text="group text"
android:textColor="#000000" />
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="#cccccc" />
</LinearLayout>
item_child
<?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="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="18dp"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:id="@+id/iv_child"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@mipmap/ic_launcher" />
<TextView
android:id="@+id/tv_child"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="item text"
android:textColor="#000000" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:layout_marginLeft="18dp"
android:background="#cccccc" />
</LinearLayout>
csdn上传demo,分类选择列表一直没法选择,不能够上传,demo以后再补上吧。
二、好了使用比较简单下面探讨项目中使用遇到的问题
问题一、
如图,腾讯云的最近页面展示最新上传的文件,也是listview的二级列表,留意下会发现一个很有意思的问题,childArray的数据类型不同,有的的单个的Entity展示一行,有的是Entitys组成的list充当childArray的item布局,这种情况下怎么装载数据,怎么返回child的个数和item???
// 整合数据,beans为adapter传入的初步数据源
private List<Object> data = new ArrayList<Object>();
// 把数据装载同一个list里面,这里把所有数据都转为object类型是为了装载同一个list里面好进行排序
ArrayList<NearestFileEntity.DataBean> imgEntitys = new ArrayList<NearestFileEntity.DataBean>();
ArrayList<NearestFileEntity.DataBean> otherEntitys = new ArrayList<NearestFileEntity.DataBean>();
for (int m = 0; m < beans.size(); m++) {
String type = beans.get(m).getSource_type();
if (type.equalsIgnoreCase("jpg") || type.equalsIgnoreCase("png") || type.equalsIgnoreCase("gif")
|| type.equalsIgnoreCase("jpeg")) {
imgEntitys.add(beans.get(m));
} else {
otherEntitys.add(beans.get(m));
}
}
data.addAll(otherEntitys);
if (imgEntitys.size() >= 2) {
data.add(imgEntitys);
}
if (imgEntitys.size() == 1) {
data.add(imgEntitys.get(0));
}
// 如有需要还可以自定义比较器按时间排序来填充数据
// Collections.sort(data, new MyComparator());
其基本原理就是将数据统一按object处理,很好的解决了getChildrenCount和getChild的问题,下面就是数据的使用
ViewHolder holder = null;
if (convertView == null) {
convertView = inflater.inflate(R.layout.item_nearest_lv_lv, parent, false);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Object object = data.get(position);
if (object instanceof NearestFileEntity.DataBean) {
//数据源是单个的entity处理
NearestFileEntity.DataBean bean = (DataBean) object;
} else {
//数据源是多个entity组成的list
ArrayList<NearestFileEntity.DataBean> entity = (ArrayList<DataBean>) object;
}
return convertView;
问题二、原生的OKHttp怎么在get请求的时候添加params
Request.Builder reqBuild = new Request.Builder();
HttpUrl.Builder urlBuilder = HttpUrl.parse(Constant.QUERE_FILES).newBuilder();
urlBuilder.addQueryParameter("uid", SharePreferencesOperate.getInstance().ReadStringFromPreferences(getActivity(), "uid"));
urlBuilder.addQueryParameter("start_date", getTime(System.currentTimeMillis()));
urlBuilder.addQueryParameter("end_date", getTime(System.currentTimeMillis() + 1000L * 3600 * 24 * 30));
Request request = reqBuild.url(urlBuilder.build()).build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onResponse(Call arg0, Response response) throws IOException {
final String result = response.body().string();
if (result != null && !result.equals("")) {
NearestFileEntity entity = gson.fromJson(result, NearestFileEntity.class);
if (entity.isSuccess()) {
List<NearestFileEntity.DataBean> datas = entity.getData();
}
}
}
@Override
public void onFailure(Call arg0, IOException arg1) {
}
});