RecyclerView二級聯動,仿京東分類介面
阿新 • • 發佈:2018-11-24
今天我們一起探討一下通過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;
}
}
}
}
好了,到這裡我們的分類就算結束了,最後看一下效果: