仿京东——分类

本文详细介绍了在Android应用中使用MVP模式实现商品分类模块的过程,包括界面布局设计、数据请求与响应、适配器创建及网格视图的自定义,展示了如何通过Retrofit进行网络请求,以及如何利用ButterKnife简化视图绑定。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

分类主代码

public class TypeFragment extends Fragment implements TypeView {
    @BindView(R.id.type_Catagory)
    RecyclerView typeCatagory;
    @BindView(R.id.type_exl)
    ExpandableListView typeExl;
    Unbinder unbinder;
    private TypePresenter presenter;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = View.inflate(getActivity(), R.layout.type_fg, null);
        unbinder = ButterKnife.bind(this, view);
        return view;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        presenter = new TypePresenter(this);
        //初始化分类
        initCatagory();
    }

    private void initCatagory() {
        typeCatagory.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
        presenter.getCatagory();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        unbinder.unbind();
        presenter.onDestroy();
        presenter = null;
    }

    @Override
    public void onCatagorySuccess(Catagory catagory) {

        List<Catagory.DataBean> data = catagory.getData();
        CatagoryAdapter adapter = new CatagoryAdapter(data);
        typeCatagory.setAdapter(adapter);
        //默认请求cid=1的数据
        presenter.getProductCatagory("1");
        //分类点击回调
        adapter.setOnCatagoryLisenter(new CatagoryAdapter.OnCatagoryLisenter() {
            @Override
            public void onNameClick(int cid) {
                //调用p层请求子分类
                presenter.getProductCatagory(cid + "");
            }
        });
    }

    @Override
    public void onCatagoryFaild() {
        Toast.makeText(getActivity(), "获得数据失败", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onProductCatagorySuccess(ProductCatagory productCatagory) {
        if (productCatagory.getData().size() == 0) {
            Toast.makeText(getActivity(), "该分类暂时没有商品", Toast.LENGTH_SHORT).show();
        } else {
            List<ProductCatagory.DataBean> data = productCatagory.getData();
            ExAdapter adapter = new ExAdapter(data);
            typeExl.setAdapter(adapter);
            //默认展开所有一级item
            for (int i = 0; i < data.size(); i++) {
                typeExl.expandGroup(i);
            }
        }
    }
}

主界面

<?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">
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/type_Catagory"
            android:layout_width="0dp"
            android:layout_weight="2"
            android:layout_height="match_parent"></android.support.v7.widget.RecyclerView>
        <ExpandableListView
            android:groupIndicator="@null"
            android:id="@+id/type_exl"
            android:layout_width="0dp"
            android:layout_weight="8"
            android:layout_height="match_parent"></ExpandableListView>
    </LinearLayout>
</LinearLayout>

mvp-model-TypeModel

public class TypeModel {

    //获取分类
    public Observable<Catagory> getCatagory() {
        return RetrofitUtil.getDefault().create(MyRetrofit.class).getCatagory();
    }

    //获取子分类
    public Observable<ProductCatagory> getProductCatagory(String cid) {
        return RetrofitUtil.getDefault().create(MyRetrofit.class).getProductCatagory(cid);
    }
    //获取商品列表
    public Observable<Products> getProducts(String pscid) {
        return RetrofitUtil.getDefault().create(MyRetrofit.class).getProducts(pscid);
    }
}

mvp-presenter-TypePresenter
 

public class TypePresenter extends BasePresenter<TypeView> {

    private TypeModel typeModel;

    public TypePresenter(TypeView view) {
        super(view);
    }

    @Override
    public void initModel() {
        typeModel = new TypeModel();
    }
    //获得分类
    public void getCatagory() {
        typeModel.getCatagory()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Catagory>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        compositeDisposable.add(d);
                    }

                    @Override
                    public void onNext(Catagory catagory) {
                        view.onCatagorySuccess(catagory);
                    }

                    @Override
                    public void onError(Throwable e) {
                        view.onCatagoryFaild();
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }
    //获得子分类
    public void getProductCatagory(String cid) {
        typeModel.getProductCatagory(cid)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<ProductCatagory>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        compositeDisposable.add(d);
                    }

                    @Override
                    public void onNext(ProductCatagory productCatagory) {
                        view.onProductCatagorySuccess(productCatagory);
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }
}

mvp-view-view

public interface TypeView extends IView{
    void onCatagorySuccess(Catagory catagory);
    void onCatagoryFaild();
    void onProductCatagorySuccess(ProductCatagory productCatagory);
}

adapter-CatagroyAdapter

public class CatagoryAdapter extends RecyclerView.Adapter {
    private List<Catagory.DataBean> list;

    public CatagoryAdapter(List<Catagory.DataBean> list) {
        this.list = list;
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = View.inflate(parent.getContext(), R.layout.catagory_item, null);
        MViewHolder mViewHolder = new MViewHolder(view);
        return mViewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        MViewHolder mHolder = (MViewHolder) holder;
        final Catagory.DataBean bean = list.get(position);
        mHolder.catagory_name.setText(bean.getName());

        mHolder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (onCatagoryLisenter != null) {
                    onCatagoryLisenter.onNameClick(bean.getCid());
                }
            }
        });
    }

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

    class MViewHolder extends RecyclerView.ViewHolder {

        private final TextView catagory_name;

        public MViewHolder(View itemView) {
            super(itemView);
            catagory_name = itemView.findViewById(R.id.catagory_name);
        }
    }

    public interface OnCatagoryLisenter {
        void onNameClick(int cid);
    }

    private OnCatagoryLisenter onCatagoryLisenter;

    public void setOnCatagoryLisenter(OnCatagoryLisenter onCatagoryLisenter) {
        this.onCatagoryLisenter = onCatagoryLisenter;
    }
}

