1. 程式人生 > >RecyclerView二級聯動,仿京東分類介面

RecyclerView二級聯動,仿京東分類介面

今天我們一起探討一下通過RecyclerView實現二級聯動,在這裡我做的是仿京東的分類頁面,京東的分類頁面是一個非常經典的專案,今天我們就來寫一下.
首先,第一步:搭建環境(依賴和許可權)
在這裡首先看一下所需依賴:在這裡圖片的記載我使用的是Glide

 /*android5.0的新特性使用*/
    compile 'com.android.support:support-v13:28.0.0'
    compile 'com.android.support:cardview-v7:28.0.0'
    compile 'com.android.support:design:28.0.0'
    implementation 'com.android.support:support-v13:28.0.0'
    /*RecyclerView所需依賴*/
    compile 'com.android.support:recyclerview-v7:28.0.0'
    /*OkHttp所需依賴*/
    compile 'com.squareup.okhttp3:okhttp:3.4.2'
    /*gson所需依賴*/
    implementation 'com.google.code.gson:gson:2.8.5'
    /*Glide所需依賴*/
    implementation 'com.github.bumptech.glide:glide:4.8.0'
  

然後是許可權:在這裡我們配置一個網路請求就好:

 <uses-permission android:name="android.permission.INTERNET"/>

環境搭建完畢,開始我們的操作
MainActivity:對於UI的展示我們用一下TabLayout+ViewPager

package com.cart.month.activity;

import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.
Fragment; import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import com.cart.month.R; import com.cart.month.adapter.ViewPagerAdapter; import com.cart.month.fragment.CartFragment; import com.cart.month.fragment.ClassifyFragment; import com.cart.month.fragment.
HomeFragment; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { private ViewPager vp; private TabLayout tab; private ViewPagerAdapter viewPagerAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //初始化控制元件 initView(); //建立ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager()); //建立Fragment ArrayList<Fragment> fragments = new ArrayList<Fragment>(); fragments.add(new HomeFragment()); fragments.add(new ClassifyFragment()); fragments.add(new CartFragment()); tab.setupWithViewPager(vp); viewPagerAdapter.setData(fragments); vp.setAdapter(viewPagerAdapter); } private void initView() { vp = (ViewPager) findViewById(R.id.vp); tab = (TabLayout) findViewById(R.id.tab); } }

此次我一共生成三個頁面,但是咱們今天就先來了解以下分類頁面,所以在這個就只給大家展示一個分類介面的相關操作:

package com.cart.month.fragment;

import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.cart.month.R;
import com.cart.month.adapter.LeftRecyclerViewAdapter;
import com.cart.month.adapter.RightRecyclerViewAdapter;
import com.cart.month.bean.DataItemLeft;
import com.cart.month.bean.DataItemRight;
import com.cart.month.util.ClassifyGetHttp;
import com.cart.month.util.ClassifyPostHttp;
import com.cart.month.util.JsonInterface;

import java.util.HashMap;
import java.util.List;

/**
 * date:2018/11/22
 * author:李壯(HUAWEI)
 * function:
 */
public class ClassifyFragment extends Fragment {
    private RecyclerView reyclerView_left;
    private LinearLayout linear;
    private RecyclerView reyclerView_right;
    private String pathLeft = "http://www.zhaoapi.cn/product/getCatagory?source=android";
    private String pathRight = "http://www.zhaoapi.cn/product/getProductCatagory?source=android";
    private LeftRecyclerViewAdapter mLeftRecyclerViewAdapter;
    String ccid = "1";
    private RightRecyclerViewAdapter mRightRecyclerViewAdapter;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = View.inflate(getActivity(), R.layout.classifyfragment, null);
        //初始化控制元件
        initView(view);
        //初始化資料
        initData();
        return view;

    }

    private void initData() {
        //獲取左邊資料
        leftData();
    }

    private void leftData() {
        ClassifyGetHttp.getinstance().getHttp(pathLeft, new JsonInterface() {
            @Override
            public void success(List<DataItemLeft.DataBean> data) {
                LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL,false);
                //設定佈局管理器
                reyclerView_left.setLayoutManager(linearLayoutManager);
                //建立介面卡
                mLeftRecyclerViewAdapter = new LeftRecyclerViewAdapter(getActivity(),data);
                //新增到介面卡
                reyclerView_left.setAdapter(mLeftRecyclerViewAdapter);
                //自定義介面回撥,實現點選事件
                mLeftRecyclerViewAdapter.setGetCid(new GetCid() {
                    @Override
                    public void setCid(String cid) {
                        ccid = cid;
                        Log.e("lz",cid);
                        initRight();
                    }
                });
            }

            @Override
            public void error() {
                Toast.makeText(getActivity(), "網路請求失敗!!!!", Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void initRight() {
        final HashMap<String, String> map = new HashMap<>();
        map.put("cid",ccid);
        ClassifyPostHttp.getinstance().postHttp(pathRight, map, new JsonPostInterface() {
            @Override
            public void success(List<DataItemRight.DataBean> data) {
                Log.e("lz",data.get(0).getName());
                //在載入新的資料前先清空
                linear.removeAllViews();
                if (data != null){
                    for (int i = 0 ; i < data.size() ; i++){
                        List<DataItemRight.DataBean.ListBean> list = data.get(i).getList();
                        //動態建立TextView
                        TextView textView = new TextView(getActivity());
                        textView.setText(data.get(i).getName());
                        //顏色
                        textView.setTextColor(Color.RED);
                        //字型大小
                        textView.setTextSize(30);
                        //動態建立右側RecyclerView
                        reyclerView_right = new RecyclerView(getActivity());
                        //建立介面卡
                        mRightRecyclerViewAdapter = new RightRecyclerViewAdapter(getActivity(), list);
                        //設定佈局管理,在這裡使用網格佈局
                        GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 3);
                        reyclerView_right.setLayoutManager(gridLayoutManager);
                        //新增到介面卡
                        reyclerView_right.setAdapter(mRightRecyclerViewAdapter);
                        mRightRecyclerViewAdapter.setGetPscid(new GetPscid() {
                            @Override
                            public void setPscid(String pscid) {
                                Log.e("lz","pscid:"+pscid);

                            }
                        });
                        //重新整理
                        mRightRecyclerViewAdapter.notifyDataSetChanged();
                        linear.addView(textView);
                        linear.addView(reyclerView_right);
                    }
                }

            }

            @Override
            public void error() {
                Toast.makeText(getActivity(), "網路請求失敗!!!!", Toast.LENGTH_SHORT).show();
            }
        });
    }

    //獲取資源id
    private void initView(View view) {
        reyclerView_left = (RecyclerView) view.findViewById(R.id.reyclerView_left);
        linear = (LinearLayout) view.findViewById(R.id.linear);
    }

}

接下來看一下OkHttp的二次封裝

package com.cart.month.util;

import android.os.Handler;
import android.os.Looper;

import java.io.IOException;
import java.util.Map;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * date:2018/11/22
 * author:李壯(HUAWEI)
 * function:二次封裝OKHTTP
 */
public class OKHttPUtils {

    private static OKHttPUtils okhttputils;
    private final Handler mHandler;
    private final OkHttpClient mOkHttpClient;
    private OKHttPUtils(){
        mHandler = new Handler(Looper.getMainLooper());
        mOkHttpClient = new OkHttpClient.Builder().build();
    }
    public static OKHttPUtils getinstance(){
        if (okhttputils == null){
            synchronized (OKHttPUtils.class){
                if (okhttputils == null){
                    okhttputils=new OKHttPUtils();
                }
            }
        }
        return okhttputils;
    }
    public void doPost(String path, Map<String,String> map, final OkInterface mokinterface){
        FormBody.Builder builder = new FormBody.Builder();
        if (map != null){
            for (String key : map.keySet()){
                builder.add(key,map.get(key));
            }
        }
        FormBody formBody = builder.build();
        Request build = new Request.Builder().url(path).post(formBody).build();
        mOkHttpClient.newCall(build).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, final IOException e) {
                if (mokinterface != null){
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            mokinterface.failtrue(e);
                        }
                    });
                }
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response != null && response.isSuccessful()){
                    final String string = response.body().string();
                    if (mokinterface != null){
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                mokinterface.response(string);
                            }
                        });
                    }
                }
            }
        });
    }

    public void doGet(String path, final OkInterface mokinterface){
        Request build = new Request.Builder().url(path).build();
        mOkHttpClient.newCall(build).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, final IOException e) {
                if (mokinterface != null){
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            mokinterface.failtrue(e);
                        }
                    });
                }
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response != null && response.isSuccessful()){
                    final String string = response.body().string();
                    if (mokinterface != null){
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                mokinterface.response(string);
                            }
                        });
                    }
                }
            }
        });
    }
}

