1. 示例图
  2. 技术选型
  3. 业务逻辑需求
  4. 接口
  5. MainActivity.java
  6. HttpUtils
  7. CallBack
  8. INewsView
  9. LoggingInterceptor拦截器
  10. GsonUtils
  11. NewsPresenter
  12. NewsListAdapter
  13. Main2Activity.java
  14. activity_main.xml
  15. activity_main2.xml
  16. item.xml
  17. 权限
  18. 依赖

示例图:

Android——自定义拦截器实现OKHttp网络请求_第1张图片Android——自定义拦截器实现OKHttp网络请求_第2张图片

一、技术选型:

1. 项目框架:MVP;注意:避免内存泄漏;

2. 图片加载: Universal-Image-Loader或Glide图片加载框架

3.网络加载框架:OkHttp

4. 自定义应用拦截器,封装公共请求参数(注意:必须通过拦截器封装公共请求参数,否则无法请求数据)

公共请求参数,在我们项目研发过程中,作用非常大。封装公共请求承参数之后,那么所有的接口都会默认携带这些公共参数,达到复用的效果。

公共请求参数:source=android

参数名称:source

参数值:android

类型:String

是否必传:是

5. 数据展示使用RecylerView;

二、业务逻辑需求:

1. 搜索框输入关键字(笔记本、手机),其他关键词没有数据,点击搜索实现如图效果;

2. 图1是列表布局,图2是网格布局;

3. 通过右上角按钮点击切换列表布局和网格布局,按钮随着切换;

4. 实现下拉刷新展示第一页数据、上拉加载更多实现分页功能。

三、接口:

http://120.27.23.105/product/searchProducts

keywords=笔记本&page=1

参数说明:

keywords 关键字字段 String类型 必传

page  页码数  String类型  必传

公共参数:source 来源字段 String类型 (通过自定义拦截器封装)

MainActivity.java

package com.bawei.com.wangruixin1509c20171113;import android.content.Intent;import android.os.Bundle;import android.os.Handler;import android.support.v7.app.AppCompatActivity;import android.support.v7.widget.GridLayoutManager;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.view.MotionEvent;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.ImageView;import com.bawei.com.wangruixin1509c20171113.adapter.NewsListAdapter;import com.bawei.com.wangruixin1509c20171113.bean.JavaBean;import com.bawei.com.wangruixin1509c20171113.httputils.INewsView;import com.bawei.com.wangruixin1509c20171113.presenter.NewsPresenter;import com.jwenfeng.library.pulltorefresh.BaseRefreshListener;import com.jwenfeng.library.pulltorefresh.PullToRefreshLayout;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity implements INewsView{    private RecyclerView re_view;    private List<JavaBean.DataBean> list;    private NewsListAdapter adapter;    private Button btn_sousuo;    private EditText et_sousuo;    private NewsPresenter presenter;    private ImageView right;    private boolean flag = true;    private PullToRefreshLayout mpull;    private int page = 1;    private String show;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        re_view = (RecyclerView) findViewById(R.id.re_view);        btn_sousuo = (Button) findViewById(R.id.btn_sousuo);        et_sousuo = (EditText) findViewById(R.id.et_sousuo);        right = (ImageView) findViewById(R.id.right);        mpull = (PullToRefreshLayout) findViewById(R.id.mpull);        list = new ArrayList<>();        adapter = new NewsListAdapter(this, list,1);        LinearLayoutManager manager = new LinearLayoutManager(this);        re_view.setLayoutManager(manager);        re_view.setAdapter(adapter);        presenter = new NewsPresenter();        presenter.attachView(this);        btn_sousuo.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                show = et_sousuo.getText().toString().trim();                presenter.getNews(show,page);            }        });        right.setOnTouchListener(new View.OnTouchListener() {            @Override            public boolean onTouch(View view, MotionEvent motionEvent) {                if (flag){                    adapter.notifyDataSetChanged();                        adapter = new NewsListAdapter(MainActivity.this, list,2);                        right.setImageDrawable(getResources().getDrawable(R.mipmap.lv_icon));                        GridLayoutManager manager = new GridLayoutManager(MainActivity.this, 2);                        re_view.setLayoutManager(manager);                        re_view.setAdapter(adapter);                        flag = false;                }else {                    adapter.notifyDataSetChanged();                    adapter = new NewsListAdapter(MainActivity.this, list,1);                    right.setImageDrawable(getResources().getDrawable(R.mipmap.grid_icon));                    LinearLayoutManager manager = new LinearLayoutManager(MainActivity.this);                    re_view.setLayoutManager(manager);                    re_view.setAdapter(adapter);                    flag = true;                }                return false;            }        });        mpull.setLayoutMode(MODE_APPEND);//设置模板        mpull.setRefreshListener(new BaseRefreshListener() {            @Override            public void refresh() {                new Handler().postDelayed(new Runnable() {                    @Override                    public void run() {                        page=1;                        presenter.getNews(show,page);                        mpull.finishRefresh();                    }                }, 3000);            }            @Override            public void loadMore() {                new Handler().postDelayed(new Runnable() {                                              @Override                                              public void run() {                                                  page++;                                                  presenter.getNews(show,page);                                                  mpull.finishLoadMore();                                              }                                          }, 3000                );            }        });    }    @Override    public void success(String tag, List<JavaBean.DataBean> news) {        list.clear();        list.addAll(news);        adapter.notifyDataSetChanged();        adapter.setOnItemClickListener(new NewsListAdapter.OnItemClickListener() {            @Override            public void onClick(int position) {                Intent intent = new Intent(MainActivity.this, Main2Activity.class);                String url = list.get(position).getDetailUrl();                intent.putExtra("url",url);                startActivity(intent);            }            @Override            public void onLongClick(int position) {            }        });    }    @Override    public void failed(String tag, Exception e) {    }}
HttpUtils

