效果个人数据有问题所以效果不是太好
权限
<uses-permission android:name="android.permission.INTERNET"/>
网址:
public class Constant {
//获取分类列表
public static final String CATEGORY_URL = "http://www.zhaoapi.cn/product/getCatagory";
//详情分类列表
public static final String DETAIL_URL = "http://www.zhaoapi.cn/product/getProductCatagory";
}
拦截日志
public class LogInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Log.e("LogInterceptor", "request:" + request);
Log.e("LogInterceptor", "System.nanoTime():" + System.nanoTime());
Response response = chain.proceed(request);
Log.e("LogInterceptor", "request:" + request);
Log.e("LogInterceptor", "System.nanoTime():" + System.nanoTime());
return response;
}
}
单例模式+get()
public class OKHttpUtil {
private static OKHttpUtil okHttpUtil;
private final OkHttpClient client;
//私有化
private OKHttpUtil() {
//拦截器
client = new OkHttpClient.Builder().
addInterceptor(new LogInterceptor()).
build();
}
public static OKHttpUtil getInstance() {
if (null == okHttpUtil) {
synchronized (OKHttpUtil.class) {
if (null == okHttpUtil) {
okHttpUtil = new OKHttpUtil();
}
}
}
return okHttpUtil;
}
public void get(String urlString, Callback callback) {
Request request = new Request.Builder()
.url(urlString).build();
client.newCall(request).enqueue(callback);
}
}
依赖
//网络请求框架 OkHttp
implementation 'com.squareup.okhttp3:okhttp:3.12.0'
implementation 'com.google.dagger:dagger:2.10'
annotationProcessor 'com.google.dagger:dagger-compiler:2.10'
implementation 'com.lzy.net:okgo:3.0.4'
implementation 'com.android.support:design:28+'
implementation 'com.google.code.gson:gson:2.8.2'
//gilde
implementation 'com.github.bumptech.glide:glide:4.8.0'
//BaseQuickAdapter
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.30'
契约类:
public interface ICategoryContract {
//V层
public interface IView {
//展示分类信息
public void showCategoryData(String reponseData);
//展示详情数据
public void showDetailData(String reponseData);
}
//P层
public interface IPresenter<IView> {
//绑定
public void attachView(IView categoryView);
//解绑
public void detachView(IView categoryView);
//请求分类数据
public void requestCategoryData();
//请求详情
public void requestDetailData(int cid);
}
//M层
public interface IModel {
//请求详情数据
public void containCategoryData(OnCallBack onCallBack);
//请求详情数据
public void containDetailData(int cid, OnCallBack onCallBack);
//回调
public interface OnCallBack {
public void onCallBack(String reponseData);
}
}
}
Presenter:
public class CategoryPresenter implements ICategoryContract.IPresenter<ICategoryContract.IView> {
ICategoryContract.IView categoryView;
private SoftReference<ICategoryContract.IView> softReference;
private ICategoryContract.IModel model;
@Override
public void attachView(ICategoryContract.IView categoryView) {
this.categoryView = categoryView;
//防止内存泄漏
softReference = new SoftReference<>(categoryView);
//获取M层
model = new CategoryModel();
}
@Override
public void detachView(ICategoryContract.IView categoryView) {
softReference.clear();
}
@Override
public void requestCategoryData() {
model.containCategoryData(new ICategoryContract.IModel.OnCallBack() {
@Override
public void onCallBack(String reponseData) {
categoryView.showCategoryData(reponseData);
}
});
}
@Override
public void requestDetailData(int cid) {
model.containDetailData(cid,new ICategoryContract.IModel.OnCallBack() {
@Override
public void onCallBack(String reponseData) {
categoryView.showDetailData(reponseData);
}
});
}
}
Model:
public class CategoryModel implements ICategoryContract.IModel {
@Override
public void containCategoryData(final OnCallBack onCallBack) {
OKHttpUtil
.getInstance()
.get(Constant.CATEGORY_URL, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//错误的数据
String errorMsg = e.getMessage();
onCallBack.onCallBack(errorMsg);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
//请求得到的数据
String reponseData = response.body().string();
//回调
onCallBack.onCallBack(reponseData);
}
});
}
@Override
public void containDetailData(int cid, final OnCallBack onCallBack) {
OKHttpUtil.getInstance().get(Constant.DETAIL_URL + "?cid=" + cid, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
//错误的数据
String errorMsg = e.getMessage();
onCallBack.onCallBack(errorMsg);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
//请求得到的数据
String reponseData = response.body().string();
//回调
onCallBack.onCallBack(reponseData);
}
});
}
}
Activity
public class CategoryActivity extends AppCompatActivity implements ICategoryContract.IView {
@BindView(R.id.rv_categroy)
RecyclerView rvCategroy;
@BindView(R.id.rv_detail)
RecyclerView rvDetail;
@BindView(R.id.ctb_title_bar)
CustomTitleBar ctbTitleBar;
private ICategoryContract.IPresenter presenter;
private CategoryAdapter categoryAdapter;
private Context context;
private List<CategoryBean.DataBean> beanList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
context = this;
//创建P层
presenter = new CategoryPresenter();
//触发请求动作
presenter.attachView(this);
presenter.requestCategoryData();
//点击返回
ctbTitleBar.setOnCallBackLisenter(new CustomTitleBar.OnCallBackLisenter() {
@Override
public void onCallBack() {
CategoryActivity.this.finish();
}
});
//属性动画
ctbTitleBar.setOnMenuCallBackLisenter(new CustomTitleBar.OnMenuCallBackLisenter() {
@Override
public void onMenuCallBack() {
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(ctbTitleBar, "alpha", 0.1f, 0.8f);
objectAnimator.setDuration(2000);
objectAnimator.start();
}
});
}
@Override
public void showCategoryData(final String reponseData) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Gson gson = new Gson();
CategoryBean categoryBean = gson.fromJson(reponseData, CategoryBean.class);
//数据源
beanList = categoryBean.getData();
//布局管理器
LinearLayoutManager manager = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false);
rvCategroy.setLayoutManager(manager);
//适配器
categoryAdapter = new CategoryAdapter(R.layout.category_item, beanList);
rvCategroy.setAdapter(categoryAdapter);
categoryAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
@Override
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
//获取请求的参数cid
int cid = beanList.get(position).getCid();
//点击子条目时动作触发,请求详情条目
presenter.requestDetailData(cid);
}
});
}
});
}
@Override
public void showDetailData(final String reponseData) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Gson gson = new Gson();
DetailBean detailBean = gson.fromJson(reponseData, DetailBean.class);
List<DetailBean.DataBean> detailBeanData = detailBean.getData();
//布局管理器
LinearLayoutManager manager = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false);
rvDetail.setLayoutManager(manager);
//设置适配器
DetailAdapter detailAdapter = new DetailAdapter(R.layout.detail_item, detailBeanData);
rvDetail.setAdapter(detailAdapter);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
presenter.detachView(this);
}
CategoryAdapter
public class CategoryAdapter extends BaseQuickAdapter<CategoryBean.DataBean, BaseViewHolder> {
public CategoryAdapter(int layoutResId, @Nullable List<CategoryBean.DataBean> data) {
super(layoutResId, data);
}
@Override
protected void convert(BaseViewHolder helper, CategoryBean.DataBean item) {
helper.setText(R.id.tv_category, item.getName());
}
}
DetailAdapter
public class DetailAdapter extends BaseQuickAdapter<DetailBean.DataBean, BaseViewHolder> {
public DetailAdapter(int layoutResId, @Nullable List<DetailBean.DataBean> data) {
super(layoutResId, data);
}
@Override
protected void convert(BaseViewHolder helper, DetailBean.DataBean item) {
helper.setText(R.id.tv_detail_title, item.getName());
RecyclerView rv_goods = helper.getView(R.id.rv_goods);
//商品条目
List<DetailBean.DataBean.ListBean> beanList = item.getList();
Log.e(TAG, "beanList.size():" + beanList.size());
//布局管理器
GridLayoutManager manager = new GridLayoutManager(mContext, 3, GridLayoutManager.VERTICAL, false);
rv_goods.setLayoutManager(manager);
//设置适配器
GoodsAdapter adapter = new GoodsAdapter(R.layout.goods_item, beanList);
rv_goods.setAdapter(adapter);
}
}
GoodsAdapter
public class GoodsAdapter extends BaseQuickAdapter<DetailBean.DataBean.ListBean, BaseViewHolder> {
public GoodsAdapter(int layoutResId, @Nullable List<DetailBean.DataBean.ListBean> data) {
super(layoutResId, data);
}
@Override
protected void convert(BaseViewHolder helper, DetailBean.DataBean.ListBean item) {
helper.setText(R.id.tv_goods_title, item.getName());
//Glide加载显示图片
ImageView iv_goods_icon = helper.getView(R.id.iv_goods_icon);
Glide.with(mContext).load(item.getIcon()).into(iv_goods_icon);
}
}
主布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:alex="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.activity.CategoryActivity">
<com.android.alex.secondweektest.ui.widget.CustomTitleBar
alex:mColor="@color/colorPrimary"
android:id="@+id/ctb_title_bar"
android:layout_width="match_parent"
android:layout_height="60dp"></com.android.alex.secondweektest.ui.widget.CustomTitleBar>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_categroy"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"></android.support.v7.widget.RecyclerView>
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_detail"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="7"></android.support.v7.widget.RecyclerView>
</LinearLayout>
</LinearLayout>
自定义view布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center">
<ImageView
android:id="@+id/iv_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:src="@mipmap/back" />
<TextView
android:id="@+id/tv_custom_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:gravity="center"
android:text="分类"
android:textSize="28sp" />
<ImageView
android:id="@+id/iv_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:src="@mipmap/menu" />
</RelativeLayout>
此处省略三个 布局…
//继承view
public class CustomTitleBar extends LinearLayout implements View.OnClickListener {
private int mColor;
OnCallBackLisenter onCallBackLisenter;
//接口回调
public interface OnCallBackLisenter{
public void onCallBack();
};
public void setOnCallBackLisenter(OnCallBackLisenter onCallBackLisenter){
this.onCallBackLisenter = onCallBackLisenter;
}
OnMenuCallBackLisenter onMenuCallBackLisenter;
//接口回调
public interface OnMenuCallBackLisenter{
public void onMenuCallBack();
};
public void setOnMenuCallBackLisenter(OnMenuCallBackLisenter onMenuCallBackLisenter){
this.onMenuCallBackLisenter = onMenuCallBackLisenter;
}
public CustomTitleBar(Context context) {
super(context);
}
public CustomTitleBar(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
View rootView = LayoutInflater.from(context).inflate(R.layout.title_bar_item, this);
TextView tv_custom_title = rootView.findViewById(R.id.tv_custom_title);
ImageView iv_back = rootView.findViewById(R.id.iv_back);
ImageView iv_menu = rootView.findViewById(R.id.iv_menu);
iv_back.setOnClickListener(this);
iv_menu.setOnClickListener(this);
//自定义属性
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomTitleBar);
int indexCount = typedArray.getIndexCount();
for (int i = 0; i < indexCount; i++) {
int index = typedArray.getIndex(i);
switch (index){
case R.styleable.CustomTitleBar_mColor:
mColor = typedArray.getColor(i, Color.GREEN);
tv_custom_title.setTextColor(mColor);
break;
}
}
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.iv_back:
onCallBackLisenter.onCallBack();
break;
case R.id.iv_menu:
onMenuCallBackLisenter.onMenuCallBack();
break;
}
}
}
attrs.xml
<declare-styleable name="CustomTitleBar">
<attr name="mColor" format="color"></attr>
</declare-styleable>