adapter-ExAdapter

public class ExAdapter extends BaseExpandableListAdapter {
    private List<ProductCatagory.DataBean> list;

    public ExAdapter(List<ProductCatagory.DataBean> list) {
        this.list = list;
    }

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

    @Override
    public int getChildrenCount(int groupPosition) {
        return 1;
    }

    @Override
    public Object getGroup(int groupPosition) {
        return list.get(groupPosition);
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return list.get(groupPosition).getList().get(childPosition);
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    @Override
    public boolean hasStableIds() {
        return true;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = View.inflate(parent.getContext(), R.layout.group_item, null);
        }
        TextView group_name = convertView.findViewById(R.id.group_name);
        group_name.setText(list.get(groupPosition).getName());
        return convertView;
    }

    @Override
    public View getChildView(int groupPosition, final int childPosition, boolean isLastChild, View convertView, final ViewGroup parent) {
        if (convertView == null) {
            convertView = View.inflate(parent.getContext(), R.layout.grid_view, null);
        }
        //二级item加载一个gridview布局
        MyGridView grid = convertView.findViewById(R.id.grid);
        final List<ProductCatagory.DataBean.ListBean> list = this.list.get(groupPosition).getList();
        grid.setAdapter(new GridAdapter(list));
        //为gridview设置条目点击监听
        grid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//                Toast.makeText(parent.getContext(), list.get(position).getPscid() + "==", Toast.LENGTH_SHORT).show();
                Intent intent = new Intent(parent.getContext(), ProductsActivity.class);
                intent.putExtra("pscid", list.get(position).getPscid());
                parent.getContext().startActivity(intent);
            }
        });
        return convertView;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }
}

二级列表,父列表group_item

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@color/huo"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
<TextView
    android:id="@+id/group_name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
</LinearLayout>

子列表

<?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:stretchMode="spacingWidthUniform">

    <com.bw.movie.diyview.MyGridView
        android:id="@+id/grid"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:numColumns="3"></com.bw.movie.diyview.MyGridView>

</LinearLayout>

自定义的gridview

public class MyGridView extends GridView {
    public MyGridView(Context context) {
        this(context, null, 0);
    }

    public MyGridView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyGridView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //重新计算高度
        int newHeight = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, newHeight);
    }
}

 

Gridviewadapter

class GridAdapter extends BaseAdapter {
    private List<ProductCatagory.DataBean.ListBean> list;

    public GridAdapter(List<ProductCatagory.DataBean.ListBean> list) {
        this.list = list;
    }

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

    @Override
    public Object getItem(int position) {
        return list.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;
        if (convertView == null) {
            convertView = View.inflate(parent.getContext(), R.layout.child_item, null);
            viewHolder=new ViewHolder(convertView);
            convertView.setTag(viewHolder);
        }else {
            viewHolder= (ViewHolder) convertView.getTag();
        }
        viewHolder.childImg.setImageURI(Uri.parse(list.get(position).getIcon()));
        viewHolder.childName.setText(list.get(position).getName());
        return convertView;
    }

