android 用mvp模式来架构自己的app+打造Recyclerview万能适配器

最近又要启动新的项目,项目较小,所有就像尝试点自己不会的玩意。(在小公司造轮子有一点好处就是不用那么死板,老板叫你造轮子,你只要造出来能用就好)。于是就发现了一套自己没用到的架构来打造自己的轮子:dagger2+mvp+rxjava+retrofit2+bindview


什么是mvp模式,百度一大把,这里不做解释,像我做过j2ee开发的,很容易就能明白,类似于SSH那一套(struts+spring+hibernate


大概也就是,让View(视图)与Model(逻辑)和Presenter(控制)分别管理自己该管的东西。View管理视图,Model管理逻辑,但是Model与View之间不能直接进行交互,必须通过Presenter。



example:用Mvp模式让RecyclerView加载数据:


1,逻辑层:包括一个接口(里面要分别定义view,modle,presenter的接口以及要实现的方法)和一个实现该接口里的关于逻辑的接口的类


package biz;

import android.content.Context;
import android.support.v7.widget.RecyclerView;

import com.github.mikephil.charting.charts.PieChart;

/**
 * Created by Administrator on 2016/12/9.
 */

public interface HomePageFragmentContact {

    /**
     *     视图接口
     *     定义你需要activity或者fragment返回给你的参数:上下文,饼图(view),RecyclerView(view)
     */



    interface HomePageFragmentView {
        Context haveContext();

        PieChart havePieChart();

        RecyclerView haveRecyclerView();
    }

    /**
     * 逻辑层的接口,定义了加载饼图和Recyclerview加载数据的抽象方法
     */

    interface HomePageFragmentModel {
        void initPie(Context context, PieChart pieChart);
        void initModule(Context context, RecyclerView recyclerView);
    }

    /**
     * 控制层接口:让view与model间接的交互
     */

    interface HomePageFragmentPresenter {
        void initPie();
        void initModule();
    }
}

package biz;
import android.content.Context;
import android.graphics.Color;
import android.support.v7.widget.RecyclerView;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import com.alibaba.fastjson.JSON;
import com.github.mikephil.charting.charts.PieChart;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.PieData;
import com.github.mikephil.charting.data.PieDataSet;
import com.github.mikephil.charting.formatter.ValueFormatter;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
import com.github.mikephil.charting.utils.ViewPortHandler;
import com.wyt.hcy.parentmanagerapp.R;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import adapter.CommonAdapter;
import bean.Module;
import json.PieJsonData;
import utils.CommonViewHolder;
import utils.MyHttpUtils;

/**
 * Created by hcy on 2016/12/9.
 */

public class HomePageFragmentBiz implements HomePageFragmentContact.HomePageFragmentModel, OnChartValueSelectedListener {
     private PieData mPieData;
     private List moduleList;
     private CommonAdapter moduleAdapter;

    /**
     * 加载饼图
     * @param context
     * @param pieChart
     */
    @Override
    public void initPie(final Context context, final PieChart pieChart) {
        Map keyMap= new LinkedHashMap();


        keyMap.put("ago_time","7");

        keyMap.put("userno","1280150");


        new MyHttpUtils(context, keyMap, "/api/getOperationCondition.php", new MyHttpUtils.HttpResponseListener() {
            @Override
            public void HttpSuccess(String msg) {

                Log.i("获取学生作业的饼图数据::",msg);

                PieJsonData pieJsonData = JSON.parseObject(msg, PieJsonData.class);


                if (pieJsonData.getStatus()==9){

                    int Fval = pieJsonData.getResult().getFinish_num().getVal();
                    int UFval = pieJsonData.getResult().getNo_finish_num().getVal();


                    int total=Fval+UFval;


                    if (total==0){
                        Log.i("获取学生作业的饼图数据::",total+"");
                        mPieData = getPieData(2,context,Fval,UFval);
                      //  showPieChart(pieChart, mPieData);
                        pieChart.setNoDataTextDescription("本周没有作业发布奥");//没有数据的时候显示

                    }else{
                        mPieData = getPieData(2,context,Fval,UFval);
                        showPieChart(pieChart, mPieData);
                    }


                }

            }
        });

        //pieChart.setNoDataTextDescription("本周没有作业发布奥");//没有数据的时候显示
    }

    /**
     * 加载Recyclerview的逻辑
     * @param context
     * @param recyclerView
     */

    @Override
    public void initModule(final Context context, RecyclerView recyclerView) {
        moduleList = new ArrayList();
        moduleList.add(new Module("学习日志"));
        moduleList.add(new Module("应用"));
        moduleList.add(new Module("护眼"));
        moduleList.add(new Module("防沉迷"));
        moduleList.add(new Module("上网"));
        moduleList.add(new Module("留言墙"));
        moduleAdapter = new CommonAdapter(context, moduleList, R.layout.item_moduleadapter) {
            @Override
            public void convert(CommonViewHolder holder, Module list, int position) {

                holder.setText(R.id.tv_modulename, moduleList.get(position).getName());

            }
        };
        recyclerView.setAdapter(moduleAdapter);
        moduleAdapter.setItemClickListener(new CommonAdapter.onRecyclerViewItemClickListener() {
            @Override
            public void OnItemClickListener(View view, int position) {

                Toast.makeText(context,"点击"+moduleList.get(position),Toast.LENGTH_SHORT).show();

            }
        });
    }


    private void showPieChart(PieChart pieChart, PieData pieData) {
        // 展示百分比
        pieChart.setUsePercentValues(true);  //显示成百分比
        pieChart.setDescription("");//给饼图设置名称
        pieChart.setDrawSliceText(false);//设置隐藏饼图上文字,只显示百分比
        pieChart.setDrawHoleEnabled(true);//去除掉透明
        pieChart.setHoleColorTransparent(true);
        pieChart.setHoleRadius(50f);  //半径
        pieChart.setTransparentCircleRadius(55f); // 半透明圈
        pieChart.setHoleColor(Color.parseColor("#F1F1F1"));//设置同心圆的颜色
        // pieChart.setHoleRadius(0); //实心圆
        pieChart.setTransparentCircleColor(Color.parseColor("#F7F7F7"));
        pieChart.setTransparentCircleAlpha(110);
        // mChart.setDrawYValues(true);
        pieChart.setDrawCenterText(true);  //饼状图中间可以添加文字
        pieChart.setRotationAngle(90); // 初始旋转角度
        // 支持手动旋转true
        pieChart.setRotationEnabled(true); // 可以手动旋转
        pieChart.setCenterText("小明" + "\n" + "一周作业统计");  //饼状图中间的文字

        //设置数据
        pieChart.setData(pieData);

        Legend mLegend = pieChart.getLegend();  //获取比例图
        mLegend.setPosition(Legend.LegendPosition.RIGHT_OF_CHART);  //最右边显示
        mLegend.setForm(Legend.LegendForm.CIRCLE);  //设置比例图的形状,默认是方形
        mLegend.setXEntrySpace(7f);
        mLegend.setYEntrySpace(5f);
        mLegend.setTextSize(18);
        mLegend.setEnabled(true);//设置比列图不可见
        pieChart.animateXY(1000, 1000);  //设置动画
        //设置分块的单击事件
        pieChart.setOnChartValueSelectedListener(this);
        //设置文字大小与颜色
        pieData.getDataSet().setValueTextColor(Color.WHITE);
        pieData.getDataSet().setValueTextSize(18);
    }



    private PieData getPieData(int count, Context context,int F,int U) {
        ArrayList xValues = new ArrayList();//a饼图上要展示的内容
        xValues.add("已做");
        xValues.add("未做");
        ArrayList yValues = new ArrayList();//每个饼块的实际数据
  /*      // 饼图数据
        *//**//**
        * 将一个饼形图分成四部分, 四部分的数值比例为14:14:34:38
                * 所以 14代表的百分比就是14%
        *//**//**/
        float quarterly1 = F;
        float quarterly2 = U;
        yValues.add(new Entry(quarterly1, 0));
        yValues.add(new Entry(quarterly2, 1));
        //y轴的集合
        PieDataSet pieDataSet = new PieDataSet(yValues, "");//*显示在比例图上*//*
                pieDataSet.setSliceSpace(0f); //设置个饼状图之间的距离
        ArrayList colors = new ArrayList();
        // 饼图颜色
        //colors.add(Color.rgb(205, 205, 205));
        colors.add(Color.parseColor("#18A15E"));
        colors.add(Color.parseColor("#DB4538"));//
        // colors.add(Color.rgb(57, 135, 200));
        pieDataSet.setColors(colors);
        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        float px = 5 * (metrics.densityDpi / 160f);
        pieDataSet.setSelectionShift(px); // 选中态多出的长度
        pieDataSet.setValueFormatter(new ValueFormatter() {
            @Override
            public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
                int n = (int) value;
                String str = n + "%"; // 设置折线上显示数据的格式。如果不设置,将默认显示float数据格式。
                return str;
            }

        });
        PieData pieData = new PieData(xValues, pieDataSet);
        return pieData;
    }

    @Override
    public void onValueSelected(Entry e, int dataSetIndex, Highlight h) {

    }

    @Override
    public void onNothingSelected() {

    }
}


2.控制层:实现控制接口的方法,同时要包含一个视图层接口的引用和一个逻辑接口的引用,逻辑接口的引用要指向实现该接口的类


package presenter;

import biz.HomePageFragmentBiz;
import biz.HomePageFragmentContact;

/**
 * Created by hcy on 2016/12/9.
 */

public class HomePagefragmentPresenter implements HomePageFragmentContact.HomePageFragmentPresenter {

    private HomePageFragmentContact.HomePageFragmentView homePageFragmentView;

    private HomePageFragmentContact.HomePageFragmentModel homePageFragmentModel;

    public HomePagefragmentPresenter(HomePageFragmentContact.HomePageFragmentView homePageFragmentView) {
        this.homePageFragmentView = homePageFragmentView;
        homePageFragmentModel=new HomePageFragmentBiz();
    }

    @Override
    public void initPie() {

        homePageFragmentModel.initPie(homePageFragmentView.haveContext(),homePageFragmentView.havePieChart());

    }

    @Override
    public void initModule() {
        homePageFragmentModel.initModule(homePageFragmentView.haveContext(),homePageFragmentView.haveRecyclerView());
    }
}

3.视图层,实现视图接口的方法,绑定view和初始化控制类:


package fragment;

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.github.mikephil.charting.charts.PieChart;

import com.wyt.hcy.parentmanagerapp.R;

import biz.HomePageFragmentContact;
import divider.DividerGridItemDecoration;
import presenter.HomePagefragmentPresenter;

/**
 * 首页
 */
public class HomePageFragment extends Fragment implements HomePageFragmentContact.HomePageFragmentView {

    private RecyclerView rv_module;

    private PieChart mPieChart;


    private HomePagefragmentPresenter homePagefragmentPresenter;

    public HomePageFragment() {

    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_home_page, container, false);
    }


    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        initUI(view);
        initData();
    }


    private void initData() {
        homePagefragmentPresenter = new HomePagefragmentPresenter(this);
        initPieData();
        initModule();
    }

    private void initModule() {


        homePagefragmentPresenter.initModule();
    }

    private void initUI(View view) {
        mPieChart = (PieChart) view.findViewById(R.id.pieChart);
        rv_module = (RecyclerView) view.findViewById(R.id.rv_module);
        rv_module.setLayoutManager(new GridLayoutManager(getContext(), 3));
        rv_module.addItemDecoration(new DividerGridItemDecoration(getContext()));
    }


    private void initPieData() {
        homePagefragmentPresenter.initPie();
    }

    @Override
    public Context haveContext() {
        return getContext();
    }

    @Override
    public PieChart havePieChart() {
        return mPieChart;
    }

    @Override
    public RecyclerView haveRecyclerView() {
        return rv_module;
    }


}



RecyclerView的万能适配器:(在Listview完成适配器的基础上改的)


package utils;

import android.support.v7.widget.RecyclerView;
import android.util.SparseArray;
import android.view.View;
import android.widget.TextView;


/**
 * Created by hcy on 2016/11/14.
 * func:RecyclerView通用的ViewHolder
 */

public class CommonViewHolder extends RecyclerView.ViewHolder {

    private final SparseArray mViews;

    private View mConvertView;

    public CommonViewHolder(View itemView) {
        super(itemView);
        mConvertView = itemView;
        this.mViews = new SparseArray();
    }

    /**
     * 通过控件的Id获取对于的控件,如果没有则加入views
     *
     * @param viewId
     * @return
     */
    public  T findViewById(int viewId) {

        View view = mViews.get(viewId);
        if (view == null) {
            view = mConvertView.findViewById(viewId);
            mViews.put(viewId, view);
        }
        return (T) view;
    }


    //设置文本
    public void setText(int textViewID, String text) {
        TextView textView = findViewById(textViewID);
        textView.setText(text);
    }


}

package adapter;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;


import com.wyt.hcy.parentmanagerapp.R;

import java.util.List;

import utils.CommonViewHolder;

/**
 * Created by hcy on 2016/12/5.
 */

public abstract class CommonAdapter extends RecyclerView.Adapter{


    private Context context;


    private List  list;


    private int layoutId;

    private LayoutInflater inflater;

    private onRecyclerViewItemClickListener itemClickListener;

    public void setItemClickListener(onRecyclerViewItemClickListener itemClickListener) {
        this.itemClickListener = itemClickListener;
    }

    public CommonAdapter(Context context, List list, int layoutId) {
        this.context = context;
        this.list = list;
        this.layoutId = layoutId;

        inflater=LayoutInflater.from(context);

    }

    @Override
    public CommonViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new CommonViewHolder(inflater.inflate(layoutId,parent,false));
    }


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

    @Override
    public void onBindViewHolder(final CommonViewHolder holder, int position) {
        if (itemClickListener!=null){


            holder.itemView.setBackgroundResource(R.drawable.recycler_bg);



            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //注意,这里的position不要用上面参数中的position,会出现位置错乱
                    itemClickListener.OnItemClickListener(holder.itemView, holder.getLayoutPosition());
                }
            });
        }

        convert(holder, list.get(position), position);
    }

    public interface  onRecyclerViewItemClickListener{
        void OnItemClickListener(View view, int position);
    }

    public abstract void convert(CommonViewHolder holder,T list,int position);
}





 
  








你可能感兴趣的:(Android)