package com.bawei.com.wangruixin1509c20171113.httputils;import android.os.Handler;import android.text.TextUtils;import com.bawei.com.wangruixin1509c20171113.callback.CallBack;import com.bawei.com.wangruixin1509c20171113.utils.GsonUtils;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 Wangrx on 2017/11/13. */public class HttpUtils {    private static Handler handler = new Handler();    private static volatile HttpUtils instance;    private HttpUtils(){    }    public static HttpUtils getInstance(){        if (null==instance){            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 cls, final String tag){        if (TextUtils.isEmpty(url)){            return;        }        StringBuffer sb = new StringBuffer();        sb.append(url);        if (url.contains("?")){            if (url.indexOf("?")==url.length()-1){            }else {                sb.append("&");            }        }else {            sb.append("?");        }        for (Map.Entry<String,String> entry:map.entrySet()){            sb.append(entry.getKey())                    .append("=")                    .append(entry.getValue())                    .append("&");        }        if (sb.indexOf("&")!=-1){            sb.deleteCharAt(sb.lastIndexOf("&"));        }        OkHttpClient client = new OkHttpClient                .Builder()                .addInterceptor(new LoggingInterceptor())                .build();        Request request = new Request.Builder()                .get()                .url(sb.toString())                .build();        Call call = client.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(tag,e);                    }                });            }            @Override            public void onResponse(Call call, Response response) throws IOException {                final String result = response.body().string();                //请求成功后做解析,通过自己的回调接口将数据返回去                handler.post(new Runnable() {                    @Override                    public void run() {                        Object o;                        if (TextUtils.isEmpty(result)){                            o = null;                        }else {                            o = GsonUtils.getInstance().fromJson(result, cls);                        }                        callBack.onSuccess(tag,o);                    }                });            }        });    }}
CallBack

package com.bawei.com.wangruixin1509c20171113.callback;/** * Created by Wangrx on 2017/11/13. */public interface CallBack {    void onSuccess(String tag,Object o);    void onFailed(String tag,Exception e);}
INewsView

package com.bawei.com.wangruixin1509c20171113.httputils;import com.bawei.com.wangruixin1509c20171113.bean.JavaBean;import java.util.List;/** * Created by Wangrx on 2017/11/13. */public interface INewsView {    void success(String tag, List<JavaBean.DataBean> list);    void failed(String tag,Exception e);}
LoggingInterceptor拦截器

package com.bawei.com.wangruixin1509c20171113.httputils;import java.io.IOException;import okhttp3.HttpUrl;import okhttp3.Interceptor;import okhttp3.Request;import okhttp3.Response;/** * Created by 笔片 on 2017/10/16. * 网络拦截器 */public class LoggingInterceptor 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);    }}
GsonUtils

package com.bawei.com.wangruixin1509c20171113.utils;import com.google.gson.Gson;/** * Created by Wangrx on 2017/11/13. */public class GsonUtils {    private static Gson instance;        private GsonUtils(){        }        public static Gson getInstance(){            if (instance==null){                instance = new Gson();            }            return instance;        }}
NewsPresenter

package com.bawei.com.wangruixin1509c20171113.presenter;import com.bawei.com.wangruixin1509c20171113.bean.JavaBean;import com.bawei.com.wangruixin1509c20171113.callback.CallBack;import com.bawei.com.wangruixin1509c20171113.httputils.HttpUtils;import com.bawei.com.wangruixin1509c20171113.httputils.INewsView;import java.util.HashMap;import java.util.List;import java.util.Map;/** * Created by Wangrx on 2017/11/13. */public class NewsPresenter {    private INewsView inv;    public void attachView(INewsView inv){        this.inv = inv;    }    public void getNews(String show,int page){        Map<String, String> map = new HashMap<>();        map.put("keywords",show);        map.put("page",page+"");        HttpUtils.getInstance().get("http://120.27.23.105/product/searchProducts", map, new CallBack() {            @Override            public void onSuccess(String tag, Object o) {                JavaBean bean = (JavaBean) o;                if (bean != null){                    List<JavaBean.DataBean> data = bean.getData();                    inv.success(tag,data);                }            }            @Override            public void onFailed(String tag, Exception e) {                inv.failed(tag,e);            }        }, JavaBean.class,"news");    }    public void detachView(){        if (inv!=null){            inv = null;        }    }}
NewsListAdapter

package com.bawei.com.wangruixin1509c20171113.adapter;import android.content.Context;import android.graphics.Paint;import android.support.v7.widget.RecyclerView;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.TextView;import com.bawei.com.wangruixin1509c20171113.R;import com.bawei.com.wangruixin1509c20171113.bean.JavaBean;import com.bumptech.glide.Glide;import java.util.List;/** * Created by Wangrx on 2017/11/13. */public class NewsListAdapter extends RecyclerView.Adapter<NewsListAdapter.ViewHolder> {    private Context context;    private List<JavaBean.DataBean> list;    private int count;    public NewsListAdapter(Context context, List<JavaBean.DataBean> list,int count) {        this.context = context;        this.list = list;        this.count = count;    }    private OnItemClickListener mOnItemClickListener;    public interface OnItemClickListener{        void onClick( int position);        void onLongClick( int position);    }    public void setOnItemClickListener(OnItemClickListener onItemClickListener ){        this. mOnItemClickListener=onItemClickListener;    }    @Override    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        if (count==1){            View v = View.inflate(context, R.layout.item, null);            ViewHolder holder = new ViewHolder(v);            return holder;        }else if (count==2){            View v = View.inflate(context, R.layout.item1, null);            ViewHolder holder = new ViewHolder(v);            return holder;        }        return null;    }    @Override    public void onBindViewHolder(ViewHolder holder, final int position) {        String[] split = list.get(position).getImages().split("[|]");        Glide.with(context).load(split[0]).into(holder.item_img);        holder.item_bargainPrice.setText("原价:¥"+list.get(position).getBargainPrice());        holder.item_bargainPrice.getPaint().setFlags(Paint. STRIKE_THRU_TEXT_FLAG); //下划线        holder.item_bargainPrice.getPaint().setAntiAlias(true);//抗锯齿        holder.item_price.setText("折扣价:¥"+list.get(position).getPrice());        holder.item_title.setText(list.get(position).getTitle());        if( mOnItemClickListener!= null){            holder.itemView.setOnClickListener( new View.OnClickListener() {                @Override                public void onClick(View v) {                    mOnItemClickListener.onClick(position);                }            });            holder. itemView.setOnLongClickListener( new View.OnLongClickListener() {                @Override                public boolean onLongClick(View v) {                    mOnItemClickListener.onLongClick(position);                    return false;                }            });        }    }    @Override    public int getItemCount() {        if (list==null){            return 0;        }        return list.size();    }    public class ViewHolder extends RecyclerView.ViewHolder {        private final ImageView item_img;        private final TextView item_price;        private final TextView item_bargainPrice;        private final TextView item_title;        public ViewHolder(View itemView) {            super(itemView);            item_img = itemView.findViewById(R.id.item_img);            item_title = itemView.findViewById(R.id.item_title);            item_price = itemView.findViewById(R.id.item_price);            item_bargainPrice = itemView.findViewById(R.id.item_bargainPrice);        }    }}
Main2Activity.java

package com.bawei.com.wangruixin1509c20171113;import android.content.Intent;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.webkit.WebSettings;import android.webkit.WebView;import android.webkit.WebViewClient;public class Main2Activity extends AppCompatActivity {    private WebView web;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main2);        Intent intent = getIntent();        String url = intent.getStringExtra("url");        web = (WebView) findViewById(R.id.web);        web.loadUrl(url);        web.setWebViewClient(new WebViewClient());        WebSettings settings = web.getSettings();        settings.setJavaScriptCanOpenWindowsAutomatically(true);        settings.setJavaScriptEnabled(true);    }}
activity_main.xml

<?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.bawei.com.wangruixin1509c20171113.MainActivity">    <TextView        android:id="@+id/tv_show"        android:layout_width="match_parent"        android:layout_height="40dp"        android:text="搜索商品"        android:textSize="25sp"        android:gravity="center"        />    <ImageView        android:id="@+id/right"        android:layout_width="40dp"        android:layout_height="40dp"        android:src="@mipmap/grid_icon"        android:layout_alignParentRight="true"        />    <RelativeLayout        android:id="@+id/rel"        android:layout_width="match_parent"        android:layout_height="50dp"        android:layout_below="@+id/tv_show"        android:layout_alignParentStart="true">        <EditText            android:id="@+id/et_sousuo"            android:layout_width="300dp"            android:layout_height="50dp"            android:drawableLeft="@mipmap/a_4"            android:hint="请输入关键字"            />        <Button            android:id="@+id/btn_sousuo"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_toRightOf="@+id/et_sousuo"            android:text="搜索"            />    RelativeLayout>    <com.jwenfeng.library.pulltorefresh.PullToRefreshLayout        android:layout_width="match_parent"        android:id="@+id/mpull"        android:layout_below="@+id/rel"        android:layout_height="match_parent">        <android.support.v7.widget.RecyclerView            android:id="@+id/re_view"            android:layout_width="match_parent"            android:layout_height="wrap_content"            >android.support.v7.widget.RecyclerView>    com.jwenfeng.library.pulltorefresh.PullToRefreshLayout>RelativeLayout>
activity_main2.xml

<?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.bawei.com.wangruixin1509c20171113.Main2Activity">    <WebView        android:id="@+id/web"        android:layout_width="match_parent"        android:layout_height="match_parent">WebView>RelativeLayout>
item.xml

<?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:id="@+id/item_img"        android:layout_width="100dp"        android:layout_height="100dp" />    <RelativeLayout        android:layout_width="match_parent"        android:layout_height="100dp"        android:layout_toRightOf="@+id/item_img">        <TextView            android:id="@+id/item_title"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:singleLine="true"            android:text="title"            android:textSize="16sp" />        <TextView            android:id="@+id/item_bargainPrice"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_below="@+id/item_title"            android:text="售价"            android:layout_marginTop="10dp"            android:textColor="#ccc"            android:textSize="14sp" />        <TextView            android:id="@+id/item_price"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_below="@+id/item_title"            android:layout_marginLeft="10dp"            android:layout_toRightOf="@+id/item_bargainPrice"            android:text="售价"            android:layout_marginTop="10dp"            android:textColor="#f00"            android:textSize="14sp"            />    RelativeLayout>LinearLayout>
权限:

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

compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'compile 'com.squareup.okhttp3:okhttp:3.9.0'compile 'com.google.code.gson:gson:2.8.2'compile 'com.github.bumptech.glide:glide:3.7.0'compile 'com.jwenfeng.pulltorefresh:library:1.0.3'

更多相关文章

  1. Android 获取剪切板第一条数据
  2. Android在程序中动态生成控件,动态布局
  3. Android 手机端与服务端POST数据交互类
  4. Android RectF类的构造函数参数说明
  5. java后台接收android客户端通过http方式发送的数据
  6. android 相对布局例子代码
  7. Android实现动态切换横竖屏,保存横竖屏数据(用Preference存储)

随机推荐

  1. android内核编译方法
  2. [置顶] Android面试题【高级工程师版】
  3. android下不规则多边形填充位图
  4. Android : 隐藏软键盘
  5. Android SplashActivity启动时黑屏的问题
  6. Android包(android.view.animation)的简介
  7. Android: Android Light Sensor HOWTO
  8. android 获取位置
  9. Android Studio之编译t提示Invoke-custom
  10. Android添加USB add-on硬件访问服务