    static class ViewHolder {
        @BindView(R.id.child_img)
        SimpleDraweeView childImg;
        @BindView(R.id.child_name)
        TextView childName;

        ViewHolder(View view) {
            ButterKnife.bind(this, view);
        }
    }
}

Gridviewadapter布局

<LinearLayout 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:orientation="vertical">

    <com.facebook.drawee.view.SimpleDraweeView
        android:id="@+id/child_img"
        android:layout_width="50dp"
        android:layout_height="50dp"
        app:placeholderImage="@drawable/ic_launcher_background" />

    <TextView
        android:id="@+id/child_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

ProductsActivity

public class ProductsActivity extends BaseActivity<ProductsPresenter> implements ProductsView {


    @BindView(R.id.products_rv)
    RecyclerView productsRv;

    @Override
    public ProductsPresenter providePresenter() {
        return new ProductsPresenter(this);
    }

    @Override
    public int provideLayoutId() {
        return R.layout.activity_products;
    }

    @Override
    public void initListener() {

    }

    @Override
    public void initDate() {
        int pscid = getIntent().getIntExtra("pscid", 0);
        productsRv.setLayoutManager(new LinearLayoutManager(ProductsActivity.this, LinearLayoutManager.VERTICAL, false));
        presenter.getProducts(pscid + "");
    }

    @Override
    public void onSuccess(Products products) {
        List<Products.DataBean> data = products.getData();
        productsRv.setAdapter(new ProductsAdapter(data));
    }

}

ProductsAdapter

public class ProductsAdapter extends RecyclerView.Adapter {

    private List<Products.DataBean> list;
    private Context context;

    public ProductsAdapter(List<Products.DataBean> list) {
        this.list = list;
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        context = parent.getContext();
        View view = View.inflate(context, R.layout.products, null);
        ViewHolder viewHolder = new ViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        ViewHolder viewHolder = (ViewHolder) holder;
        final Products.DataBean bean = list.get(position);
        String imgUrl = getImgUrl(list.get(position).getImages());
        viewHolder.productsImg.setImageURI(Uri.parse(imgUrl));
        viewHolder.productsTitle.setText(bean.getTitle());
        viewHolder.productsYuanjia.setText("原价:¥" + bean.getPrice() + "");
        viewHolder.productsXianjia.setText("现价:¥" + bean.getBargainPrice() + "");

        viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String pid = bean.getPid() + "";
                Intent intent = new Intent(context, DetailActivity.class);
                intent.putExtra("pid", pid);
                context.startActivity(intent);
            }
        });
    }

    private String getImgUrl(String images) {
        int i = images.indexOf("!");
        return images.substring(0, i);
    }

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

    public interface OnCatagoryLisenter {
        void onNameClick(int cid);
    }

    private CatagoryAdapter.OnCatagoryLisenter onCatagoryLisenter;

    public void setOnCatagoryLisenter(CatagoryAdapter.OnCatagoryLisenter onCatagoryLisenter) {
        this.onCatagoryLisenter = onCatagoryLisenter;
    }

    static class ViewHolder extends RecyclerView.ViewHolder {
        @BindView(R.id.products_img)
        SimpleDraweeView productsImg;
        @BindView(R.id.products_title)
        TextView productsTitle;
        @BindView(R.id.products_yuanjia)
        TextView productsYuanjia;
        @BindView(R.id.products_xianjia)
        TextView productsXianjia;

        ViewHolder(View view) {
            super(view);
            ButterKnife.bind(this, view);
            productsYuanjia.getPaint().setFlags(Paint.STRIKE_THRU_TEXT_FLAG);
        }
    }
}

products-item

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">
<com.facebook.drawee.view.SimpleDraweeView
    android:id="@+id/products_img"
    app:placeholderImage="@drawable/ic_launcher_background"
    android:layout_width="100dp"
    android:layout_height="150dp" />

    <TextView
        android:id="@+id/products_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_toEndOf="@+id/products_img"
        android:text="标题" />

    <TextView
        android:id="@+id/products_yuanjia"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@+id/products_xianjia"
        android:layout_marginBottom="-78dp"
        android:layout_toEndOf="@+id/products_img"
        android:text="原价" />

    <TextView
        android:textColor="@color/colorAccent"
        android:id="@+id/products_xianjia"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_marginTop="106dp"
        android:layout_toEndOf="@+id/products_img"
        android:text="现价" />
</RelativeLayout>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值