在這裡為了方便大家閱讀,我將Post和GET兩種請求又進行了分類封裝
先來看一下Get的封裝

package com.cart.month.util;

import com.cart.month.bean.DataItemLeft;
import com.google.gson.Gson;

import java.util.List;

/**
 * date:2018/11/22
 * author:李壯(HUAWEI)
 * function:
 */
public class ClassifyGetHttp {
    private static ClassifyGetHttp classifyGetHttp;

    private ClassifyGetHttp() {}
    public static ClassifyGetHttp getinstance(){
        if (classifyGetHttp == null){
            synchronized (ClassifyGetHttp.class){
                if (classifyGetHttp == null){
                    classifyGetHttp = new ClassifyGetHttp();
                }
            }
        }
        return classifyGetHttp;
    }

    //封裝get
    public void getHttp(String path, final JsonInterface mjsoninterface){
        OKHttPUtils.getinstance().doGet(path, new OkInterface() {
            @Override
            public void response(String json) {
                DataItemLeft dataItemLeft = new Gson().fromJson(json, DataItemLeft.class);
                List<DataItemLeft.DataBean> data = dataItemLeft.getData();
                if (mjsoninterface != null){
                    mjsoninterface.success(data);
                }
            }

            @Override
            public void failtrue(Exception e) {
                if (mjsoninterface != null){
                    mjsoninterface.error();
                }
            }
        });
    }
}

其次是Post請求的封裝

package com.cart.month.util;

import com.cart.month.bean.DataItemRight;
import com.google.gson.Gson;

import java.util.List;
import java.util.Map;

/**
 * date:2018/11/22
 * author:李壯(HUAWEI)
 * function:
 */
public class ClassifyPostHttp {
    private static ClassifyPostHttp bposthttp;
    private ClassifyPostHttp() {}
    public static ClassifyPostHttp getinstance(){
        if (bposthttp == null){
            synchronized (ClassifyGetHttp.class){
                if (bposthttp == null){
                    bposthttp = new ClassifyPostHttp();
                }
            }
        }
        return bposthttp;
    }

    public void postHttp(String path, Map<String,String> map, final JsonPostInterface mjsonPostInterface){

        OKHttPUtils.getinstance().doPost(path,map, new OkInterface() {
            @Override
            public void response(String json) {
                DataItemRight dataItemRight = new Gson().fromJson(json, DataItemRight.class);
                List<DataItemRight.DataBean> data = dataItemRight.getData();
                if (mjsonPostInterface != null){
                    mjsonPostInterface.success(data);
                }
            }

            @Override
            public void failtrue(Exception e) {
                if (mjsonPostInterface != null){
                    mjsonPostInterface.error();
                }
            }
        });
    }
}

然後我對一些請求的介面進行了提取,一起看一下吧
getcid

package com.cart.month.util;

/**
 * date:2018/11/22
 * author:李壯(HUAWEI)
 * function:
 */
public interface GetCid {
    void setCid(String cid);

}

getpscid

package com.cart.month.util;

/**
 * date:2018/11/22
 * author:李壯(HUAWEI)
 * function:
 */
public interface GetPscid {
    void setPscid(String pscid);
}

