实现订单列表页面

实现订单列表页面

思路:

1. 实现如图1视图布局;

2. 实现订单列表功能;

3. 订单列表各元素绘制,严格按照如图所示效果设计;

4. 实现下拉刷新和上拉加载更多,分页功能

5. 列表视图用RecyclerView控件展示

接口:

uid=71

订单列表

https://www.zhaoapi.cn/product/getOrders

uid =71 & page=1

请求参数说明:

uid 用户id字段 String类型 必传

page  页码数  String类型 非必传(实现分页功能时,必传)

返回字段说明

status  订单状态 String类型

0:待支付

1:已支付

2:已取消

1.依赖

//Retrofit网络请求依赖》
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
compile 'com.squareup.retrofit2:converter-gson:2.4.0'
//Recyclerview的依赖》
compile 'com.android.support:recyclerview-v7:26.1.0'
//Butterknife依赖(黄油刀)compile 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
//Rxjava2compile 'io.reactivex.rxjava2:rxjava:2.1.7'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
//RXjava2的适配器》
compile 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
//SmartRefreshLayout依赖
compile 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0-alpha-5'
compile 'com.scwang.smartrefresh:SmartRefreshHeader:1.1.0-alpha-5'//没有使用特殊Header,可以不加这行

2.权限

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

android:name=".app.App"
3.接口拼接

package com.example.dell.rikao0428.api;

import com.example.dell.rikao0428.bean.MyDataBean;
import io.reactivex.Flowable;
import retrofit2.http.GET;
import retrofit2.http.Query;

public interface ApiService {
    //Flowable:背压
    //拼接接口
    @GET("product/getOrders")
    Flowable<MyDataBean> getData(@Query("uid")String uid,@Query("page")String page);
}

4.接口拼接

package com.example.dell.rikao0428.utils;

//接口拼接
public class StringUrl {
    //接口路径
    public static final String BASE_URL="https://www.zhaoapi.cn/";
}

5.Retrofit网络请求封装

package com.example.dell.rikao0428.utils;

import com.example.dell.rikao0428.api.ApiService;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

public class RetrofitUtils {
    //1创建一个单列模式
    private static volatile RetrofitUtils instance;
    private final Retrofit retrofit;

    //2创建一个私有的无参构造
    private RetrofitUtils(){

        //创建Retrofit
        retrofit = new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create())//默认Gson进行解析
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())//使用RxJava2的适配器
                .baseUrl(StringUrl.BASE_URL)//接口
                .build();

    }
    //4.创建一个静态方法,得到instance 判断是否为空
    public static RetrofitUtils getInstance(){
        if(null==instance){
            synchronized (RetrofitUtils.class){
                if(instance==null){
                    instance = new RetrofitUtils();
                }
            }
        }
        //5返回创建的instance
        return instance;
    }
    //6创建方法 方便调用
    public ApiService getApiService(){
        return  retrofit.create(ApiService.class);
    }
}

6.SmartRefreshLayout的App

package com.example.dell.rikao0428.app;

import android.app.Application;
import android.content.Context;
import com.example.dell.rikao0428.R;
import com.scwang.smartrefresh.layout.SmartRefreshLayout;
import com.scwang.smartrefresh.layout.api.DefaultRefreshFooterCreator;
import com.scwang.smartrefresh.layout.api.DefaultRefreshHeaderCreator;
import com.scwang.smartrefresh.layout.api.RefreshFooter;
import com.scwang.smartrefresh.layout.api.RefreshHeader;
import com.scwang.smartrefresh.layout.api.RefreshLayout;
import com.scwang.smartrefresh.layout.footer.ClassicsFooter;
import com.scwang.smartrefresh.layout.header.ClassicsHeader;

//SmartRefreshLayoutApp
public class App extends Application{
    //static 代码段可以防止内存泄露
    static {
        //设置全局的Header构建器
        SmartRefreshLayout.setDefaultRefreshHeaderCreator(new DefaultRefreshHeaderCreator() {
            @Override
            public RefreshHeader createRefreshHeader(Context context, RefreshLayout layout) {
                layout.setPrimaryColorsId(R.color.colorPrimary, android.R.color.white);//全局设置主题颜色
                return new ClassicsHeader(context);//.setTimeFormat(new DynamicTimeFormat("更新于 %s"));//指定为经典Header,默认是 贝塞尔雷达Header
            }
        });
        //设置全局的Footer构建器
        SmartRefreshLayout.setDefaultRefreshFooterCreator(new DefaultRefreshFooterCreator() {
            @Override
            public RefreshFooter createRefreshFooter(Context context, RefreshLayout layout) {
                //指定为经典Footer,默认是 BallPulseFooter
                return new ClassicsFooter(context).setDrawableSize(20);
            }
        });
    }
}

7.网络请求的数据Bean

package com.example.dell.rikao0428.bean;

import java.util.List;

public class MyDataBean {
    
    private String code;
    private String msg;
    private String page;
    private List<DataBean> data;

    public String getCode() {
        return code;
    }

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

    public String getMsg() {
        return msg;
    }

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

    public String getPage() {
        return page;
    }

    public void setPage(String page) {
        this.page = page;
    }

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

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

    public static class DataBean {

        private String createtime;
        private int orderid;
        private double price;
        private int status;
        private String title;
        private int uid;

        public String getCreatetime() {
            return createtime;
        }

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

        public int getOrderid() {
            return orderid;
        }

        public void setOrderid(int orderid) {
            this.orderid = orderid;
        }

        public double getPrice() {
            return price;
        }

        public void setPrice(double price) {
            this.price = price;
        }

        public int getStatus() {
            return status;
        }

        public void setStatus(int status) {
            this.status = status;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public int getUid() {
            return uid;
        }

        public void setUid(int uid) {
            this.uid = uid;
        }
    }
}

8.M层接口

package com.example.dell.rikao0428.model;

//M层接口
public interface DataModel {
    void getDataModel(String uid,String page);
}

9.M层实现类

package com.example.dell.rikao0428.model;

import com.example.dell.rikao0428.bean.MyDataBean;
import com.example.dell.rikao0428.presenter.MyDataPresenter;
import com.example.dell.rikao0428.utils.RetrofitUtils;
import io.reactivex.Flowable;

public class MyDataModel implements DataModel{

    //创建构造器 将P层传给M    MyDataPresenter presenter;
    public MyDataModel(MyDataPresenter presenter){
        this.presenter=presenter;
    }

    @Override
    public void getDataModel(String uid,String page) {
        Flowable<MyDataBean> flowable = RetrofitUtils.getInstance().getApiService().getData(uid,page);

       //调用P层方法 将数据传给P        presenter.Success(flowable);

    }
}

10.P层接口

package com.example.dell.rikao0428.presenter;

import com.example.dell.rikao0428.bean.MyDataBean;
import io.reactivex.Flowable;

//P层接口
public interface DataPresenter {
    //定义成功与失败的方法
    void Success(Flowable<MyDataBean> flowable);
    void Error();
}
11.P层实现类

package com.example.dell.rikao0428.presenter;

import com.example.dell.rikao0428.bean.MyDataBean;
import com.example.dell.rikao0428.model.MyDataModel;
import com.example.dell.rikao0428.view.DataView;
import java.util.List;
import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.subscribers.DefaultSubscriber;

public class MyDataPresenter implements DataPresenter{

    //创建构造器 将V层传给P    DataView dataView;
    private final MyDataModel model;

    public MyDataPresenter(DataView dataView){
        this.dataView=dataView;

        model = new MyDataModel(this);
    }

    //成功与失败的方法
    @Override
    public void Success(Flowable<MyDataBean> flowable) {
        flowable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new DefaultSubscriber<MyDataBean>() {
                    @Override
                    public void onNext(MyDataBean myDataBean) {
                        List<MyDataBean.DataBean> list = myDataBean.getData();
                        if(list!=null){
                            //调用V层方法 将数据传给V                            dataView.toBackHome(list);
                        }

                    }

                    @Override
                    public void onError(Throwable t) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });

    }

