1.先导入需要的各种包
2.添加网络权限,
3.编写代码
布局就省略不写了
ok框架
package com.example.thinkpad.wsj20186251601v.model.util;
import android.os.Handler;
import android.os.Looper;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
public class OkhttpUtil {
private static OkhttpUtil mokhttpUtil;
private final OkHttpClient mokhttpClient;
private final Handler mHandler;
public OkhttpUtil(){
mHandler = new Handler(Looper.getMainLooper());
////拦截器log日志
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
PublicParamInterceptor publicParamInterceptor = new PublicParamInterceptor(map);
mokhttpClient = new OkHttpClient.Builder()
.writeTimeout(3000, TimeUnit.MILLISECONDS)
.readTimeout(3000, TimeUnit.MILLISECONDS)
.connectTimeout(3000, TimeUnit.MILLISECONDS)
//拦截器log日志
.addInterceptor(httpLoggingInterceptor)
.addInterceptor(publicParamInterceptor)
.build();
}
public static OkhttpUtil getInstance(){
if (mokhttpUtil==null){
synchronized (OkhttpUtil.class){
if (mokhttpUtil==null){
return new OkhttpUtil();
}
}
}
return mokhttpUtil;
}
public void doget(String url, final OkCallback okCallback){
final Request request = new Request.Builder()
.get()
.url(url)
.build();
Call call = mokhttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, final IOException e) {
if (okCallback!=null){
mHandler.post(new Runnable() {
@Override
public void run() {
okCallback.onFailure(e);
}
});
}
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
if (response != null && response.isSuccessful()) {
final String json = response.body().string();
mHandler.post(new Runnable() {
@Override
public void run() {
if (okCallback != null) {
okCallback.onResponse(json);
}
}
});
}
}
});
}
public void dopost(String url, Map<String, String> map, final OkCallback okCallback)throws IOException {
FormBody.Builder builder = new FormBody.Builder();
for (String key : map.keySet()) {
builder.add(key, map.get(key));
}
FormBody formBody = builder.build();
Request request = new Request.Builder()
.post(formBody)
.url(url)
.build();
Call call = mokhttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, final IOException e) {
if(okCallback!=null){
mHandler.post(new Runnable() {
@Override
public void run() {
okCallback.onFailure(e);
}
});
}
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
if (response != null && response.isSuccessful()) {
final String json = response.body().string();
mHandler.post(new Runnable() {
@Override
public void run() {
if (okCallback != null) {
okCallback.onResponse(json);
}
}
});
}
}
});
}
public interface OkCallback{
void onFailure(Exception e);
void onResponse(String json);
}
//自定义一个拦截器,封装公共请求参数 public class PublicParamInterceptor implements Interceptor { Map<String, String> paramMap = new HashMap<>(); public PublicParamInterceptor(Map<String, String> paramMap) { this.paramMap = paramMap; } @Override public Response intercept(Chain chain) throws IOException { //拿到原来的request Request oldRequest = chain.request(); //拿到请求的url String url = oldRequest.url().toString(); //判断是GET还是POST请求 if (oldRequest.method().equalsIgnoreCase("GET")) { if (paramMap != null && paramMap.size() > 0) { StringBuilder urlBuilder = new StringBuilder(url); //拼接公共请求参数 for (Map.Entry<String, String> entry : paramMap.entrySet()) { urlBuilder.append("&" + entry.getKey() + "=" + entry.getValue()); } url = urlBuilder.toString(); //如果之前的url没有?号,我们需要手动给他添加一个?号 if (!url.contains("?")) { url = url.replaceFirst("&", "?"); } //依据原来的request构造一个新的request, Request request = oldRequest.newBuilder() .url(url) .build(); return chain.proceed(request); } } else { if (paramMap != null && paramMap.size() > 0) { RequestBody body = oldRequest.body(); if (body != null && body instanceof FormBody) { FormBody formBody = (FormBody) body; //1.把原来的的body里面的参数添加到新的body中 FormBody.Builder builder = new FormBody.Builder(); //为了防止重复添加相同的key和value Map<String, String> temMap = new HashMap<>(); for (int i = 0; i < formBody.size(); i++) { builder.add(formBody.encodedName(i), formBody.encodedValue(i)); temMap.put(formBody.encodedName(i), formBody.encodedValue(i)); } //2.把公共请求参数添加到新的body中 for (Map.Entry<String, String> entry : paramMap.entrySet()) { if(!temMap.containsKey(entry.getKey())){ builder.add(entry.getKey(), entry.getValue()); } } FormBody newFormBody = builder.build(); //依据原来的request构造一个新的request, Request newRequest = oldRequest.newBuilder() .post(newFormBody) .build(); return chain.proceed(newRequest); } } } return chain.proceed(oldRequest); } } }
m层
package com.example.thinkpad.wsj20186251601v.model;
import android.util.Log;
import com.example.thinkpad.wsj20186251601v.model.bean.Bean;
import com.example.thinkpad.wsj20186251601v.model.util.OkhttpUtil;
import com.google.gson.Gson;
public class Loginmodel {
public void login(final ILoginmodel iLoginmodel){
String url="http://p6acqdvet.bkt.clouddn.com/_data_json.json";
OkhttpUtil instance = OkhttpUtil.getInstance();
instance.doget(url, new OkhttpUtil.OkCallback() {
@Override
public void onFailure(Exception e) {
}
@Override
public void onResponse(String json) {
// Log.e("tag","+++++++++"+json);
Gson gson = new Gson();
Bean bean = gson.fromJson(json,Bean.class);
if(iLoginmodel !=null){
iLoginmodel.onResponse(bean);
}
}
});
}
public interface ILoginmodel{
void onFailure(Exception e);
void onResponse(Bean bean);
}
}
p层
package com.example.thinkpad.wsj20186251601v.presses;
import com.example.thinkpad.wsj20186251601v.model.Loginmodel;
import com.example.thinkpad.wsj20186251601v.model.bean.Bean;
import com.example.thinkpad.wsj20186251601v.view.Iloginview;
public class Loginpresses {
Iloginview mloginview;
private final Loginmodel loginmodel;
public Loginpresses(Iloginview iloginview){
mloginview=iloginview;
loginmodel = new Loginmodel();
}
public void lohin(){
loginmodel.login(new Loginmodel.ILoginmodel() {
@Override
public void onFailure(Exception e) {
if (mloginview!=null){
mloginview.onFailure(e);
}
}
@Override
public void onResponse(Bean bean) {
if (mloginview!=null){
mloginview.onResponse(bean);
}
}
});
}
public void onDestroy(){
mloginview=null;
}
}
v层
package com.example.thinkpad.wsj20186251601v.view;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import com.example.thinkpad.wsj20186251601v.R;
import com.example.thinkpad.wsj20186251601v.apade.Myapade;
import com.example.thinkpad.wsj20186251601v.model.bean.Bean;
import com.example.thinkpad.wsj20186251601v.presses.Loginpresses;
import java.util.List;
public class MainActivity extends AppCompatActivity implements Iloginview{
private Loginpresses loginpresses;
private RecyclerView recyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.rv);
loginpresses = new Loginpresses(this);
loginpresses.lohin();
}
@Override
public void onFailure(Exception e) {
Toast.makeText(this,"e",Toast.LENGTH_LONG).show();
}
@Override
public void onResponse(Bean bean) {
final List<Bean.JsonBean> json = bean.getJson();
List<Bean.LikeBean> like = bean.getLike();
final Myapade myapade = new Myapade(json);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(MainActivity.this);
//1.类似listview条目的形式
recyclerView.setLayoutManager(linearLayoutManager);
//设置item线性摆放的方向,默认是垂直的
// linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
//2.类似gridView的形式
// GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 3);
// gridLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
// recyclerView.setLayoutManager(gridLayoutManager);
//
//3.瀑布流的形式
// StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
// recyClerView.setLayoutManager(staggeredGridLayoutManager);
myapade.setOnItemClickListener(new Myapade.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
json.remove(position);
// 这个方法没有动画效果,而且整个刷新
myapade.notifyDataSetChanged();
// //局部刷新
myapade.notifyItemRemoved(position);
//刷新后重新获取集合的大小
myapade.notifyItemRangeChanged(position,json.size());
}
});
recyclerView.setAdapter(myapade);
//设置默认的动画
// recyclerView.setItemAnimator(new DefaultItemAnimator());
//添加分割线
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL);
//设置分割线的颜色
// dividerItemDecoration.setDrawable(getResources().getDrawable(R.drawable.item_decoration));
// recyclerView.addItemDecoration(dividerItemDecoration);
}
@Override
protected void onDestroy() {
super.onDestroy();
loginpresses.onDestroy();
}
}
v层接口
package com.example.thinkpad.wsj20186251601v.view;
import com.example.thinkpad.wsj20186251601v.model.bean.Bean;
public interface Iloginview {
void onFailure(Exception e);
void onResponse(Bean bean);
}
RecyclerView的适配器
package com.example.thinkpad.wsj20186251601v.apade;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.thinkpad.wsj20186251601v.R;
import com.example.thinkpad.wsj20186251601v.model.bean.Bean;
import com.nostra13.universalimageloader.core.ImageLoader;
import java.util.ArrayList;
import java.util.List;
public class Myapade extends RecyclerView.Adapter<Myapade.MyViewHodel>{
List<Bean.JsonBean> arr= new ArrayList<Bean.JsonBean>();
public Myapade(List<Bean.JsonBean> list){
this.arr=list;
}
@NonNull
@Override
public MyViewHodel onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
// parent.addView(View.inflate(context1,R.layout.activity_main1,null));
View inflate = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_main1, parent, false);
MyViewHodel myViewHodel = new MyViewHodel(inflate);
return myViewHodel;
}
@Override
public void onBindViewHolder(@NonNull MyViewHodel holder, final int position) {
//String url="http://p6563v2ck.bkt.clouddn.com/t1.jpg";
String image = arr.get(position).getImage();
MyViewHodel holder1 = holder;
holder1.main1_tv.setText(arr.get(position).getName());
ImageLoader.getInstance().displayImage(image ,holder1.main1_iv,Myapp.getOptions());
holder.main1_tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (onItemClickListener != null) {
onItemClickListener.onItemClick(v,position);
}
}
});
}
@Override
public int getItemCount() {
return arr==null?0:arr.size();
}
public class MyViewHodel extends RecyclerView.ViewHolder{
private final ImageView main1_iv;
private final TextView main1_tv;
public MyViewHodel(View itemView) {
super(itemView);
main1_iv= itemView.findViewById(R.id.main1_iv);
main1_tv= itemView.findViewById(R.id.main1_tv);
}
}
//给RecyclerView设置条目点击监听
private OnItemClickListener onItemClickListener;
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
public interface OnItemClickListener {
void onItemClick(View view, int position);
}
}
ImageLoader的图片加载框架 在使用时要记住在清单文件中将该类添加 例:
android:name=".apade.Myapp"
package com.example.thinkpad.wsj20186251601v.apade;
import android.app.Application;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Handler;
import com.example.thinkpad.wsj20186251601v.R;
import com.nostra13.universalimageloader.cache.disc.naming.HashCodeFileNameGenerator;
import com.nostra13.universalimageloader.cache.memory.impl.LruMemoryCache;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
import com.nostra13.universalimageloader.core.display.SimpleBitmapDisplayer;
import com.nostra13.universalimageloader.core.download.BaseImageDownloader;
public class Myapp extends Application{
private Context context;
@Override
public void onCreate() {
super.onCreate();
context = this;
initDatas();
}
private void initDatas() {
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
//保存的每个缓存文件的最大长宽
.memoryCacheExtraOptions(480, 800) // default = device screen dimensions
//线程池内加载的数量
.threadPoolSize(3) // default
//解释:当同一个Uri获取不同大小的图片,缓存到内存时,只缓存一个。默认会缓存多个不同的大小的相同图片
.threadPriority(Thread.NORM_PRIORITY - 1) // default
//设置图片下载和显示的工作队列排序
.tasksProcessingOrder(QueueProcessingType.FIFO) // default
//拒绝缓存多个图片。
.denyCacheImageMultipleSizesInMemory()
//缓存策略你可以通过自己的内存缓存实现 ,这里用弱引用,缺点是太容易被回收了,不是很好!
.memoryCache(new LruMemoryCache(2 * 1024 * 1024))
//设置内存缓存的大小
.memoryCacheSize(2 * 1024 * 1024)
.memoryCacheSizePercentage(13) // default
//设置磁盘缓存大小 50M
.diskCacheSize(50 * 1024 * 1024)
//缓存的文件数量
.diskCacheFileCount(100)
//将保存的时候的URI名称用MD5 加密
.diskCacheFileNameGenerator(new HashCodeFileNameGenerator()) // default
.imageDownloader(new BaseImageDownloader(context)) // default
//显示图片的参数,默认:
.defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default
//打开调试日志
.writeDebugLogs()
//开始构建
.build();
ImageLoader.getInstance().init(config);
}
public static DisplayImageOptions getOptions() {
DisplayImageOptions options = new DisplayImageOptions.Builder()
//设置图片在下载期间显示的图片
.showImageOnLoading(R.mipmap.ic_launcher) // resource or drawable
//设置图片Uri为空或是错误的时候显示的图片
.showImageForEmptyUri(R.mipmap.ic_launcher) // resource or drawable
//设置图片加载/解码过程中错误时候显示的图片
.showImageOnFail(R.mipmap.ic_launcher) // resource or drawable
//设置图片在下载前是否重置,复位
.resetViewBeforeLoading(false) // default
//int delayInMillis为你设置的下载前的延迟时间
.delayBeforeLoading(1000)
//设置下载的图片是否缓存在内存中
.cacheInMemory(true) // default
//设置下载的图片是否缓存在SD卡中
.cacheOnDisk(true) // default
//设置图片以如何的编码方式显示
.imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) // default
//设置图片的解码类型
.bitmapConfig(Bitmap.Config.ARGB_8888) // default
//不推荐用!!!!是否设置为圆角,弧度为多少
.displayer(new SimpleBitmapDisplayer()) // default
.handler(new Handler()) // default
//构建完成
.build();
return options;
}
}