今天我们一起探讨一下通过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'
然后是权限:在这里我们配置一个网络请求就好:
环境搭建完毕,开始我们的操作
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 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 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 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 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 mFragments;
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
mFragments = new ArrayList<>();
}
public void setData(ArrayList 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 {
List list;
Context context;
public LeftRecyclerViewAdapter(Context context, List 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 {
List list;
Context context;
public RightRecyclerViewAdapter(Context context, List 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 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 getData() {
return data;
}
public void setData(List 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 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 getData() {
return data;
}
public void setData(List data) {
this.data = data;
}
public static class DataBean {
private String cid;
private String name;
private String pcid;
private List 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 getList() {
return list;
}
public void setList(List 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;
}
}
}
}