package com.cart.month.util;

import com.cart.month.bean.DataItemLeft;

import java.util.List;

/**
 * date:2018/11/22
 * author:李壯(HUAWEI)
 * function:
 */
public interface JsonInterface {
    void success(List<DataItemLeft.DataBean> data);
    void error();
}

package com.cart.month.util;


import com.cart.month.bean.DataItemRight;

import java.io.IOException;
import java.util.List;

/**
 * date:2018/11/22
 * author:李壯(HUAWEI)
 * function:
 */
public interface JsonPostInterface{

    void success(List<DataItemRight.DataBean> data);
    void error();

}

package com.cart.month.util;

/**
 * date:2018/11/22
 * author:李壯(HUAWEI)
 * function:
 */
public interface OkInterface {
    void response(String json);
    void failtrue(Exception e);
}


ViewPager介面卡瞭解一下

package com.cart.month.adapter;

import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

import java.util.ArrayList;

/**
 * date:2018/11/22
 * author:李壯(HUAWEI)
 * function:
 */
public class ViewPagerAdapter extends FragmentPagerAdapter {

    private ArrayList<Fragment> mFragments;

    public ViewPagerAdapter(FragmentManager fm) {
        super(fm);
        mFragments = new ArrayList<>();
    }
    public void setData(ArrayList<Fragment> fragments) {
        this.mFragments = fragments;
    }

    @Override
    public Fragment getItem(int i) {
        return mFragments.get(i);
    }

    @Override
    public int getCount() {
        return mFragments.size();
    }

    @Nullable
    @Override
    public CharSequence getPageTitle(int position) {
        switch (position){
            case 0:
                return "首頁";
            case 1:
                return "分類";
            case 2:
                return "購物車";

        }
        return null;
    }
}

在這裡分類我們一個有兩個介面卡進行管理,左邊負責組,右邊負責每一組的具體資料,先來看一下左邊組的介面卡:

package com.cart.month.adapter;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.cart.month.R;
import com.cart.month.bean.DataItemLeft;
import com.cart.month.util.GetCid;

import java.util.List;

/**
 * date:2018/11/22
 * author:李壯(HUAWEI)
 * function:
 */
public class LeftRecyclerViewAdapter extends RecyclerView.Adapter<LeftRecyclerViewAdapter.ViewHolder> {

    List<DataItemLeft.DataBean> list;
    Context context;

    public LeftRecyclerViewAdapter(Context context, List<DataItemLeft.DataBean> data) {
        this.context = context;
        list = data;
    }

    @NonNull
    @Override//建立ViewHolder
    public LeftRecyclerViewAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view = View.inflate(context,R.layout.recyclerview_left,null);
        ViewHolder viewHolder = new ViewHolder(view);
        return viewHolder;
    }

    @Override//繫結檢視
    public void onBindViewHolder(@NonNull LeftRecyclerViewAdapter.ViewHolder viewHolder, int i) {
          viewHolder.recyclerView_left_title.setText(list.get(i).getName());
          //條目點選事件, 自定義介面回撥
          viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (mGetCid != null){
                    mGetCid.setCid(list.get(i).getCid()+"");
                }
            }
        });
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    //獲取資源展示id
    public class ViewHolder extends RecyclerView.ViewHolder {
        private TextView recyclerView_left_title;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            recyclerView_left_title = itemView.findViewById(R.id.reyclerView_left_title);
        }
    }


    //介面回撥
    private GetCid mGetCid;
    public void setGetCid(GetCid getCid){
        mGetCid = getCid;
    }
}

右邊具體商品資訊的介面卡

package com.cart.month.adapter;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.cart.month.R;
import com.cart.month.bean.DataItemRight;
import com.cart.month.util.GetPscid;

import java.util.List;

/**
 * date:2018/11/22
 * author:李壯(HUAWEI)
 * function:
 */
public class RightRecyclerViewAdapter extends RecyclerView.Adapter<RightRecyclerViewAdapter.ViewHolder> {
    List<DataItemRight.DataBean.ListBean> list;
    Context context;

    public RightRecyclerViewAdapter(Context context, List<DataItemRight.DataBean.ListBean> data) {
        this.context = context;
        list = data;
    }

    @NonNull
    @Override//建立ViewHolder
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view = View.inflate(context, R.layout.recyclerview_right, null);
        ViewHolder viewHolder = new ViewHolder(view);
        return viewHolder;
    }

    @Override//繫結檢視
    public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
        //載入標題
         viewHolder.recyclerView_right_title.setText(list.get(i).getName());
         //載入圖片,在這裡我使用的是Glide
        Glide.with(context).load(list.get(i).getIcon()).into(viewHolder.recyclerView_right_icon);
        //圖片的點選事件,通過自定義介面回撥
        viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (mGetPscid != null){
                    mGetPscid.setPscid(list.get(i).getPscid()+"");
                }
            }
        });
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    //獲取展示資源的id
    public class ViewHolder extends RecyclerView.ViewHolder {
        private TextView recyclerView_right_title;
        private ImageView recyclerView_right_icon;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            recyclerView_right_title = itemView.findViewById(R.id.reyclerView_right_title);
            recyclerView_right_icon = itemView.findViewById(R.id.reyclerView_right_icon);
        }
    }

    //介面回撥
    private GetPscid mGetPscid;

    public void setGetPscid(GetPscid getPscid) {
        mGetPscid = getPscid;
    }
}

最後剩下的就是兩個Bean類,左右各一個
左邊的

package com.cart.month.bean;

import java.util.List;

/**
 * date:2018/11/22
 * author:李壯(HUAWEI)
 * function:
 */
public class DataItemLeft {
    

    private String msg;
    private String code;
    private List<DataBean> data;

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public List<DataBean> getData() {
        return data;
    }

    public void setData(List<DataBean> data) {
        this.data = data;
    }

    public static class DataBean {
      
        private int cid;
        private String createtime;
        private String icon;
        private int ishome;
        private String name;

        public int getCid() {
            return cid;
        }

        public void setCid(int cid) {
            this.cid = cid;
        }

        public String getCreatetime() {
            return createtime;
        }

        public void setCreatetime(String createtime) {
            this.createtime = createtime;
        }

        public String getIcon() {
            return icon;
        }

        public void setIcon(String icon) {
            this.icon = icon;
        }

        public int getIshome() {
            return ishome;
        }

        public void setIshome(int ishome) {
            this.ishome = ishome;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}

右邊的

package com.cart.month.bean;

import java.util.List;

/**
 * date:2018/11/22
 * author:李壯(HUAWEI)
 * function:
 */
public class DataItemRight {

  

    private String msg;
    private String code;
    private List<DataBean> data;

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public List<DataBean> getData() {
        return data;
    }

    public void setData(List<DataBean> data) {
        this.data = data;
    }

    public static class DataBean {
        

        private String cid;
        private String name;
        private String pcid;
        private List<ListBean> list;

        public String getCid() {
            return cid;
        }

        public void setCid(String cid) {
            this.cid = cid;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getPcid() {
            return pcid;
        }

        public void setPcid(String pcid) {
            this.pcid = pcid;
        }

        public List<ListBean> getList() {
            return list;
        }

        public void setList(List<ListBean> list) {
            this.list = list;
        }

        public static class ListBean {
            private String icon;
            private String name;
            private int pcid;
            private int pscid;

            public String getIcon() {
                return icon;
            }

            public void setIcon(String icon) {
                this.icon = icon;
            }

            public String getName() {
                return name;
            }

            public void setName(String name) {
                this.name = name;
            }

            public int getPcid() {
                return pcid;
            }

            public void setPcid(int pcid) {
                this.pcid = pcid;
            }

            public int getPscid() {
                return pscid;
            }

            public void setPscid(int pscid) {
                this.pscid = pscid;
            }
        }
    }
}

好了,到這裡我們的分類就算結束了,最後看一下效果:
在這裡插入圖片描述