您的位置:首页 > 理论基础 > 计算机网络

okHttp网络请求2——MVP

2017-10-25 20:20 155 查看
adapter包

package adapter;

import android.app.Activity;

import android.content.Context;

import android.content.Intent;

import android.sax.StartElementListener;

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.example.dell.zhoukao3.Main2Activity;

import com.example.dell.zhoukao3.Main3Activity;

import com.example.dell.zhoukao3.R;

import java.util.List;

import bean.Shop;

/**

 * Created by DELL on 2017/10/21.

 */

public class MyAdapter extends RecyclerView.Adapter {

    private Activity context;

    private List<Shop.DataBean> data;

    private final int atype=0;

    private final int btype=1;

    private final int ctype=2;

    public MyAdapter(Activity context, List<Shop.DataBean> data) {

        this.context = context;

        this.data = data;

   
4000
}

    @Override

    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        //View view = View.inflate(context, R.layout.rv_item, null);

        View view=null;

        RecyclerView.ViewHolder holder=null;

        switch (viewType)

        {

            case atype:

                view = View.inflate(context, R.layout.rv_item1, null);

                holder=new ViewHolder1(view);

                break;

            case btype:

                view = View.inflate(context, R.layout.rv_item2, null);

                holder=new ViewHolder2(view);

                break;

            case ctype:

                view = View.inflate(context, R.layout.rv_item3, null);

                holder=new ViewHolder3(view);

                break;

        }

        return holder;

    }

    @Override

    public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {

        switch (getItemViewType(position))

        {

            case atype:

                ViewHolder1 holder1= (ViewHolder1) holder;

                holder1.tv_name.setText(data.get(position).title);

                holder1.tv_price.setText(data.get(position).price+"");

                String images = data.get(position).images;

                String[] img = images.split("\\|");

                Glide.with(context).load(img[0]).into(holder1.iv);

                holder.itemView.setOnClickListener(new View.OnClickListener() {

                    @Override

                    public void onClick(View view) {

                        Intent intent=new Intent(context, Main3Activity.class);

                        intent.putExtra("title",data.get(position).title);

                        context.startActivity(intent);

                    }

                });

                break;

            case btype:

                ViewHolder2 holder2= (ViewHolder2) holder;

                holder2.tv_name.setText(data.get(position).title);

                holder2.tv_price.setText(data.get(position).price+"");

                String images1 = data.get(position).images;

                String[] img1 = images1.split("\\|");

                Glide.with(context).load(img1[0]).into(holder2.iv);

                holder.itemView.setOnClickListener(new View.OnClickListener() {

                    @Override

                    public void onClick(View view) {

                        Intent intent=new Intent(context, Main3Activity.class);

                        intent.putExtra("title",data.get(position).title);

                        context.startActivity(intent);

                    }

                });

                break;

            case ctype:

                ViewHolder3 holder3= (ViewHolder3) holder;

                holder3.tv_name.setText(data.get(position).title);

                holder3.tv_price.setText(data.get(position).price+"");

                String images2 = data.get(position).images;

                String[] img2 = images2.split("\\|");

                Glide.with(context).load(img2[0]).into(holder3.iv);

                holder.itemView.setOnClickListener(new View.OnClickListener() {

                    @Override

                    public void onClick(View view) {

                        Intent intent=new Intent(context, Main3Activity.class);

                        intent.putExtra("title",data.get(position).title);

                        context.startActivity(intent);

                    }

                });

                break;

        }

    }

    @Override

    public int getItemCount() {

        return data.size();

    }

    public class ViewHolder1 extends RecyclerView.ViewHolder{

        private final TextView tv_name;

        private final TextView tv_price;

        private final ImageView iv;

        public ViewHolder1(View itemView) {

            super(itemView);

            tv_name = itemView.findViewById(R.id.tv_name);

            tv_price = itemView.findViewById(R.id.tv_price);

            iv = itemView.findViewById(R.id.iv);

        }

    }

    public class ViewHolder2 extends RecyclerView.ViewHolder{

        private final TextView tv_name;

        private final TextView tv_price;

        private final ImageView iv;

        public ViewHolder2(View itemView) {

            super(itemView);

            tv_name = itemView.findViewById(R.id.tv_name);

            tv_price = itemView.findViewById(R.id.tv_price);

            iv = itemView.findViewById(R.id.iv);

        }

    }

    public class ViewHolder3 extends RecyclerView.ViewHolder{

        private final TextView tv_name;

        private final TextView tv_price;

        private final ImageView iv;

        public ViewHolder3(View itemView) {

            super(itemView);

            tv_name = itemView.findViewById(R.id.tv_name);

            tv_price = itemView.findViewById(R.id.tv_price);

            iv = itemView.findViewById(R.id.iv);

        }

    }

    @Override

    public int getItemViewType(int position) {

        if(data.get(position).itemtype==0)

        {

            return atype;

        }

        else if(data.get(position).itemtype==1)

        {

            return btype;

        }

        else

        {

            return ctype;

        }

    }

}

Bean类

bean

package bean;

import java.util.List;

/**

 * Created by DELL on 2017/10/21.

 */

public class Shop {

 

