最近使用一个图片API的时候想要弄一个像QQ好友列表那样的效果,然后给图片列表分类,在网上查找资料的时候就发现了ExpandableListView这个控件,然后就顺带发现了这些大佬们的文章,也是看了一下他们怎么使用这个控件的,然后自己实践了一下,下面是文章的地址。
①:Android中ExpandableListView的使用
http://blog.csdn.net/gyflyx/article/details/6461242
②:Android ExpandableListView的技巧和问题
http://www.cnblogs.com/potato-zero/p/5870353.html
③:Android中ExpandableListView的使用(一)
http://blog.csdn.net/sysukehan/article/details/51960473
有兴趣的骚年们可以先去看一看。
首先说一下我用的图片API,下面是我使用的图片API的地址,个人觉得蛮不错的,其中的美女图片也是我想用这个API的主要原因啊:
https://www.showapi.com/api/lookPoint/852/2#price
地址返回的数据是下面这个样子的:
接下来用了GsonFormat自动生成了数据类,然后用Gson去解析,接着用okhttp3去请求网络,当然,权限不能忘
<uses-permission android:name="android.permission.INTERNET"/>
结果非常坑爹,我被一个小疏忽耽误了半个多小时,一定要记住,使用okhttp联网请求返回的response转换成String类型的时候,一定要用respons.body().string而不是response.body().toString();
同时response只能调用一次!如果调用了多次,也是会有问题的。
以上就是使用okhttp最容易出错的两个点。
然后返回的数据我就思考该用什么方式去存储,从上面的图片也可以看有两个方法分别是二维List<>或者二维数组。
一开始使用二维List<>的时候经常被绕晕,然后就寻思着是不是用二位数组方便一些,结果没想到java里面动态设置二位数组更加麻烦,不过好在也是找到一篇不错的文章,然后知道了怎么去设置二位数组。明白二位数组怎么操作之后List当然也就轻松许多。下面是这盘文章的地址,非常简单:
http://blog.csdn.net/u010074743/article/details/53968949
然后先来简单的实操一下吧,首先是布局文件activity_main.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">
<ExpandableListView
android:id="@+id/expandableListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
然后把okhttp3请求网络以及Gson解析数据放在HttpUtil.class中,请求的地址放在Constants.class里:
public class HttpUtil {
//使用okhttp3
public static void sendOkHttpRequest(String url, okhttp3.Callback callback){
OkHttpClient client = new OkHttpClient();
okhttp3.Request request = new okhttp3.Request.Builder()
.url(url)
.build();
client.newCall(request).enqueue(callback);
}
//Gson解析数据
public static AllNameListBean parsedNameLisJsonWithGson(String json){
return new Gson().fromJson(json, AllNameListBean.class);
}
}
接下来在MainActivity去写代码啦,下面存储数据的时候二位数组和List都用到了,可以对比一下:
public class MainActivity extends AppCompatActivity {
private ExpandableListView expandableListView;
private MyExpandableListViewAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
expandableListView = (ExpandableListView) findViewById(R.id.expandableListView);
getDataByokhttp();
}
private void getDataByokhttp(){
HttpUtil.sendOkHttpRequest(Constants.allPicUrl, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
LogUtil.e("失败");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
LogUtil.e("成功");
String data = response.body().string(); //千万千万别写成了toString
AllNameListBean bean = HttpUtil.parsedNameLisJsonWithGson(data); //解析数据
List<String> parentListName = new ArrayList<String>(); //父项name列表
List<String> childListName = new ArrayList<String>(); //子项name列表
List<Integer> childListId = new ArrayList<Integer>(); //子项id列表
List<List<String>> allChildName = new ArrayList<List<String>>(); //使用List<List<>>方法的子项name列表集合
List<List<Integer>> allChildId = new ArrayList<List<Integer>>(); //使用List<List<>>方法的子项id列表集合
List<AllNameListBean.ShowapiResBodyBean.ListBeanX> parentList = bean.getShowapi_res_body().getList(); //父项数据列表
String [][] childArrayName = new String[parentList.size()][]; //子项name数组集合
int [][] childArrayId = new int[parentList.size()][]; //子项id数组集合
for (int i = 0; i < parentList.size(); i ++){
List<AllNameListBean.ShowapiResBodyBean.ListBeanX.ListBean> childList = parentList.get(i).getList(); //子项数据列表
String parentName = parentList.get(i).getName(); //每一个父项的name
parentListName.add(parentName);
String[] childN = new String[childList.size()];
int[] childI = new int[childList.size()];
for (int j = 0; j < childList.size(); j++){
int childId = childList.get(j).getId();
String childName = childList.get(j).getName();
childListId.add(childId);
childListName.add(childName);
childN[j] = childName;
childI[j] = childId;
}
childArrayName[i] = childN;
childArrayId[i] = childI;
allChildName.add(childListName);
allChildId.add(childListId);
}
LogUtil.e("id分别为" + childListId); //LogUtil是一个封装好的打印工具类
LogUtil.e("子项名字分别为——" + childListName);
LogUtil.e("父项名字分别为——" + parentListName);
LogUtil.e(allChildName.get(0).get(0));
adapter = new MyExpandableListViewAdapter(MainActivity.this, parentListName, childArrayName);
runOnUiThread(new Runnable() {
@Override
public void run() {
expandableListView.setAdapter(adapter);
}
});
}
});
}
}
上面用到了ExpandableListView的适配器,适配器传入的数据用的是数组,之后再换成List<>列表类型的(上面两种方法都用到了),虽然效果都一样,但是后者明显简单不少,所以推荐后者。
下面去定义一下适配器:
public class MyExpandableListViewAdapter extends BaseExpandableListAdapter {
private Context context;
private List<String> parentListName;
private String [][] childArrayName;
public MyExpandableListViewAdapter(Context context, List<String> parentListName, String [][] childArrayName) {
this.context = context;
this.parentListName = parentListName;
this.childArrayName = childArrayName;
}
// 获得父项的数量
@Override
public int getGroupCount() {
return parentListName.size();
}
// 获得某个父项的子项数目
@Override
public int getChildrenCount(int groupPosition) {
return childArrayName[groupPosition].length;
}
// 获得某个父项
@Override
public Object getGroup(int groupPosition) {
return parentListName.get(groupPosition);
}
// 获得某个父项的某个子项
@Override
public Object getChild(int groupPosition, int childPosition) {
return childArrayName[groupPosition][childPosition];
}
// 获得某个父项的id
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
// 获得某个父项的某个子项的id
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
/*
如果hasStableIds返回false的话 每次调用notifyDataSetChanged方法时adapter就会判断getItemId 并且在只调用那些Item发生变化的getView方法,
说白了就是通过getItemId来判断那些需要getView从而达到局部刷新的效果,在getView比较耗时的情况下起到优化的效果。
*/
@Override
public boolean hasStableIds() {
return false;
}
// 获得父项显示的view
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
String string = parentListName.get(groupPosition);
return getGenericView(string);
}
// 获得子项显示的view
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
String string = childArrayName[groupPosition][childPosition];
return getGenericView(string);
}
// 子项是否可选中,如果需要设置子项的点击事件,需要返回true
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return false;
}
public TextView getGenericView(String string)
{
// Layout parameters for the ExpandableListView
AbsListView.LayoutParams layoutParams = new AbsListView.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, 64 );
TextView text = new TextView(context);
text.setLayoutParams(layoutParams);
// Center the text vertically
text.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
// Set the text starting position
text.setPadding(36 , 0 , 0 , 0 );
text.setText(string);
return text;
}
}
看一下运行效果吧~~~
就这样简单的实现了,不过这个效果可以说是非常简陋了,当然不能满足于这样的效果,接下来再去丰富一下布局吧。
首先创建一个父项布局expandlist_group.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="70dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="55dp"
android:background="@android:color/holo_blue_light"
>
<TextView
android:id="@+id/tv_group_name"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="30dp"
android:text="父项"
android:textColor="@android:color/white"
android:textSize="20sp"
android:gravity="center_vertical"/>
<ImageView
android:id="@+id/iv_arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"
android:background="@drawable/right_arrow"/>
</RelativeLayout>
</LinearLayout>
然后是子项布局expandlist_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="45dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:background="@android:color/holo_blue_light">
<TextView
android:id="@+id/tv_child_name"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="30dp"
android:text="子项"
android:textColor="#ffffff"
android:textSize="20sp"
android:gravity="center_vertical"/>
<ImageView
android:id="@+id/iv_pic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="20dp"
android:background="@drawable/pic"/>
</RelativeLayout>
</LinearLayout>
接下来去更改适配器的代码,这次使用List传递数据,不用之前的数组了,数组老麻烦了。
public class MyExpandableListViewAdapter extends BaseExpandableListAdapter {
private Context context;
private List<String> parentListName;
private List<List<String>> allChildName;
public MyExpandableListViewAdapter(Context context, List<String> parentListName, List<List<String>> allChildName) {
this.context = context;
this.parentListName = parentListName;
this.allChildName = allChildName;
}
// 获得父项的数量
@Override
public int getGroupCount() {
return parentListName.size();
}
// 获得某个父项的子项数目
@Override
public int getChildrenCount(int groupPosition) {
return allChildName.get(groupPosition).size();
}
// 获得某个父项
@Override
public Object getGroup(int groupPosition) {
return parentListName.get(groupPosition);
}
// 获得某个父项的某个子项
@Override
public Object getChild(int groupPosition, int childPosition) {
return allChildName.get(groupPosition).get(childPosition);
}
// 获得某个父项的id
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
// 获得某个父项的某个子项的id
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
/*
如果hasStableIds返回false的话 每次调用notifyDataSetChanged方法时adapter就会判断getItemId 并且在只调用那些Item发生变化的getView方法,
说白了就是通过getItemId来判断那些需要getView从而达到局部刷新的效果,在getView比较耗时的情况下起到优化的效果。
*/
@Override
public boolean hasStableIds() {
return false;
}
// 获得父项显示的view
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
View view = convertView;
GroupHolder holder = null;
if(view == null){
holder = new GroupHolder();
view = LayoutInflater.from(context).inflate(R.layout.expandlist_group, null);
holder.groupName = (TextView)view.findViewById(R.id.tv_group_name);
holder.arrow = (ImageView)view.findViewById(R.id.iv_arrow);
view.setTag(holder);
}else{
holder = (GroupHolder)view.getTag();
}
//判断是否已经打开列表
if(isExpanded){
holder.arrow.setBackgroundResource(R.drawable.down_arrow);
}else{
holder.arrow.setBackgroundResource(R.drawable.right_arrow);
}
holder.groupName.setText(parentListName.get(groupPosition));
return view;
}
// 获得子项显示的view
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
View view = convertView;
ChildHolder holder = null;
if(view == null){
holder = new ChildHolder();
view = LayoutInflater.from(context).inflate(R.layout.expandlist_item, null);
holder.childName = (TextView)view.findViewById(R.id.tv_child_name);
holder.pic = (ImageView)view.findViewById(R.id.iv_pic);
view.setTag(holder);
}else{
holder = (ChildHolder)view.getTag();
}
holder.pic.setBackgroundResource(R.drawable.pic);
holder.childName.setText(allChildName.get(groupPosition).get(childPosition));
return view;
}
// 子项是否可选中,如果需要设置子项的点击事件,需要返回true
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return false;
}
class GroupHolder{
public TextView groupName;
public ImageView arrow;
}
class ChildHolder{
public TextView childName;
public ImageView pic;
}
}
再来看一下运行效果吧:
布局已经发生了非常大的变化,不过每个父项列表上面自带的箭头还是很蛋疼的,取消的办法是加入这行代码:
expandableListView.setGroupIndicator(null)
然后给子项添加点击事件,注意啦,要想子项有点击事件需要之前适配器里面的isChildSelectable方法返回true:
expandableListView.setOnChildClickListener(new MyOnChildClickListener(allChildId, allChildName));
class MyOnChildClickListener implements ExpandableListView.OnChildClickListener{
private List<List<Integer>> allChildId;
private List<List<String>> allChildName;
public MyOnChildClickListener(List<List<Integer>> allChildId, List<List<String>> allChildName) {
this.allChildId = allChildId;
this.allChildName = allChildName;
}
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
int childId = allChildId.get(groupPosition).get(childPosition);
String name = allChildName.get(groupPosition).get(childPosition);
Toast.makeText(MainActivity.this, name + "的id是——" + childId, Toast.LENGTH_SHORT).show();
return false;
}
}
看一下效果:
点击事件已经完成了,接下来可以设置点击某一条信息然后跳转到另外一个Activity去显示具体的图片,在点击事件里面添加如下代码:
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
int childId = allChildId.get(groupPosition).get(childPosition);
String name = allChildName.get(groupPosition).get(childPosition);
// Toast.makeText(MainActivity.this, name + "的id是——" + childId, Toast.LENGTH_SHORT).show();
Intent intent = new Intent(MainActivity.this, MorePictureActivity.class);
Bundle bundle = new Bundle();
bundle.putSerializable("allChildId", (Serializable) allChildId);
bundle.putSerializable("allChildName", (Serializable) allChildName);
intent.putExtras(bundle);
intent.putExtra("groupPosition", groupPosition);
intent.putExtra("childPosition",childPosition);
startActivity(intent);
return false;
}
上面传递了子项的name集合与id集合,同时还有groupPosition和childPosition用于获取具体的位置,接下来是MorePictureActivity获得的布局页面activity_more_picture.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@android:color/holo_blue_light"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/Theme.AppCompat.Dialog"
app:layout_scrollFlags="scroll|enterAlways|snap"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.v4.widget.SwipeRefreshLayout>
</android.support.design.widget.CoordinatorLayout>
同时还有加载具体图片的CardView布局picture_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
app:cardCornerRadius="4dp">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/every_picture"
android:layout_width="match_parent"
android:layout_height="150dp"
android:scaleType="centerCrop"/>
<TextView
android:id="@+id/every_picture_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_margin="5dp"
android:textSize="16sp"/>
</LinearLayout>
</android.support.v7.widget.CardView>
接下来就MorePictureActivity是的详情代码了:
public class MorePictureActivity extends AppCompatActivity {
private SwipeRefreshLayout swipeRefresh;
private RecyclerView recyclerView;
private Toolbar toolbar;
private String picUrl;
private List<List<Integer>> allChildId;
private List<List<String>> allChildName;
private int groupPosition;
private int childPosition;
private MyRecyclerViewAdapter adapter;
private List<AllPictureBean.ShowapiResBodyBean.PagebeanBean.ContentlistBean> dataList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_more_picture);
allChildId = (List<List<Integer>>) getIntent().getSerializableExtra("allChildId");
allChildName = (List<List<String>>) getIntent().getSerializableExtra("allChildName");
groupPosition = getIntent().getIntExtra("groupPosition", 0);
childPosition = getIntent().getIntExtra("childPosition", 0);
LogUtil.e(allChildName.get(groupPosition).get(childPosition));
initView();
picUrl = Constants.getPicUrl(allChildId.get(groupPosition).get(childPosition), 1);
getDataByOkhttp();
//上拉刷新
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
getDataByOkhttp();
swipeRefresh.setRefreshing(false);
}
});
}
private void initView(){
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
swipeRefresh = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh);
toolbar = (Toolbar)findViewById(R.id.toolbar);
toolbar.setTitle(allChildName.get(groupPosition).get(childPosition));
setSupportActionBar(toolbar);
GridLayoutManager layoutManager = new GridLayoutManager(this, 2);
recyclerView.setLayoutManager(layoutManager);
recyclerView.addItemDecoration(new SpaceItemDecoration(30));
ActionBar actionBar = getSupportActionBar();
if(actionBar != null){
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
//设置RecyclerView的间隔
class SpaceItemDecoration extends RecyclerView.ItemDecoration{
private int space;
public SpaceItemDecoration(int space) {
this.space = space;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
outRect.left = space;
outRect.bottom = space;
if (parent.getChildLayoutPosition(view) %2==0) {
outRect.left = 0;
}
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case android.R.id.home:
finish();
break;
default:break;
}
return true;
}
private void getDataByOkhttp(){
HttpUtil.sendOkHttpRequest(picUrl, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
LogUtil.e("网络请求失败了~~~");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
LogUtil.e("网络请求成功啦~~~");
String data = response.body().string();
AllPictureBean bean = HttpUtil.parsedPicListJsonWithGson(data);
dataList = bean.getShowapi_res_body().getPagebean().getContentlist();
adapter = new MyRecyclerViewAdapter(MorePictureActivity.this, dataList);
runOnUiThread(new Runnable() {
@Override
public void run() {
recyclerView.setAdapter(adapter);
}
});
}
});
}
}
上面用到的RecyclerView的适配器是:
public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder>{
private Context context;
private List<AllPictureBean.ShowapiResBodyBean.PagebeanBean.ContentlistBean> dataList;
public MyRecyclerViewAdapter(Context context, List<AllPictureBean.ShowapiResBodyBean.PagebeanBean.ContentlistBean> dataList) {
this.context = context;
this.dataList = dataList;
}
@Override
public MyRecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (context != null){
this.context = parent.getContext();
}
View view = View.inflate(context, R.layout.picture_item, null);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(MyRecyclerViewAdapter.ViewHolder holder, int position) {
AllPictureBean.ShowapiResBodyBean.PagebeanBean.ContentlistBean dataBean = dataList.get(position);
String name = dataBean.getTitle();
String firstUrl = dataBean.getList().get(0).getMiddle();
holder.pictureName.setText(name);
Glide.with(context)
.load(firstUrl)
.diskCacheStrategy(DiskCacheStrategy.RESULT)
.skipMemoryCache(false)
.error(R.drawable.default_pic)
.into(holder.pictureImage);
}
@Override
public int getItemCount() {
return dataList.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
CardView cardView;
ImageView pictureImage;
TextView pictureName;
public ViewHolder(View view){
super(view);
cardView = (CardView)view;
pictureImage = (ImageView)view.findViewById(R.id.every_picture);
pictureName = (TextView)view.findViewById(R.id.every_picture_name);
}
}
}
看一下具体的运行效果吧:
不过显然这点点图片是不够的,所以接下来要RecyclerView在最底部实现上拉加载更多数据,下面是参考文章的链接:
RecyclerView滑动事件检测——http://blog.csdn.net/u011374875/article/details/51744448
RecyclerView完全解析之下拉刷新与上拉加载SwipeRefreshLayout——http://blog.csdn.net/developer_jiangqq/article/details/49992269
想要做到上拉加载更多数据,首先对RecyclerView设置滑动监听:
//RecyclerView滑动监听
recyclerView.addOnScrollListener(new MyOnScrollListener())
private int lastVisibleItem;
class MyOnScrollListener extends RecyclerView.OnScrollListener{
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState ==RecyclerView.SCROLL_STATE_IDLE && lastVisibleItem + 1 ==adapter.getItemCount()) {
Toast.makeText(MorePictureActivity.this, "到最下面啦!", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
lastVisibleItem = layoutManager.findLastVisibleItemPosition();
}
}
然后是运行效果:
接下来去实现真正的加载数据效果,首先,定义下面的方法:
private int m = 2;
private void getMoreData(){
HttpUtil.sendOkHttpRequest(Constants.getPicUrl(allChildId.get(groupPosition).get(childPosition), m), new Callback() {
@Override
public void onFailure(Call call, IOException e) {
LogUtil.e("加载更多数据失败");
Toast.makeText(MorePictureActivity.this, "加载更多数据失败", Toast.LENGTH_SHORT).show();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String data = response.body().string();
AllPictureBean bean = HttpUtil.parsedPicListJsonWithGson(data);
List<AllPictureBean.ShowapiResBodyBean.PagebeanBean.ContentlistBean> newData = bean.getShowapi_res_body().getPagebean().getContentlist();
for (int i = 0; i < newData.size(); i ++){
dataList.add(newData.get(i));
}
m++;
runOnUiThread(new Runnable() {
@Override
public void run() {
adapter.notifyDataSetChanged();
}
});
}
});
}
然后将getMoreData()方法添加到RecyclerView拉到最底部的监听中,接下来看一下效果:
不过这样有点蛋疼就是加载的效果非常简陋,仅仅只有一个Toast提示而已,下面就去实现一下更加具体的加载效果。
为了方便一点,就用比较简单粗暴的的方法吧,在主界面的布局中,与SwipeRefreshLayout同级处添加下面这个布局:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pb_loading"
android:visibility="gone"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp"
android:gravity="center">
<ProgressBar
android:layout_gravity="center"
android:indeterminateDrawable="@drawable/custom_progressbar"
android:layout_width="30dp"
android:layout_height="30dp"/>
<TextView
android:layout_marginLeft="8dp"
android:gravity="center_horizontal"
android:text="正在加载..."
android:textColor="@android:color/holo_blue_light"
android:textSize="25sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
其中ProgressBar的详情布局custom_progressbar.xml是:
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%">
<shape
android:shape="ring"
android:innerRadiusRatio="2.5"
android:thicknessRatio="15"
android:useLevel="false">
<gradient android:startColor="@android:color/holo_blue_bright"
android:centerColor="@android:color/holo_blue_dark"
android:endColor="#ffffff"
android:type="sweep"/>
</shape>
</rotate>
实例化上面的LinearLayout,然后在getMoreData()的onResponse中添加:
@Override
public void onResponse(Call call, Response response) throws IOException {
String data = response.body().string();
AllPictureBean bean = HttpUtil.parsedPicListJsonWithGson(data);
List<AllPictureBean.ShowapiResBodyBean.PagebeanBean.ContentlistBean> newData = bean.getShowapi_res_body().getPagebean().getContentlist();
for (int i = 0; i < newData.size(); i ++){
dataList.add(newData.get(i));
}
m++;
runOnUiThread(new Runnable() {
@Override
public void run() {
try {
adapter.notifyDataSetChanged();
Thread.sleep(2000);
pb_loading.setVisibility(View.GONE);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
瞧一瞧效果如何吧: