OkHttp+MVP数据请求(上拉下拉)
添加的依赖
compile 'com.squareup.okio:okio:1.5.0' compile 'com.squareup.okhttp3:okhttp:3.2.0' compile 'com.squareup.okhttp3:logging-interceptor:3.4.1' compile 'com.google.code.gson:gson:2.8.2' compile 'com.jcodecraeer:xrecyclerview:1.3.2' compile 'com.github.bumptech.glide:glide:3.6.1' <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
activity_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" android:orientation="vertical" tools:context="com.bawie.www.okhttpmvp.MainActivity"> <com.jcodecraeer.xrecyclerview.XRecyclerView android:layout_width="368dp" android:layout_height="495dp" android:id="@+id/mRecyclerView" tools:layout_editor_absoluteY="8dp" tools:layout_editor_absoluteX="8dp"> </com.jcodecraeer.xrecyclerview.XRecyclerView> </LinearLayout>
activity_main2
<?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.bawie.www.okhttpmvp.Main2Activity"> <ImageView android:layout_width="20dp" android:layout_height="20dp" android:id="@+id/img" android:src="@drawable/a" /> </LinearLayout>
activity_main3
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout 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.bawie.www.okhttpmvp.Main3Activity"> </android.support.constraint.ConstraintLayout>
activity_main22
Kong
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" android:orientation="horizontal" > <ImageView android:layout_width="100dp" android:layout_height="100dp" android:id="@+id/img" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:textSize="20dp" android:id="@+id/tv" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="10dp" android:id="@+id/tv2" /> </LinearLayout>
MainActivity
package com.bawie.www.okhttpmvp; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.view.View; import com.bawie.www.okhttpmvp.model.Bean; import com.bawie.www.okhttpmvp.presenter.MyAdapter; import com.bawie.www.okhttpmvp.presenter.Presenter; import com.bawie.www.okhttpmvp.view.Iv; import com.jcodecraeer.xrecyclerview.ProgressStyle; import com.jcodecraeer.xrecyclerview.XRecyclerView; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity implements Iv{ private XRecyclerView mRecyclerView; private MyAdapter adapter; private Presenter presenter; private int page=1; private boolean flag=true; private List<Bean.NewslistBean> lists=new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mRecyclerView= (XRecyclerView) findViewById(R.id.mRecyclerView); LinearLayoutManager man =new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false); mRecyclerView.setLayoutManager(man); adapter=new MyAdapter(this,lists); mRecyclerView.setAdapter(adapter); mRecyclerView.setLoadingMoreEnabled(true); mRecyclerView.setLoadingMoreProgressStyle(ProgressStyle.SquareSpin); mRecyclerView.setLoadingListener(new XRecyclerView.LoadingListener() { @Override public void onRefresh() { page=1; flag=true; loadData(); } @Override public void onLoadMore() { page++; flag=false; loadData(); } }); loadData(); adapter.setmOnItemClickListener(new MyAdapter.OnItemClickListener() { @Override public void onItemClick(View view, int position) { Intent intent =new Intent(MainActivity.this,Main2Activity.class); startActivity(intent); } }); } private void loadData() { presenter =new Presenter(this); presenter.get(page); } @Override public void onSuccess(List<Bean.NewslistBean> list) { if (flag) { mRecyclerView.refreshComplete(); }else { mRecyclerView.loadMoreComplete(); } lists.clear(); lists.addAll(list); adapter.notifyDataSetChanged(); } @Override public void onFailed(Exception e) { } @Override protected void onDestroy() { super.onDestroy(); presenter.DetchView(); } }
MainActivity2
package com.bawie.www.okhttpmvp; import android.animation.TypeEvaluator; import android.animation.ValueAnimator; import android.content.Intent; import android.graphics.PointF; import android.os.Handler; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.animation.LinearInterpolator; import android.widget.ImageView; public class Main2Activity extends AppCompatActivity { private ImageView imageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); imageView = (ImageView) findViewById(R.id.img); ValueAnimator valueAnimator =new ValueAnimator(); valueAnimator.setDuration(5000); valueAnimator.setObjectValues(new PointF(0, 0)); valueAnimator.setInterpolator(new LinearInterpolator()); valueAnimator.setEvaluator(new TypeEvaluator<PointF>() { // fraction = t / duration @Override public PointF evaluate(float fraction, PointF startValue, PointF endValue) { // x方向200px/s ,则y方向0.5 * 10 * t PointF point = new PointF(); point.x = 200 * fraction * 3; point.y = 0.5f * 200 * (fraction * 3) * (fraction * 3); return point; } }); valueAnimator.start(); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { PointF point = (PointF) animation.getAnimatedValue(); imageView.setX(point.x); imageView.setY(point.y); } }); new Handler().postDelayed(new Runnable() { @Override public void run() { Intent intent = new Intent(Main2Activity.this, Main3Activity.class); startActivity(intent); Main2Activity.this.finish(); } }, 5000); } }
MainActivity3
package com.bawie.www.okhttpmvp; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; public class Main3Activity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main3); } }
接口Iv
package com.bawie.www.okhttpmvp.view; import com.bawie.www.okhttpmvp.model.Bean; import java.util.List; /** * Created by HASEE on 2017/11/21. */ public interface Iv { void onSuccess(List<Bean.NewslistBean> list); void onFailed(Exception e); }
Presenter
package com.bawie.www.okhttpmvp.presenter; import com.bawie.www.okhttpmvp.callback.CallBack; import com.bawie.www.okhttpmvp.model.Bean; import com.bawie.www.okhttpmvp.view.Iv; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Created by HASEE on 2017/11/21. */ public class Presenter { private Iv iv; public Presenter(Iv iv) { this.iv = iv; } public void get(int i){ Map map = new HashMap<String,String>(); map.put("key","2a0024d1f7f558e09936f697580f1643"); map.put("num","10"); HttpUtils.getInstance().get("http://api.tianapi.com/travel/", map, new CallBack() { @Override public void onSuccess(Object o) { Bean bean= (Bean) o; List<Bean.NewslistBean> list=bean.getNewslist(); iv.onSuccess(list); } @Override public void onFailed(Exception e) { iv.onFailed(e); } },Bean.class); } public void DetchView(){ if (iv!=null){ iv=null; } } }
MyAdapter
package com.bawie.www.okhttpmvp.presenter; import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import com.bawie.www.okhttpmvp.R; import com.bawie.www.okhttpmvp.model.Bean; import com.bumptech.glide.Glide; import java.util.ArrayList; import java.util.List; /** * Created by HASEE on 2017/11/21. */ public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> { private Context context; private List<Bean.NewslistBean> list=new ArrayList<>(); private OnItemClickListener mOnItemClickListener; private OnItemLongClickListener mOnItemLongClickListener; public void setmOnItemClickListener(OnItemClickListener mOnItemClickListener) { this.mOnItemClickListener = mOnItemClickListener; } public void setmOnItemLongClickListener(OnItemLongClickListener mOnItemLongClickListener) { this.mOnItemLongClickListener = mOnItemLongClickListener; } public interface OnItemClickListener{ void onItemClick(View view, int position); } public interface OnItemLongClickListener{ void onItemLongClick(View view, int position); } public MyAdapter(Context context, List<Bean.NewslistBean> list) { this.context = context; this.list = list; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v=View.inflate(context, R.layout.item,null); MyViewHolder holder =new MyViewHolder(v); return holder; } @Override public void onBindViewHolder(final MyViewHolder holder, int position) { Bean.NewslistBean songListBean = list.get(position); Glide.with(context).load(songListBean.getPicUrl()).into(holder.img); holder.tv.setText(songListBean.getTitle()); holder.tv2.setText(songListBean.getDescription()); if (mOnItemClickListener!=null){ holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int position= holder.getLayoutPosition(); mOnItemClickListener.onItemClick(holder.itemView,position); } }); } if (mOnItemLongClickListener!=null){ holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View view) { int position= holder.getLayoutPosition(); mOnItemLongClickListener.onItemLongClick(holder.itemView,position); return true; } }); } } @Override public int getItemCount() { return list.size(); } class MyViewHolder extends RecyclerView.ViewHolder{ private ImageView img; private TextView tv; private TextView tv2; public MyViewHolder(View itemView) { super(itemView); img=(ImageView) itemView.findViewById(R.id.img); tv=(TextView)itemView.findViewById(R.id.tv); tv2=(TextView)itemView.findViewById(R.id.tv2); } } }
HttpUtils
package com.bawie.www.okhttpmvp.presenter; import android.os.Handler; import android.util.Log; import com.bawie.www.okhttpmvp.callback.CallBack; import com.bawie.www.okhttpmvp.model.Logger; import com.google.gson.Gson; import java.io.IOException; import java.util.Map; import okhttp3.Call; import okhttp3.Callback; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; /** * Created by HASEE on 2017/11/21. */ public class HttpUtils { private static volatile HttpUtils instance; private static Handler handler = new Handler(); private HttpUtils(){ } public static HttpUtils getInstance() { if (instance == null) { synchronized (HttpUtils.class) { if (instance == null) { instance = new HttpUtils(); } } } return instance; } public void get(String url, Map<String,String> map, final CallBack callBack, final Class c) { //对url和参数做拼接处理 StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append(url); //判断是否存在? if中是存在 if (stringBuffer.indexOf("?") != -1) { //判断?是否在最后一位 if中是不在最后一位 if (stringBuffer.indexOf("?") != stringBuffer.length() - 1) { stringBuffer.append("&"); } } else { stringBuffer.append("?"); } for (Map.Entry<String, String> entry : map.entrySet()) { stringBuffer.append(entry.getKey()) .append("=") .append(entry.getValue()) .append("&"); } //判断是否存在& if中是存在 if (stringBuffer.indexOf("&") != -1) { stringBuffer.deleteCharAt(stringBuffer.lastIndexOf("&")); } Log.i("TAG",stringBuffer.toString()); OkHttpClient okHttpClient = new OkHttpClient .Builder() .addInterceptor(new Logger()) .build(); Request request = new Request.Builder().get().url(stringBuffer.toString()).build(); Call call = okHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, final IOException e) { handler.post(new Runnable() { @Override public void run() { callBack.onFailed(e); } }); } @Override public void onResponse(Call call, Response response) throws IOException { String result = response.body().string(); Log.i("aaa",result); //拿到数据开始解析 final Object o = new Gson().fromJson(result, c); //当前是在子线程,回到主线程中 handler.post(new Runnable() { @Override public void run() { //回调 callBack.onSuccess(o); } }); } }); } }
Logger
package com.bawie.www.okhttpmvp.model; import java.io.IOException; import okhttp3.HttpUrl; import okhttp3.Interceptor; import okhttp3.Request; import okhttp3.Response; /** * Created by HASEE on 2017/11/21. */ public class Logger implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { Request original = chain.request(); HttpUrl url=original.url().newBuilder() .addQueryParameter("source","android") .build(); //添加请求头 Request request = original.newBuilder() .url(url) .build(); return chain.proceed(request); } }
Bean
package com.bawie.www.okhttpmvp.model; import java.util.List; /** * Created by HASEE on 2017/11/21. */ public class Bean { /** * code : 200 * msg : success * newslist : [{"ctime":"2016-03-06 14:11","title":"德克萨斯州体验美国的枪支文化","description":"网易旅游","picUrl":"http://imgsize.ph.126.net/?imgurl=http://img4.cache.netease.com/travel/2016/1/10/2016011011515085b41_550.jpg_180x130x1x85.jpg","url":"http://travel.163.com/16/0110/11/BCVF471L00063KE8.html"},{"ctime":"2016-03-06 14:11","title":"老外眼中的25大最中国特色 还真是这么回事!","description":"网易旅游","picUrl":"http://imgsize.ph.126.net/?imgurl=http://img5.cache.netease.com/travel/2016/1/10/201601101209010164a.jpg_180x130x1x85.jpg","url":"http://travel.163.com/16/0110/12/BCVGCMVN00063KE8.html"},{"ctime":"2016-03-06 14:11","title":"游客光天化日在巴西里约街头被少年抢劫","description":"网易旅游","picUrl":"http://imgsize.ph.126.net/?imgurl=http://img5.cache.netease.com/travel/2016/1/8/2016010812321010498_550.jpg_180x130x1x85.jpg","url":"http://travel.163.com/16/0110/12/BCVHQU9100063KE8.html"},{"ctime":"2016-03-06 14:11","title":"外国人没懂老炮儿翻译 这些影视译名戳你笑点","description":"网易旅游","picUrl":"http://imgsize.ph.126.net/?imgurl=http://img2.cache.netease.com/travel/2016/1/8/201601081300498c376_550.jpg_180x130x1x85.jpg","url":"http://travel.163.com/16/0110/13/BCVJ6SHV00063KE8.html"},{"ctime":"2016-03-06 14:11","title":"伤性食物最全名单 为了\u201c性福\u201d要少吃","description":"网易旅游","picUrl":"http://imgsize.ph.126.net/?imgurl=http://img6.cache.netease.com/travel/2016/1/8/201601081321198ce82.jpg_180x130x1x85.jpg","url":"http://travel.163.com/16/0110/13/BCVKIQQ700063KE8.html"},{"ctime":"2016-03-06 14:11","title":"人间伊甸园巴哈马 全球最性感的地方","description":"网易旅游","picUrl":"http://imgsize.ph.126.net/?imgurl=http://img1.cache.netease.com/travel/2016/1/8/201601081331427dc48.jpg_180x130x1x85.jpg","url":"http://travel.163.com/16/0110/13/BCVL54UE00063KE8.html"},{"ctime":"2016-03-06 14:11","title":"布达佩斯 那些被惊扰的闲情","description":"网易旅游","picUrl":"http://imgsize.ph.126.net/?imgurl=http://img2.cache.netease.com/travel/2016/1/8/2016010814115679b34_550.jpg_180x130x1x85.jpg","url":"http://travel.163.com/16/0110/14/BCVNECRQ00063KE8.html"},{"ctime":"2016-03-06 14:11","title":"去妖魔化 眼见一个真实的印度","description":"网易旅游","picUrl":"http://imgsize.ph.126.net/?imgurl=http://img4.cache.netease.com/travel/2016/1/8/20160108142728a8a8c.jpg_180x130x1x85.jpg","url":"http://travel.163.com/16/0110/14/BCVOFB4C00063KE8.html"},{"ctime":"2016-03-06 14:11","title":"放生羊:最能代表西藏的一道独特风景","description":"网易旅游","picUrl":"http://imgsize.ph.126.net/?imgurl=http://img1.cache.netease.com/catchpic/0/0E/0EEA8F0C2596FBFBC642E0356C4C66DC.jpg_180x130x1x85.jpg","url":"http://travel.163.com/16/0110/21/BD0FHVAB00063JSA.html"},{"ctime":"2016-03-06 14:11","title":"采蘑菇算什么 你敢去采水晶吗?","description":"网易旅游","picUrl":"http://imgsize.ph.126.net/?imgurl=http://img1.cache.netease.com/catchpic/D/D0/D072F1C37F12C211F352962DAB0D3156.jpg_180x130x1x85.jpg","url":"http://travel.163.com/16/0110/21/BD0G1H7800063KE8.html"}] */ private int code; private String msg; private List<NewslistBean> newslist; public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public List<NewslistBean> getNewslist() { return newslist; } public void setNewslist(List<NewslistBean> newslist) { this.newslist = newslist; } public static class NewslistBean { /** * ctime : 2016-03-06 14:11 * title : 德克萨斯州体验美国的枪支文化 * description : 网易旅游 * picUrl : http://imgsize.ph.126.net/?imgurl=http://img4.cache.netease.com/travel/2016/1/10/2016011011515085b41_550.jpg_180x130x1x85.jpg * url : http://travel.163.com/16/0110/11/BCVF471L00063KE8.html */ private String ctime; private String title; private String description; private String picUrl; private String url; public String getCtime() { return ctime; } public void setCtime(String ctime) { this.ctime = ctime; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getPicUrl() { return picUrl; } public void setPicUrl(String picUrl) { this.picUrl = picUrl; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } } }
CallBack接口
package com.bawie.www.okhttpmvp.callback; /** * Created by HASEE on 2017/11/21. */ public interface CallBack { void onSuccess(Object o); void onFailed(Exception e); }