    public String msg;

    public String code;

    public String page;

    public List<DataBean> data;

    public static class DataBean {

        

        public double bargainPrice;

        public String createtime;

        public String detailUrl;

        public String images;

        public int itemtype;

        public int pid;

        public double price;

        public int pscid;

        public int salenum;

        public int sellerid;

        public String subhead;

        public String title;

    }

}

Main包

MainActivity

package com.example.dell.zhoukao3;

import android.animation.AnimatorSet;

import android.animation.ObjectAnimator;

import android.animation.ValueAnimator;

import android.content.Intent;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.view.View;

import android.view.animation.AnimationSet;

import android.widget.ImageView;

import android.widget.Toast;

import view.CountDownProgress;

public class MainActivity extends AppCompatActivity {

    private ImageView iv;

    private CountDownProgress countDownProgress;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        initView();

        initData();

    }

    private void initData() {

        ObjectAnimator animator=ObjectAnimator.ofFloat(iv,"translationY",0f,250f);

        ObjectAnimator animator1=ObjectAnimator.ofFloat(iv,"scaleX",1,2);

        ObjectAnimator animator2=ObjectAnimator.ofFloat(iv,"scaleX",2,1);

        AnimatorSet set=new AnimatorSet();

        set.play(animator1).before(animator2).after(animator);

        set.setDuration(3000);

        set.start();

    }

    private void initView() {

        iv = (ImageView) findViewById(R.id.iv);

        countDownProgress = (CountDownProgress) findViewById(R.id.countdownProgress);

        countDownProgress.setCountdownTime(10*1000);

        countDownProgress.setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View v) {

                countDownProgress.startCountDownTime(new CountDownProgress.OnCountdownFinishListener() {

                    @Override

                    public void countdownFinished() {

                        //Toast.makeText(MainActivity.this, "倒计时结束了--->该UI处理界面逻辑了", Toast.LENGTH_LONG).show();

                        Intent intent=new Intent(MainActivity.this,Main2Activity.class);

                        startActivity(intent);

                    }

                });

                /*Message message = Message.obtain();

                message.what = HANDLER_MESSAGE;

                handler.sendMessage(message);*/

            }

        });

    }

}

Main2Activity

package com.example.dell.zhoukao3;

import android.support.v4.widget.SwipeRefreshLayout;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.support.v7.widget.LinearLayoutManager;

import android.support.v7.widget.RecyclerView;

import android.view.View;

import com.jcodecraeer.xrecyclerview.XRecyclerView;

import java.io.IOException;

import java.util.List;

import adapter.MyAdapter;

import bean.Shop;

import okhttp3.Call;

import presenter.ShopPresenter;

import view.ShopView;

public class Main2Activity extends AppCompatActivity implements ShopView {

    private String s;

    private SwipeRefreshLayout swiperefreshlayout;

    private XRecyclerView recycler;

    private ShopPresenter presenter;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main2);

       // System.out.println(s.equals("any string"));

        initView();

        initData();

    }

    private void initData() {

        presenter = new ShopPresenter(this);

    }

    private void initView() {

        recycler = (XRecyclerView) findViewById(R.id.rv);

        recycler.setLoadingMoreEnabled(true);

        recycler.setPullRefreshEnabled(true);

    }

    @Override

    public void onShopSuccess(final List<Shop.DataBean> data) {

        System.out.println(data.size()+"^^^^^^^^^^^^");

        if(this!=null)

        {

            runOnUiThread(new Runnable() {

                @Override

                public void run() {

                    LinearLayoutManager linearLayoutManager=new LinearLayoutManager(Main2Activity.this);

                    linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);

                    recycler.setLayoutManager(linearLayoutManager);

                    MyAdapter adapter=new MyAdapter(Main2Activity.this,data);

                    recycler.setAdapter(adapter);

                    recycler.setLoadingListener(new XRecyclerView.LoadingListener() {

                        @Override

                        public void onRefresh() {

                            presenter.requestShop(1);

                            recycler.refreshComplete();

                        }

                        @Override

                        public void onLoadMore() {

                            presenter.requestShop(2);

                            recycler.loadMoreComplete();

                        }

                    });

                }

            });

        }

    }

    @Override

    public void onShopFailure(String msg) {

    }

    @Override

    public void onFailure(Call call, IOException e) {

    }

    @Override

    protected void onResume() {

        super.onResume();

        presenter.requestShop(1);

    }

}

MyApp

package com.example.dell.zhoukao3;

import android.app.Application;

import utils.CrashHandler;

/**

 * Created by
17b51
DELL on 2017/10/21.

 */

public class MyApp extends Application{

    @Override

    public void onCreate() {

        super.onCreate();

        /*CrashHandler crashHandler = CrashHandler.getInstance();

        crashHandler.init(getApplicationContext());*/

    }

}

api类

API

package common;

/**

 * Created by DELL on 2017/10/21.

 */

public class Api {

    public static  final String URL="http://120.27.23.105/product/getProducts?pscid=1";

}

拦截器

Interceptor

package lanjieqi;

import java.io.IOException;

import okhttp3.Connection;

import okhttp3.Request;

import okhttp3.Response;

/**

 * Created by DELL on 2017/10/21.

 */

public interface Interceptor {

    Response intercept(Chain chain) throws IOException;

    interface Chain{

        Request request();

        Response proceed(Request request)throws IOException;

        Connection connection();

    }

}

LoggingInterceptor

package lanjieqi;

import android.util.Log;

import java.io.IOException;

import okhttp3.*;

import okhttp3.internal.platform.Platform;

/**

 * Created by DELL on 2017/10/21.

 */

public class LoggingInterceptor implements okhttp3.Interceptor {

    public static String TAG = "LogInterceptor";

    @Override

    public Response intercept(Chain chain) throws IOException {

        Request request = chain.request();

        long startTime = System.currentTimeMillis();

        Response response = chain.proceed(chain.request());

        long endTime = System.currentTimeMillis();

        long duration=endTime-startTime;

        MediaType mediaType = response.body().contentType();

        String content = response.body().string();

        Log.d(TAG,"\n");

        Log.d(TAG,"----------Start----------------");

        Log.d(TAG, "| "+request.toString());

        String method=request.method();

        if("POST".equals(method)){

            StringBuilder sb = new StringBuilder();

            if (request.body() instanceof FormBody) {

                FormBody body = (FormBody) request.body();

                for (int i = 0; i < body.size(); i++) {

                    sb.append(body.encodedName(i) + "=" + body.encodedValue(i) + ",");

                }

                sb.delete(sb.length() - 1, sb.length());

                Log.d(TAG, "| RequestParams:{"+sb.toString()+"}");

            }

        }

        Log.d(TAG, "| Response:" + content);

        Log.d(TAG,"----------End:"+duration+"毫秒----------");

        return response.newBuilder()

                .body(ResponseBody.create(mediaType, content))

                .build();

    }

}

Model包

ShopModel

package model;

import com.google.gson.Gson;

import java.io.IOException;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import bean.Shop;

import common.Api;

import okhttp3.Call;

import okhttp3.Response;

import utils.Callbak;

import utils.NetRequestData;

/**

 * Created by DELL on 2017/10/21.

 */

public class ShopModel {

    private onShop onShop;

    public void getShop(int page){

        Map<String,String> params=new HashMap<>();

        params.put("page",page+"");

        NetRequestData.call(Api.URL, params, new Callbak() {

            @Override

            public void RequestSuccess(Call call, Response response) {

                try {

                    String result = response.body().string();

                    Gson gson=new Gson();

                    Shop shop = gson.fromJson(result, Shop.class);

                    List<Shop.DataBean> data = shop.data;

                    System.out.println("==============="+data.size());

                    String code = shop.code;

                    String msg = shop.msg;

                    if("0".equals(code))

                    {

                        onShop.onShopSuccess(data);

                    }

                    else

                    {

                        onShop.onShopFailure(msg);

                    }

                } catch (IOException e) {

                    e.printStackTrace();

                }

            }

            @Override

            public void RequestFaliure(Call call, IOException e) {

                onShop.onFailure(call,e);

            }

        });

    }

    public void setOnShop(ShopModel.onShop onShop) {

        this.onShop = onShop;

    }

    public interface onShop{

        void onShopSuccess(List<Shop.DataBean> data);

        void onShopFailure(String msg);

        void onFailure(Call call,IOException e);

    }

}

presenter包
ShopPresenter

package presenter;

import java.io.IOException;

import java.util.List;

import bean.Shop;

import model.ShopModel;

import okhttp3.Call;

import view.ShopView;

/**

 * Created by DELL on 2017/10/21.

 */

public class ShopPresenter implements ShopModel.onShop {

    private ShopModel shopModel;

    private ShopView shopView;

    public ShopPresenter(ShopView shopView) {

        this.shopView = shopView;

        shopModel=new ShopModel();

        shopModel.setOnShop(this);

    }

    public void requestShop(int page){

        shopModel.getShop(page);

    }

    @Override

    public void onShopSuccess(List<Shop.DataBean> data) {

        shopView.onShopSuccess(data);

    }

    @Override

    public void onShopFailure(String msg) {

        shopView.onShopFailure(msg);

    }

    @Override

    public void onFailure(Call call, IOException e) {

        shopView.onFailure(call,e);

    }

}

View

ShopView

package view;

import java.io.IOException;

import java.util.List;

import bean.Shop;

import okhttp3.Call;

/**

 * Created by DELL on 2017/10/21.

 */

public interface ShopView {

    void onShopSuccess(List<Shop.DataBean> data);

    void onShopFailure(String msg);

    void onFailure(Call call, IOException e);

}

Utils包

Callbak类

package utils;

import java.io.IOException;

import okhttp3.Call;

import okhttp3.Response;

/**

 * Created by DELL on 2017/10/21.

 */

public interface Callbak {

    void RequestSuccess(Call call, Response response);

    void RequestFaliure(Call call, IOException e);

}

CrashHandler

package utils;

import android.content.Context;

import android.content.pm.PackageInfo;

import android.content.pm.PackageManager;

import android.os.Looper;

import android.util.Log;

import android.widget.Toast;

import java.io.File;

import java.io.FileOutputStream;

import java.io.PrintWriter;

import java.io.StringWriter;

import java.io.Writer;

import java.lang.Thread.UncaughtExceptionHandler;

import java.lang.reflect.Field;

import java.text.DateFormat;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.HashMap;

import java.util.Map;

import android.content.Context;

import android.content.pm.PackageInfo;

import android.content.pm.PackageManager;

import android.content.pm.PackageManager.NameNotFoundException;

import android.os.Build;

import android.os.Environment;

import android.os.Looper;

import android.util.Log;

import android.widget.Toast;

/**

 * Created by DELL on 2017/10/21.

 */

public class CrashHandler implements Thread.UncaughtExceptionHandler {

    public static final String TAG = "CrashHandler";

    //系统默认的UncaughtException处理类

    private Thread.UncaughtExceptionHandler mDefaultHandler;

    //CrashHandler实例

    private static CrashHandler INSTANCE = new CrashHandler();

    //程序的Context对象

    private Context mContext;

    //用来存储设备信息和异常信息

    private Map<String, String> infos = new HashMap<String, String>();

    //用于格式化日期,作为日志文件名的一部分

    private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");

    /** 保证只有一个CrashHandler实例 */

    private CrashHandler() {

    }

    /** 获取CrashHandler实例 ,单例模式 */

    public static CrashHandler getInstance() {

        return INSTANCE;

    }

    /**

     * 初始化

     *

     * @param context

     */

    public void init(Context context) {

        mContext = context;

        //获取系统默认的UncaughtException处理器

        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();

        //设置该CrashHandler为程序的默认处理器

        Thread.setDefaultUncaughtExceptionHandler(this);

    }

    /**

     * 当UncaughtException发生时会转入该函数来处理

     */

    @Override

    public void uncaughtException(Thread thread, Throwable ex) {

        if (!handleException(ex) && mDefaultHandler != null) {

            //如果用户没有处理则让系统默认的异常处理器来处理

            mDefaultHandler.uncaughtException(thread, ex);

        } else {

            try {

                Thread.sleep(3000);

            } catch (InterruptedException e) {

                Log.e(TAG, "error : ", e);

            }

            //退出程序

            android.os.Process.killProcess(android.os.Process.myPid());

            System.exit(1);

        }

    }

    /**

     * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.

     *

     * @param ex

     * @return true:如果处理了该异常信息;否则返回false.

     */

    private boolean handleException(Throwable ex) {

        if (ex == null) {

            return false;

        }

        //使用Toast来显示异常信息

        new Thread() {

            @Override

            public void run() {

                Looper.prepare();

                Toast.makeText(mContext, "很抱歉,程序出现异常,即将退出.", Toast.LENGTH_LONG).show();

                Looper.loop();

            }

        }.start();

        //收集设备参数信息

        collectDeviceInfo(mContext);

        //保存日志文件

        saveCrashInfo2File(ex);

        return true;

    }

    /**

     * 收集设备参数信息

     * @param ctx

     */

    public void collectDeviceInfo(Context ctx) {

        try {

            PackageManager pm = ctx.getPackageManager();

            PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES);

            if (pi != null) {

                String versionName = pi.versionName == null ? "null" : pi.versionName;

                String versionCode = pi.versionCode + "";

                infos.put("versionName", versionName);

                infos.put("versionCode", versionCode);

            }

        } catch (NameNotFoundException e) {

            Log.e(TAG, "an error occured when collect package info", e);

        }

        Field[] fields = Build.class.getDeclaredFields();

        for (Field field : fields) {

            try {

                field.setAccessible(true);

                infos.put(field.getName(), field.get(null).toString());

                Log.d(TAG, field.getName() + " : " + field.get(null));

            } catch (Exception e) {

                Log.e(TAG, "an error occured when collect crash info", e);

            }

        }

    }

    /**

     * 保存错误信息到文件中

     *

     * @param ex

     * @return  返回文件名称,便于将文件传送到服务器

     */

    private String saveCrashInfo2File(Throwable ex) {

        StringBuffer sb = new StringBuffer();

        for (Map.Entry<String, String> entry : infos.entrySet()) {

            String key = entry.getKey();

            String value = entry.getValue();

            sb.append(key + "=" + value + "\n");

        }

        Writer writer = new StringWriter();

        PrintWriter printWriter = new PrintWriter(writer);

        ex.printStackTrace(printWriter);

        Throwable cause = ex.getCause();

        while (cause != null) {

            cause.printStackTrace(printWriter);

            cause = cause.getCause();

        }

        printWriter.close();

        String result = writer.toString();

        sb.append(result);

        try {

            long timestamp = System.currentTimeMillis();

            String time = formatter.format(new Date());

            String fileName = "crash-" + time + "-" + timestamp + ".log";

            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {

                String path = "/mnt/sdcard/";

                File dir = new File(path);

                if (!dir.exists()) {

                    dir.mkdirs();

                }

                FileOutputStream fos = new FileOutputStream(path + fileName);

                fos.write(sb.toString().getBytes());

                fos.close();

            }

            return fileName;

        } catch (Exception e) {

            Log.e(TAG, "an error occured while writing file...", e);

        }

        return null;

    }

}

NetRequestDate类

package utils;

import java.io.IOException;

import java.util.Map;

import lanjieqi.LoggingInterceptor;

import okhttp3.Call;

import okhttp3.Callback;

import okhttp3.FormBody;

import okhttp3.OkHttpClient;

import okhttp3.Request;

import okhttp3.RequestBody;

import okhttp3.Response;

/**

 * Created by DELL on 2017/10/21.

 */

public class NetRequestData {

    public static void call(String url, Map<String,String> params, final Callbak callbak){

        OkHttpClient client=new OkHttpClient.Builder()

                .addInterceptor(new LoggingInterceptor())

                .build();

        FormBody.Builder body= new FormBody.Builder();

        for (Map.Entry<String, String> stringStringEntry : params.entrySet()) {

            body.add(stringStringEntry.getKey(),stringStringEntry.getValue());

        }

        RequestBody build = body.build();

        Request request=new Request.Builder().url(url).header("User-Agent", "OkHttp Example").post(build).build();

        client.newCall(request).enqueue(new Callback() {

            @Override

            public void onFailure(Call call, IOException e) {

                callbak.RequestFaliure(call,e);

            }

            @Override

            public void onResponse(Call call, Response response) throws IOException {

                callbak.RequestSuccess(call,response);

            }

        });

    }

}

CountDownProgress 属性动画

package view;

import android.animation.Animator;

import android.animation.ValueAnimator;

import android.content.Context;

import android.content.res.TypedArray;

import android.graphics.Paint;

import android.graphics.RectF;

import android.os.CountDownTimer;

import android.support.annotation.Nullable;

import android.util.AttributeSet;

import android.util.Log;

import android.view.View;

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Paint;

import android.graphics.Paint.Style;

import android.graphics.RectF;

import android.util.AttributeSet;

import android.view.View;

import android.view.animation.Animation;

import android.view.animation.LinearInterpolator;

import android.view.animation.RotateAnimation;

import com.example.dell.zhoukao3.R;

/**

 * Created by DELL on 2017/10/21.

 */

public class CountDownProgress extends View {

    private static int defaultCircleSolideColor = Color.BLUE;

    private static int defaultCircleStrokeColor = Color.WHITE;

    private static int defaultCircleStrokeWidth = 8;

    private static int defaultCircleRadius = 200;

    private static int progressColor = Color.RED;

    private static int progressWidth = 4;

    private static int smallCircleSolideColor = Color.BLACK;

    private static int smallCircleStrokeColor = Color.WHITE;

    private static float smallCircleStrokeWidth = 8;

    private static float smallCircleRadius = 30;

    private static int textColor = Color.BLACK;

    private static float textSize = 30;

    private static Paint defaultCriclePaint;

    private static Paint progressPaint;

    private static Paint smallCirclePaint;

    private static Paint smallCircleSolidePaint;

    private static Paint textPaint;

    private static float currentAngle;

    private static String textDesc;

    private static long countdownTime;

    private static int mStartSweepValue = -90;

    public CountDownProgress(Context context) {

        super(context);

    }

    public CountDownProgress(Context context, AttributeSet attrs) {

        super(context, attrs);

    }

    public CountDownProgress(Context context, AttributeSet attrs, int defStyleAttr) {

        super(context, attrs, defStyleAttr);

        //获取自定义属性

        TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.CountDownProgress);

        int indexCount = typedArray.getIndexCount();

        for(int i=0;i<indexCount;i++){

            int attr = typedArray.getIndex(i);

            switch (attr){

                case R.styleable.CountDownProgress_default_circle_solide_color:

                    defaultCircleSolideColor = typedArray.getColor(attr, defaultCircleSolideColor);

                    break;

                case R.styleable.CountDownProgress_default_circle_stroke_color:

                    defaultCircleStrokeColor = typedArray.getColor(attr, defaultCircleStrokeColor);

                    break;

                case R.styleable.CountDownProgress_default_circle_stroke_width:

                    defaultCircleStrokeWidth = (int) typedArray.getDimension(attr, defaultCircleStrokeWidth);

                    break;

                case R.styleable.CountDownProgress_default_circle_radius:

                    defaultCircleRadius = (int) typedArray.getDimension(attr, defaultCircleRadius);

                    break;

                case R.styleable.CountDownProgress_progress_color:

                    progressColor = typedArray.getColor(attr, progressColor);

                    break;

                case R.styleable.CountDownProgress_progress_width:

                    progressWidth = (int) typedArray.getDimension(attr, progressWidth);

                    break;

                case R.styleable.CountDownProgress_small_circle_solide_color:

                    smallCircleSolideColor = typedArray.getColor(attr, smallCircleSolideColor);

                    break;

                case R.styleable.CountDownProgress_small_circle_stroke_color:

                    smallCircleStrokeColor = typedArray.getColor(attr, smallCircleStrokeColor);

                    break;

                case R.styleable.CountDownProgress_small_circle_stroke_width:

                    smallCircleStrokeWidth = (int) typedArray.getDimension(attr, smallCircleStrokeWidth);

                    break;

                case R.styleable.CountDownProgress_small_circle_radius:

                    smallCircleRadius = (int) typedArray.getDimension(attr, smallCircleRadius);

                    break;

                case R.styleable.CountDownProgress_text_color:

                    textColor = typedArray.getColor(attr, textColor);

                    break;

                case R.styleable.CountDownProgress_text_size:

                    textSize = (int) typedArray.getDimension(attr, textSize);

                    break;

            }

        }

        typedArray.recycle();

    }

    private void setPaint() {

        //默认圆

        defaultCriclePaint = new Paint();

        defaultCriclePaint.setAntiAlias(true);//抗锯齿

        defaultCriclePaint.setDither(true);//防抖动

        defaultCriclePaint.setStyle(Paint.Style.STROKE);

        defaultCriclePaint.setStrokeWidth(defaultCircleStrokeWidth);

        defaultCriclePaint.setColor(defaultCircleStrokeColor);//这里先画边框的颜色,后续再添加画笔画实心的颜色

        //默认圆上面的进度弧度

        progressPaint = new Paint();

        progressPaint.setAntiAlias(true);

        progressPaint.setDither(true);

        progressPaint.setStyle(Paint.Style.STROKE);

        progressPaint.setStrokeWidth(progressWidth);

        progressPaint.setColor(progressColor);

        progressPaint.setStrokeCap(Paint.Cap.ROUND);//设置画笔笔刷样式

        //进度上面的小圆

        smallCirclePaint = new Paint();

        smallCirclePaint.setAntiAlias(true);

        smallCirclePaint.setDither(true);

        smallCirclePaint.setStyle(Paint.Style.STROKE);

        smallCirclePaint.setStrokeWidth(smallCircleStrokeWidth);

        smallCirclePaint.setColor(smallCircleStrokeColor);

        //画进度上面的小圆的实心画笔(主要是将小圆的实心颜色设置成白色)

        smallCircleSolidePaint = new Paint();

        smallCircleSolidePaint.setAntiAlias(true);

        smallCircleSolidePaint.setDither(true);

        smallCircleSolidePaint.setStyle(Paint.Style.FILL);

        smallCircleSolidePaint.setColor(smallCircleSolideColor);

        //文字画笔

        textPaint = new Paint();

        textPaint.setAntiAlias(true);

        textPaint.setDither(true);

        textPaint.setStyle(Paint.Style.FILL);

        textPaint.setColor(textColor);

        textPaint.setTextSize(textSize);

    }

    @Override

    protected void onDraw(Canvas canvas) {

        super.onDraw(canvas);

        setPaint();

        canvas.save();

        canvas.translate(getPaddingLeft(), getPaddingTop());

        //画默认圆

        canvas.drawCircle(defaultCircleRadius, defaultCircleRadius, defaultCircleRadius, defaultCriclePaint);

        //画进度圆弧

        //currentAngle = getProgress()*1.0f/getMax()*360;

        canvas.drawArc(new RectF(0, 0, defaultCircleRadius*2, defaultCircleRadius*2),mStartSweepValue, 360*currentAngle,false,progressPaint);

        //画中间文字

        // String text = getProgress()+"%";

        //获取文字的长度的方法

        /* float textWidth = textPaint.measureText(textDesc);

         float textHeight = (textPaint.descent() + textPaint.ascent()) / 2;

         canvas.drawText(textDesc, defaultCircleRadius - textWidth/2, defaultCircleRadius - textHeight, textPaint);*/

        //画小圆

        float currentDegreeFlag = 360*currentAngle;

        float smallCircleX = 0,smallCircleY = 0;

        float hudu = (float) Math.abs(Math.PI * currentDegreeFlag / 180);//Math.abs:绝对值 ,Math.PI:表示π , 弧度 = 度*π / 180

        smallCircleX = (float) Math.abs(Math.sin(hudu) * defaultCircleRadius + defaultCircleRadius);

        smallCircleY = (float) Math.abs(defaultCircleRadius -Math.cos(hudu) * defaultCircleRadius);

        canvas.drawCircle(smallCircleX, smallCircleY, smallCircleRadius, smallCirclePaint);

        canvas.drawCircle(smallCircleX, smallCircleY, smallCircleRadius - smallCircleStrokeWidth, smallCircleSolidePaint);//画小圆的实心

        canvas.restore();

    }

    /**

     * 如果该View布局的宽高开发者没有精确的告诉,则需要进行测量,如果给出了精确的宽高则我们就不管了

     * @param widthMeasureSpec

     * @param heightMeasureSpec

     */

    @Override

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);

        int heightMode = MeasureSpec.getMode(heightMeasureSpec);

        int widthSize;

        int heightSize;

        int strokeWidth = Math.max(defaultCircleStrokeWidth, progressWidth);

        if(widthMode != MeasureSpec.EXACTLY){

            widthSize = getPaddingLeft() + defaultCircleRadius*2 + strokeWidth + getPaddingRight();

            widthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);

        }

        if(heightMode != MeasureSpec.EXACTLY){

            heightSize = getPaddingTop() + defaultCircleRadius*2 + strokeWidth + getPaddingBottom();

            heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY);

        }

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    }

    //属性动画

    public void startCountDownTime(final OnCountdownFinishListener countdownFinishListener){

        setClickable(false);

        ValueAnimator animator = ValueAnimator.ofFloat(0, 1.0f);

        //动画时长,让进度条在CountDown时间内正好从0-360走完,这里由于用的是CountDownTimer定时器,倒计时要想减到0则总时长需要多加1000毫秒,所以这里时间也跟着+1000ms

        animator.setDuration(3000);

        animator.setInterpolator(new LinearInterpolator());//匀速

        animator.setRepeatCount(0);//表示不循环,-1表示无限循环

        //值从0-1.0F 的动画,动画时长为countdownTime,ValueAnimator没有跟任何的控件相关联,那也正好说明ValueAnimator只是对值做动画运算,而不是针对控件的,我们需要监听ValueAnimator的动画过程来自己对控件做操作

        //添加监听器,监听动画过程中值的实时变化(animation.getAnimatedValue()得到的值就是0-1.0)

        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

            @Override

            public void onAnimationUpdate(ValueAnimator animation) {

                /**

                 * 这里我们已经知道ValueAnimator只是对值做动画运算,而不是针对控件的,因为我们设置的区间值为0-1.0f

                 * 所以animation.getAnimatedValue()得到的值也是在[0.0-1.0]区间,而我们在画进度条弧度时,设置的当前角度为360*currentAngle,

                 * 因此,当我们的区间值变为1.0的时候弧度刚好转了360度

                 */

                currentAngle = (float) animation.getAnimatedValue();

                //       Log.e("currentAngle",currentAngle+"");

                invalidate();//实时刷新view,这样我们的进度条弧度就动起来了

            }

        });

        //开启动画

        animator.start();

        //还需要另一个监听,监听动画状态的监听器

        animator.addListener(new Animator.AnimatorListener() {

            @Override

            public void onAnimationStart(Animator animation) {

            }

            @Override

            public void onAnimationEnd(Animator animation) {

                //倒计时结束的时候,需要通过自定义接口通知UI去处理其他业务逻辑

                if(countdownFinishListener != null){

                    countdownFinishListener.countdownFinished();

                }

                if(countdownTime > 0){

                    setClickable(true);

                }else{

                    setClickable(false);

                }

            }

            @Override

            public void onAnimationCancel(Animator animation) {

            }

            @Override

            public void onAnimationRepeat(Animator animation) {

            }

        });

        //调用倒计时操作

        countdownMethod();

    }

    //倒计时的方法

    private void countdownMethod(){

        new CountDownTimer(countdownTime+1000, 1000) {

            @Override

            public void onTick(long millisUntilFinished) {

                //         Log.e("time",countdownTime+"");

                countdownTime = countdownTime-1000;

                textDesc = countdownTime/1000 + "″";

                //countdownTime = countdownTime-1000;

                Log.e("time",countdownTime+"");

                //刷新view

                invalidate();

            }

            @Override

            public void onFinish() {

                //textDesc = 0 + "″";

                textDesc = "时间到";

                //同时隐藏小球

                smallCirclePaint.setColor(getResources().getColor(android.R.color.transparent));

                smallCircleSolidePaint.setColor(getResources().getColor(android.R.color.transparent));

                //刷新view

                invalidate();

            }

        }.start();

    }

    public void setCountdownTime(long countdownTime){

        this.countdownTime = countdownTime;

        textDesc = countdownTime / 1000 + "″";

    }

    public interface OnCountdownFinishListener {

        void countdownFinished();

    }

}

attr

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

<resources>

    <declare-styleable name="RoundProgressBar">

        <attr name="radius" format="dimension"></attr>

        <attr name="roundColor" format="color" />

        <attr name="roundProgressOneColor" format="color" />

        <attr name="roundProgressTwoColor" format="color" />

        <attr name="roundProgressThreeColor" format="color" />

        <attr name="roundWidth" format="dimension"></attr>

        <attr name="roundProgressOneWidth" format="dimension" />

        <attr name="roundProgressTwoWidth" format="dimension" />

        <attr name="roundProgressThreeWidth" format="dimension" />

        <attr name="smallRoundWidth" format="dimension" />

        <attr name="topTextColor" format="color" />

        <attr name="bottomTextColor" format="color" />

        <attr name="topTextSize" format="dimension" />

        <attr name="bottomTextSize" format="dimension" />

        <attr name="lineColor" format="color" />

        <attr name="lineWidth" format="dimension" />

        <attr name="max" format="integer"></attr>

        <attr name="textIsDisplayable" format="boolean"></attr>

    </declare-styleable>

    <declare-styleable name="CountDownProgress">

        <!-- 默认圆实心的颜色 -->

        <attr name="default_circle_solide_color" format="color"/>

        <!-- 默认圆边框的颜色 -->

        <attr name="default_circle_stroke_color" format="color"/>

        <!-- 默认圆边框的宽度 -->

        <attr name="default_circle_stroke_width" format="dimension"/>

        <!-- 默认圆的半径 -->

        <attr name="default_circle_radius" format="dimension"/>

        <!-- 进度条的颜色 -->

        <attr name="progress_color" format="color"/>

        <!-- 进度条的宽度 -->

        <attr name="progress_width" format="dimension"/>

        <!-- 小圆的实心颜色 -->

        <attr name="small_circle_solide_color" format="color"/>

        <!-- 小圆的边框颜色 -->

        <attr name="small_circle_stroke_color" format="color"/>

        <!-- 小圆的边框宽度 -->

        <attr name="small_circle_stroke_width" format="dimension"/>

        <!-- 小圆的半径 -->

        <attr name="small_circle_radius" format="dimension"/>

        <!-- 文字的颜色 -->

        <attr name="text_color" format="color"/>

        <!-- 文字的字体大小 -->

        <attr name="text_size" format="dimension"/>

    </declare-styleable>

