ExpandableListView的使用

最近使用一个图片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();
                        }
                    }
                });
            }

瞧一瞧效果如何吧:

这里写图片描述

猜你喜欢

转载自blog.csdn.net/asjqkkkk/article/details/78448146