    @Override
    public void Error() {

    }

    //调用接收uid的方法
    public void getUid(String uid,String page){
            model.getDataModel(uid,page);
    }

}

12.V层接口

package com.example.dell.rikao0428.view;

import com.example.dell.rikao0428.bean.MyDataBean;
import java.util.List;

//V层接口
public interface DataView {
    //接收数据的方法
    void toBackHome(List<MyDataBean.DataBean> list);
}
13.V层实现类

package com.example.dell.rikao0428.view;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.Toast;
import com.example.dell.rikao0428.R;
import com.example.dell.rikao0428.adapter.MyAdapter;
import com.example.dell.rikao0428.bean.MyDataBean;
import com.example.dell.rikao0428.presenter.MyDataPresenter;
import com.scwang.smartrefresh.layout.api.RefreshLayout;
import com.scwang.smartrefresh.layout.listener.OnLoadMoreListener;
import com.scwang.smartrefresh.layout.listener.OnRefreshListener;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;

public class MainActivity extends AppCompatActivity implements DataView,MyAdapter.OnClickListener {

    @BindView(R.id.main_rcv)
    RecyclerView main_Rcv;
    private MyAdapter myAdapter;
    private String page = "1";//设置页数默认为0
    List<MyDataBean.DataBean> list;
    List<MyDataBean.DataBean> AllList = new ArrayList<>();//设置大的集合
    private int i = 0;//设置表示 用于判断上拉还是下拉

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);

        //设置布局管理器
        main_Rcv.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));

        //实例化P        final MyDataPresenter presenter = new MyDataPresenter(this);
        presenter.getUid("71",page);


        //设置监听事件
        RefreshLayout refreshLayout = (RefreshLayout)findViewById(R.id.refreshLayout);
        //下拉刷新
        refreshLayout.setOnRefreshListener(new OnRefreshListener() {
            @Override
            public void onRefresh(RefreshLayout refreshlayout) {
                i = 0;//状态值为0
                page = "1";//页数为1
                presenter.getUid("71",page);//调用P层请求方法
                setAdapter();//调用适配器
                refreshlayout.finishRefresh(2000/*,false*/);//传入false表示刷新失败
            }
        });

        //上拉加载
        refreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() {
            @Override
            public void onLoadMore(RefreshLayout refreshlayout) {
                i = 1;//状态值为1
                page= (Integer.valueOf(page)+1)+"";//页数每次加1 现在先转为int类型+1,再转为String类型
                presenter.getUid("71",page);//调用P层请求方法
                setAdapter();//调用适配器
                refreshlayout.finishLoadMore(2000/*,false*/);//传入false表示加载失败
            }
        });
    }

    //接收数据
    @Override
    public void toBackHome(List<MyDataBean.DataBean> list) {
        //判断状态值为时(下拉)
        if(i == 0){
            //清除原本集合中的全部数据
            AllList.clear();
        }

        //判断值不为0时,则为1(上拉) 将得到的集合全部添加到大集合中
        AllList.addAll(list);

        //调用适配器
        setAdapter();

    }

    //创建适配器
    public void setAdapter(){
        //判断适配器是否为空
        if(myAdapter==null){
            //为空则创建
            myAdapter = new MyAdapter(this, AllList);
            //赋值给RecyclerView
            main_Rcv.setAdapter(myAdapter);
        }else{
            //不为空则刷新即可
            myAdapter.notifyDataSetChanged();
        }

        //调用适配器中的监听事件
       myAdapter.OnClick(this);
    }
    //重写适配器中的监听事件
    @Override
    public void OnChaClick(int position) {
        Toast.makeText(this,"查看了订单",Toast.LENGTH_SHORT).show();


    }
}
14.适配器

package com.example.dell.rikao0428.adapter;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import com.example.dell.rikao0428.R;
import com.example.dell.rikao0428.bean.MyDataBean;
import java.util.List;

public class MyAdapter extends RecyclerView.Adapter{
    Context context;
    List<MyDataBean.DataBean> list;
    public MyAdapter(Context context, List<MyDataBean.DataBean> list) {
        this.context=context;
        this.list=list;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //引入子布局
        View view = View.inflate(context, R.layout.rcv_item, null);
        //创建MyViewHolder View传过去
        MyViewHolder myViewHolder = new MyViewHolder(view);
        return myViewHolder;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
        MyViewHolder myViewHolder = (MyViewHolder) holder;
        //为控件赋值
        myViewHolder.rcv_title.setText(list.get(position).getTitle());
        myViewHolder.rcv_price.setText("价格:"+list.get(position).getPrice());
        myViewHolder.rcv_data.setText("创建时间:"+list.get(position).getCreatetime());

       //得到集合中的状态值
        int i = list.get(position).getStatus();
        //进行判断 并赋值
        if(i==0){
            myViewHolder.rcv_zt.setText("待支付");
            myViewHolder.rcv_dd.setText("取消订单");
        }else if(i==1){
            myViewHolder.rcv_zt.setText("已支付");
            myViewHolder.rcv_dd.setText("查看订单");
        }else{
            myViewHolder.rcv_zt.setText("已取消");
            myViewHolder.rcv_dd.setText("查看订单");
        }

        //给查看订单设置点击事件
        myViewHolder.rcv_dd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
            //点击事件
            onClickListener.OnChaClick(position);
            }
        });

    }

    //集合的条目数量
    @Override
    public int getItemCount() {
        return list.size();
    }

    //创建MyViewHolder
    class MyViewHolder extends RecyclerView.ViewHolder{

        private final TextView rcv_title;
        private final TextView rcv_price;
        private final TextView rcv_zt;
        private final TextView rcv_data;
        private final Button rcv_dd;

        public MyViewHolder(View view) {
            super(view);

            //找到布局文件的控件的ID
            rcv_title = view.findViewById(R.id.rcv_title);
            rcv_price = view.findViewById(R.id.rcv_price);
            rcv_zt = view.findViewById(R.id.rcv_zt);
            rcv_data = view.findViewById(R.id.rcv_data);
            rcv_dd = view.findViewById(R.id.rcv_dd);
        }
}
    
    //创建暴露点击事件的类
    OnClickListener onClickListener;
    public void OnClick(OnClickListener onClickListener){
        this.onClickListener=onClickListener;
    }

    //创建点击事件接口
    public interface OnClickListener{
        void OnChaClick(int position);
    }



}
15.主布局

<?xml version="1.0" encoding="utf-8"?>

<!--设置SmartRefreshLayout为最大的控件 子控件只能有三个-->
<com.scwang.smartrefresh.layout.SmartRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/refreshLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.dell.rikao0428.view.MainActivity">

    <!--头部布局-->
    <com.scwang.smartrefresh.layout.header.ClassicsHeader
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <!--RecyclerView-->
    <android.support.v7.widget.RecyclerView
        android:id="@+id/main_rcv"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </android.support.v7.widget.RecyclerView>

    <!--底部布局-->
    <com.scwang.smartrefresh.layout.footer.ClassicsFooter
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</com.scwang.smartrefresh.layout.SmartRefreshLayout>
16.子条目布局

<?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:orientation="vertical"
    android:padding="10dp">

    <RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="50dp">
    <TextView
        android:id="@+id/rcv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="订单标题测试"
        android:layout_centerVertical="true"/>
    <TextView
        android:id="@+id/rcv_zt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="待支付"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"/>
</RelativeLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp">
        <TextView
            android:id="@+id/rcv_price"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#f00"
            android:text="价格:99.99"
            android:layout_centerVertical="true"/>

    </RelativeLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp">
        <TextView
            android:id="@+id/rcv_data"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="创建时间:2017-11-09T09:20:58"
            android:layout_centerVertical="true"/>

        <Button
            android:id="@+id/rcv_dd"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="查看订单"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"/>

    </RelativeLayout>


</LinearLayout>