</resources>

权限

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

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

依赖

compile 'com.squareup.okhttp3:okhttp:3.9.0'

    compile 'org.kie.modules:com-google-code-gson:6.5.0.Final'

    compile 'com.google.code.gson:gson:2.8.2'

    compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'

    compile 'com.github.bumptech.glide:glide:3.7.0'

    compile 'com.jcodecraeer:xrecyclerview:1.3.2'

Main布局

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

<LinearLayout 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:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context="com.example.dell.zhoukao3.MainActivity"

    android:orientation="vertical"

    android:weightSum="1">

    <ImageView

        android:id="@+id/iv"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:src="@mipmap/ic_launcher" />

   <!-- <view.CountDownProgress

        android:id="@+id/countdownprogress"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content" />-->

    <view.CountDownProgress

        android:id="@+id/countdownProgress"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_centerInParent="true"

        android:layout_gravity="center"

        />

</LinearLayout>

Main2布局

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

<RelativeLayout 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:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context="com.example.dell.zhoukao3.Main2Activity">

  <!-- <android.support.v4.widget.SwipeRefreshLayout

        android:id="@+id/swiperefreshlayout"

        android:layout_width="fill_parent"

        android:layout_height="fill_parent"

        android:scrollbars="vertical"

        >

        <android.support.v7.widget.RecyclerView

            android:id="@+id/recycler"

            android:layout_width="fill_parent"

            android:layout_height="fill_parent"

            ></android.support.v7.widget.RecyclerView>

    </android.support.v4.widget.SwipeRefreshLayout>-->

    <com.jcodecraeer.xrecyclerview.XRecyclerView

        android:id="@+id/rv"

        android:layout_width="match_parent"

        android:layout_height="match_parent"></com.jcodecraeer.xrecyclerview.XRecyclerView>

</RelativeLayout>

Main3布局

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

<LinearLayout 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:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context="com.example.dell.zhoukao3.Main3Activity">

    <WebView

        android:id="@+id/wv"

        android:layout_width="match_parent"

        android:layout_height="match_parent"></WebView>

</LinearLayout>

rv_item布局

<?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">

    <ImageView

        android:id="@+id/iv"

        android:layout_width="wrap_content"

        android:layout_height="84dp"

        android:src="@mipmap/ic_launcher"

        android:padding="10dp"/>

    <LinearLayout

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:orientation="vertical"

        android:padding="10dp">

    <TextView

        android:id="@+id/tv_name"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="title"

        android:padding="5dp"/>

        <TextView

            android:id="@+id/tv_price"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="price"

            android:padding="5dp"/>

</LinearLayout>

</LinearLayout>

rv_item1布局

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

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical" android:layout_width="match_parent"

    android:layout_height="match_parent">

    <ImageView

        android:id="@+id/iv"

        android:layout_width="wrap_content"

        android:layout_height="84dp"

        android:src="@mipmap/ic_launcher"

        android:padding="10dp"/>

    <LinearLayout

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:padding="10dp">

        <TextView

            android:id="@+id/tv_name"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="title"

            android:padding="5dp"/>

        <TextView

            android:id="@+id/tv_price"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="price"

            android:padding="5dp"/>

    </LinearLayout>

</LinearLayout>

rv_item2

<?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">

    <ImageView

    android:id="@+id/iv"

    android:layout_width="wrap_content"

    android:layout_height="84dp"

    android:src="@mipmap/ic_launcher"

    android:padding="10dp"/>

    <LinearLayout

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:orientation="vertical"

        android:padding="10dp">

        <TextView

            android:id="@+id/tv_name"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="title"

            android:padding="5dp"/>

        <TextView

            android:id="@+id/tv_price"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="price"

            android:padding="5dp"/>

    </LinearLayout>

</LinearLayout>

rv_item3

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

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical" android:layout_width="match_parent"

    android:layout_height="match_parent">

    <LinearLayout

        android:layout_width="match_parent"

        android:layout_height="wrap_content">

    <ImageView

        android:id="@+id/iv"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:src="@mipmap/ic_launcher"/>

    <ImageView

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:src="@mipmap/ic_launcher"/>

</LinearLayout>

    <LinearLayout

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:orientation="vertical"

        android:padding="10dp">

        <TextView

            android:id="@+id/tv_name"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="title"

            android:padding="5dp"/>

        <TextView

            android:id="@+id/tv_price"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="price"

            android:padding="5dp"/>

    </LinearLayout>

</LinearLayout>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: