MVP框架:
MVP架构是当前比较成熟的Android架构,还有其他架构比如最初始的MVC和MVVM。
MVC相对于较为落后,MVVM使用DataBind,普及性不如MVP。所以最终决定自己设计的框架
是基于MVP思想进行总结的框架。
选择MVP框架的原因之一也是google官方的示例中MVP sample已经是完成,证明google官方对于MVP的承认度。
MainActivity.java
package com.bawei.com.myapplication; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.widget.Toast; import com.bawei.com.myapplication.adapter.NewsListAdapter; import com.bawei.com.myapplication.bean.Bean; import com.bawei.com.myapplication.callback.INewsView; import com.bawei.com.myapplication.presaenter.NewsPresenter; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity implements INewsView{ private RecyclerView re_view; private List<Bean.DataBean> list; private NewsPresenter presenter; private NewsListAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); re_view = (RecyclerView) findViewById(R.id.re_view); list = new ArrayList<>(); adapter = new NewsListAdapter(this, list); LinearLayoutManager manager = new LinearLayoutManager(this); re_view.setLayoutManager(manager); re_view.setAdapter(adapter); presenter = new NewsPresenter(); presenter.attachView(this); presenter.getNews(); adapter.setOnItemClickListener(new NewsListAdapter.OnItemClickListener() { @Override public void onClick(int position) { Toast.makeText(MainActivity.this,"您点击了"+position+"行",Toast.LENGTH_SHORT).show(); } @Override public void onLongClick(int position) { Toast.makeText(MainActivity.this,"您长按点击了"+position+"行",Toast.LENGTH_SHORT).show(); } }); } @Override public void success(String tag, List<Bean.DataBean> news) { if (null != news) { list.addAll(news); adapter.notifyDataSetChanged(); } } @Override public void failed(String tag, Exception e) { Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show(); } @Override protected void onDestroy() { super.onDestroy(); if (presenter != null) { presenter.detachView(); } } }HttpUtils
package com.bawei.com.myapplication.http; import android.os.Handler; import android.text.TextUtils; import android.util.Log; import com.bawei.com.myapplication.callback.CallBack; import com.bawei.com.myapplication.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; public class HttpUtils { private static final String TAG = "HttpUtils"; private static volatile HttpUtils instance; private static Handler handler = new Handler(); private HttpUtils() { } public static HttpUtils getInstance() { if (null == instance) { synchronized (HttpUtils.class) { if (instance == null) { instance = new HttpUtils(); } } } return instance; } /** * Get请求 * * @param url * @param map * @param callBack * @param cls * @param tag */ public void get(String url, Map<String, String> map, final CallBack callBack, final Class cls, final String tag) { // http://www.baoidu.com/login?mobile=11111&password=11111&age=1&name=zw // 1.http://www.baoidu.com/login --------? key=value&key=value // 2.http://www.baoidu.com/login? --------- key=value&key=value // 3.http://www.baoidu.com/login?mobile=11111 -----&key=value&key=value if (TextUtils.isEmpty(url)) { return; } StringBuffer sb = new StringBuffer(); sb.append(url); // 如果包含?说明是2.3类型 if (url.contains("?")) { // 如果包含?并且?是最后一位,对应是2类型 if (url.indexOf("?") == url.length() - 1) { } else { // 如果包含?并且?不是最后一位,对应是3类型 sb.append("&"); } } else { // 不包含?,对应的1类型 sb.append("?"); } // 遍历map集合进行拼接,拼接的形式是 key=value& 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("&")); } Log.i(TAG, "get url: " + sb); OkHttpClient client = new OkHttpClient(); final 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); } }); } }); }
/** * 封装的post请求 * * @param url * @param map * @param callback * @param cls */ public void post(String url, Map<String, String> map, final Callback callback, final Class cls) { OkHttpClient client = new OkHttpClient(); FormBody.Builder builder = new FormBody.Builder(); for (Map.Entry<String, String> entry : map.entrySet()) { builder.add(entry.getKey(), entry.getValue()); } FormBody body = builder.build(); final Request request = new Request.Builder() .url(url) .post(body) .build(); Call call = client.newCall(request); call.enqueue(new okhttp3.Callback() { @Override public void onFailure(Call call, final IOException e) { Log.e(TAG, "onFailure: " + e.getCause().getStackTrace() + e.getMessage()); 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(TAG, "onResponse: " + result); final Object o = GsonUtils.getInstance().fromJson(result, cls); handler.post(new Runnable() { @Override public void run() { callback.onSuccess(o); } }); } }); }
}CallBack
package com.bawei.com.myapplication.callback; /** * Created by Wangrx on 2017/11/10. */ public interface CallBack { void onSuccess(String tag,Object O); void onFailed(String tag, Exception e); }INewsView
package com.bawei.com.myapplication.callback; import com.bawei.com.myapplication.bean.Bean; import java.util.List; public interface INewsView { void success(String tag, List<Bean.DataBean> news); void failed(String tag, Exception e); }NewsListAdapter
package com.bawei.com.myapplication.adapter; 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.bawei.com.myapplication.R; import com.bawei.com.myapplication.bean.Bean; import com.bumptech.glide.Glide; import java.util.List; public class NewsListAdapter extends RecyclerView.Adapter<NewsListAdapter.ViewHolder> { private Context context; private List<Bean.DataBean> list; private OnItemClickListener mOnItemClickListener; public interface OnItemClickListener{ void onClick( int position); void onLongClick( int position); } public void setOnItemClickListener(OnItemClickListener onItemClickListener ){ this. mOnItemClickListener=onItemClickListener; } public NewsListAdapter(Context context, List<Bean.DataBean> list) { this.context = context; this.list = list; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = View.inflate(context, R.layout.item_news, null); ViewHolder holder = new ViewHolder(v); return holder; } @Override public void onBindViewHolder(final ViewHolder holder, final int position) { Glide.with(context).load(list.get(position).getIcon()).into(holder.imgLogo); holder.txtTitle.setText(list.get(position).getName()); holder.txtTime.setText(list.get(position).getCreatetime()); 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(); } class ViewHolder extends RecyclerView.ViewHolder { private ImageView imgLogo; private TextView txtTitle; private TextView txtTime; public ViewHolder(View itemView) { super(itemView); imgLogo = (ImageView) itemView.findViewById(R.id.img_logo); txtTitle = (TextView) itemView.findViewById(R.id.txt_title); txtTime = (TextView) itemView.findViewById(R.id.txt_time); } } }NewsPresenter
package com.bawei.com.myapplication.presaenter; import com.bawei.com.myapplication.bean.Bean; import com.bawei.com.myapplication.callback.CallBack; import com.bawei.com.myapplication.callback.INewsView; import com.bawei.com.myapplication.http.HttpUtils; import java.util.HashMap; import java.util.List; import java.util.Map; public class NewsPresenter { private INewsView inv; public void attachView(INewsView inv) { this.inv = inv; } public void getNews() { //type=top&key=dbedecbcd1899c9785b95cc2d17131c5 Map<String, String> map = new HashMap<>(); // map.put("cid", "1"); // map.put("key", "dbedecbcd1899c9785b95cc2d17131c5"); HttpUtils.getInstance().get("http://120.27.23.105/product/getCatagory", map, new CallBack() { @Override public void onSuccess(String tag, Object o) { Bean bean = (Bean) o; if (bean != null) { List<Bean.DataBean> data = bean.getData(); inv.success(tag, data); } } @Override public void onFailed(String tag, Exception e) { inv.failed(tag, e); } }, Bean.class, "news"); } public void detachView() { if (inv != null) { inv = null; } } }布局文件:
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.myapplication.MainActivity"> <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> </RelativeLayout>item_news.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="wrap_content" android:orientation="horizontal"> <ImageView android:id="@+id/img_logo" android:layout_width="70dp" android:layout_height="70dp" android:layout_margin="10dp" android:scaleType="centerCrop" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/txt_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:ellipsize="end" android:singleLine="true" android:textColor="#232121" android:textSize="15sp" android:textStyle="bold" /> <TextView android:id="@+id/txt_time" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="#635353" android:textSize="13sp" /> </LinearLayout> </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.squareup.okhttp3:okhttp:3.9.0' 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'