1. 主页面显示一个RecyclerView 列表展示(10分);2. 访问网络接口获取数据(10分);3. 通过Handler将数据发送到主线程(10分);4. 将获取到的数据解析成实体类型(10分);5. 设置适配器,将数据列表传入适配器(10分);6. 在构造方法中初始化Fresco并做配置完成(10分);7. Recyclerview 多条目展示(10分);8. 配置图片的显示方式为奇数行用圆角实现(10分);9. 在偶数行用圆形实现(10分);10. 点击条目跳到第二页面实现点击跳转(10分);11.携带数据(10分);12.初始化EventBus(10分);13.注册粘性事件(10分);14.传值,注销 (10分);15. 使用ButterKnife初始化控件 10分
https://api.tianapi.com/wxnew/?key=8d6e3228d25298f13af4fc40ce6c9679&num=10
1依赖:
compile 'com.google.code.gson:gson:2.2.4' compile 'com.squareup.okhttp3:okhttp:3.10.0' compile 'com.facebook.fresco:fresco:0.12.0' compile 'org.greenrobot:eventbus:3.0.0' compile 'com.github.bumptech.glide:glide:3.7.0' compile 'com.android.support:recyclerview-v7:26.1.0'
2 权限:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
3
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.example.dell.a1511r0411.view.MainActivity"> <android.support.v4.widget.SwipeRefreshLayout android:id="@+id/my_srl" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/my_rcv" android:layout_width="wrap_content" android:layout_height="wrap_content"> android.support.v7.widget.RecyclerView> android.support.v4.widget.SwipeRefreshLayout> LinearLayout>
4.M层网络获取的数据Bean
package com.example.dell.a1511r0411.model; import java.util.List; public class DataBean { private int code; private String msg; private Listnewslist; 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 getNewslist() { return newslist; } public void setNewslist(List newslist) { this.newslist = newslist; } public static class NewslistBean { 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; } } }
5.M层的接口
package com.example.dell.a1511r0411.model; import com.example.dell.a1511r0411.presenter.DataPresenter; public interface DataModel { //请求数据的方法 void getData(String url, DataPresenter presenter); }
6.M层实现接口的类
package com.example.dell.a1511r0411.model; import com.example.dell.a1511r0411.presenter.DataPresenter; import com.example.dell.a1511r0411.util.OkhtttpUtils; import com.google.gson.Gson; import java.io.IOException; import java.util.List; import okhttp3.Call; import okhttp3.Callback; import okhttp3.Response; public class MyDataModel implements DataModel{ @Override public void getData(String url, final DataPresenter presenter) { OkhtttpUtils.doGet(url, new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { String json = response.body().string(); Gson gson = new Gson(); DataBean dataBean = gson.fromJson(json, DataBean.class); Listlist = dataBean.getNewslist(); presenter.Success(list); } }); } }
7.P层的接口
package com.example.dell.a1511r0411.presenter; import com.example.dell.a1511r0411.model.DataBean; import java.util.List; public interface DataPresenter { //成功与失败的方法 void Success(List8.P层实现接口的类list); void Error(); }
package com.example.dell.a1511r0411.presenter; import com.example.dell.a1511r0411.model.DataBean; import com.example.dell.a1511r0411.model.MyDataModel; import com.example.dell.a1511r0411.view.DataView; import java.util.List; public class MyDataPersenter implements DataPresenter{ //创建构造器 DataView dataView; private final MyDataModel model; public MyDataPersenter(DataView dataView) { this.dataView=dataView; model = new MyDataModel(); } //成功的方法 @Override public void Success(Listlist) { //调用V层接收数据的方法 dataView.toBackHome(list); } //失败的方法 @Override public void Error() {} //接收url public void netWork(String url){ //调用M层请求数据的方法 model.getData(url,this); } }
9.V层的接口
package com.example.dell.a1511r0411.view; import com.example.dell.a1511r0411.model.DataBean; import java.util.List; public interface DataView { //接收数据的方法 void toBackHome(Listlist); }
10.V层实现接口的类
package com.example.dell.a1511r0411.view; import android.content.Intent; import android.os.Handler; import android.os.Message; 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 android.widget.Toast; import com.example.dell.a1511r0411.R; import com.example.dell.a1511r0411.adapter.MyAdapter; import com.example.dell.a1511r0411.model.DataBean; import com.example.dell.a1511r0411.presenter.MyDataPersenter; import com.facebook.drawee.backends.pipeline.Fresco; import com.facebook.imagepipeline.producers.SwallowResultProducer; import org.greenrobot.eventbus.EventBus; import java.util.List; public class MainActivity extends AppCompatActivity implements DataView,MyAdapter.OnClickListener { private RecyclerView my_rcv; String url = "https://api.tianapi.com/wxnew/?key=fe7aac932e1e94f10a4f8d0f2d5fe924&num=10"; private MyAdapter myAdapter; private Listlist; Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); list = (List ) msg.obj; myAdapter = new MyAdapter(MainActivity.this, list); my_rcv.setAdapter(myAdapter); //调用适配器中的点击事件 myAdapter.OnClick((MyAdapter.OnClickListener) MainActivity.this); } }; private SwipeRefreshLayout my_srl; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Fresco.initialize(this); setContentView(R.layout.activity_main); //找到资源控件的ID my_rcv = findViewById(R.id.my_rcv); my_srl = findViewById(R.id.my_srl); my_srl.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { //控制使它显示刷新 my_srl.setRefreshing(true); } }); //设置管理器 my_rcv.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false)); //初始化P层,将url和本类传过去 MyDataPersenter persenter = new MyDataPersenter(this); persenter.netWork(url); } //接收数据 @Override public void toBackHome(List list) { Message msg = new Message(); msg.obj=list; handler.sendMessage(msg); my_srl.setRefreshing(false); } //设置点击事件 @Override public void OnItemClick(int position) { Evens evens = new Evens(); String title = list.get(position).getTitle(); String url = list.get(position).getPicUrl(); evens.setName(title); evens.setUrl(R.drawable.psb); evens.setUrl2(R.drawable.yy); EventBus.getDefault().postSticky(evens);//发送粘性事件 //实现跳转 Intent intent = new Intent(MainActivity.this,Main2Activity.class); startActivity(intent); } }
11.创建Evens,实现传递数据
package com.example.dell.a1511r0411.view; public class Evens { private String name; private int url; private int url2; public int getUrl2() { return url2; } public void setUrl2(int url2) { this.url2 = url2; } public int getUrl() { return url; } public void setUrl(int url) { this.url = url; } public String getName() { return name; } 12.适配器
package com.example.dell.a1511r0411.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.example.dell.a1511r0411.R; import com.example.dell.a1511r0411.model.DataBean; import com.example.dell.a1511r0411.view.MainActivity; import com.facebook.drawee.view.SimpleDraweeView; import java.util.List; /** * Created by dell on 2018/4/11. */ public class MyAdapter extends RecyclerView.Adapter{ Context context; List13.跳转的第二个页面,接收Event传来的数据list; public MyAdapter(Context context, List list) { this.context=context; this.list=list; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view; //判断条目的类型 判断引入的布局文件 int itemViewType = getItemViewType(viewType); if(itemViewType==0){ view = View.inflate(context, R.layout.rcv_item, null); }else{ view = View.inflate(context, R.layout.rcv_item2, null); } MyViewHolder myViewHolder = new MyViewHolder(view); return myViewHolder; } //获取条目的类型 然后进行判断 @Override public int getItemViewType(int position) { if(position%2==0){ return 0; }else { return 1; } } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { MyViewHolder myViewHolder = (MyViewHolder) holder; //得到条目 int itemViewType = getItemViewType(position); if(itemViewType==0){ myViewHolder.rcv_title.setText(list.get(position).getTitle()); }else{ myViewHolder.rcv_title2.setText(list.get(position).getTitle()); } //条目进行点击事件 myViewHolder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { onClickListener.OnItemClick(position); } }); } @Override public int getItemCount() { return list.size(); } class MyViewHolder extends RecyclerView.ViewHolder{ private final TextView rcv_title,rcv_title2; private final SimpleDraweeView rcv_img; private final SimpleDraweeView rcv_img2; public MyViewHolder(View view) { super(view); //找到两个子布局文件的控件id rcv_img = view.findViewById(R.id.rcv_img); rcv_title = view.findViewById(R.id.rcv_title); rcv_img2 = view.findViewById(R.id.rcv_img2); rcv_title2 = view.findViewById(R.id.rcv_title2); } } //创建暴露点击事件的类 OnClickListener onClickListener; public void OnClick(OnClickListener onClickListener){ this.onClickListener=onClickListener; } //创建点击事件接口 public interface OnClickListener{ void OnItemClick(int position); } }
package com.example.dell.a1511r0411.view; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.ImageView; import android.widget.TextView; import com.bumptech.glide.Glide; import com.example.dell.a1511r0411.R; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; public class Main2Activity extends AppCompatActivity { private TextView my_title; private ImageView my_img; int index=0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); my_title = findViewById(R.id.my_title); my_img = findViewById(R.id.my_img); //注册 EventBus.getDefault().register(this); } @Subscribe(threadMode = ThreadMode.MAIN,sticky = true) //在ui线程执行 public void onEvens(Evens evens) { //获取Evens传来的数据,进行赋值 my_title.setText(evens.getName()); if(index%2==0){ Glide.with(this).load(evens.getUrl()).into(my_img); }else{ Glide.with(this).load(evens.getUrl2()).into(my_img); } } @Override protected void onDestroy() { super.onDestroy(); //反注册,进行销毁 EventBus.getDefault().unregister(this); } }14.条目子布局文件
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" xmlns:fresco="http://schemas.android.com/apk/res-auto" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="10px"> <com.facebook.drawee.view.SimpleDraweeView android:id="@+id/rcv_img" android:layout_width="150px" android:layout_height="150px" fresco:placeholderImage="@drawable/psb" fresco:roundedCornerRadius="30dp" fresco:roundTopLeft="true" fresco:roundTopRight="true" fresco:roundBottomLeft="true" fresco:roundBottomRight="true"> com.facebook.drawee.view.SimpleDraweeView> <TextView android:id="@+id/rcv_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="只要你躺足70天,NASA就给你11万块钱!" android:layout_gravity="center_vertical" android:layout_marginLeft="10px"/> LinearLayout> LinearLayout>
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" xmlns:fresco="http://schemas.android.com/apk/res-auto" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="10px"> <com.facebook.drawee.view.SimpleDraweeView android:id="@+id/rcv_img2" android:layout_width="150px" android:layout_height="150px" fresco:placeholderImage="@drawable/yy"
fresco:actualImageScaleType="centerCrop" fresco:placeholderImageScaleType="centerCrop" fresco:roundAsCircle="true"
> com.facebook.drawee.view.SimpleDraweeView>
<TextView android:id="@+id/rcv_title2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="只要你躺足70天,NASA就给你11万块钱!"
android:layout_marginLeft="10px"
android:layout_gravity="center_vertical" />
LinearLayout>LinearLayout>15.接收数据的页面
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.example.dell.a1511r0411.view.Main2Activity"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="10px"> <ImageView android:id="@+id/my_img" android:layout_width="150px" android:layout_height="150px" android:src="@mipmap/ic_launcher"/> <TextView android:id="@+id/my_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="只要你躺足70天,NASA就给你11万块钱!" android:layout_gravity="center_vertical" android:layout_marginLeft="10px"/> LinearLayout> LinearLayout>16.OKHttP的封装
package com.example.dell.a1511r0411.util; import android.os.Environment; import java.io.File; import java.util.Map; import java.util.concurrent.TimeUnit; import okhttp3.Cache; import okhttp3.Callback; import okhttp3.FormBody; import okhttp3.MediaType; import okhttp3.MultipartBody; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; public class OkhtttpUtils { //单例模式,把构造方法进行私有化 private OkhtttpUtils(){}; static OkHttpClient client; public static OkHttpClient getInstance(){ if (client==null) { //更加安全 synchronized (OkhtttpUtils.class) { //缓存的地方 mnt/sdcard File file = new File(Environment.getExternalStorageDirectory(), "cache11"); client = new OkHttpClient().newBuilder() .readTimeout(3000, TimeUnit.SECONDS) //设置读取超时时间 .connectTimeout(3000, TimeUnit.SECONDS) //设置连接的超时时间 .cache(new Cache(file, 10 * 1024)) .build(); } } return client; } /** * get请求 * Callback 是一个接口 */ public static void doGet(String url, Callback callback){ //1:拿到okhttpclient 对像 OkHttpClient client = getInstance(); //2:进行请求的操作 Request request = new Request.Builder() .url(url) .build(); client.newCall(request).enqueue(callback); } //post请求 /** * * @param url 请求的地址 * @param parms 请求的参数 * @param callback callback */ public static void doPost(String url, Mapparms,Callback callback){ //得到客户端的对像 OkHttpClient client = getInstance(); //不是FormBody,而是一个Builder FormBody.Builder body = new FormBody.Builder(); //key value for (String key:parms.keySet()){ //value的值 body.add(key,parms.get(key)); } Request request = new Request.Builder() .url(url) .post(body.build()) .build(); client.newCall(request).enqueue(callback); } //用来上传图片的 //url , 图片 ,参数 Callback public static void upImage(String url,File file,String filenName,Map params,Callback callback){ OkHttpClient client = getInstance(); //requestBody的实现类 Formbody MultipartBody.Builder builder = new MultipartBody.Builder(); if (params!=null){ for (String key :params.keySet()){ builder.addFormDataPart(key,params.get(key)); } } //设置类型 builder.setType(MultipartBody.FORM); builder.addFormDataPart("file",filenName,RequestBody.create(MediaType.parse("application/octet-stream"),file)); // builder.setType(MultipartBody.FORM); // builder.addFormDataPart("file",filenName,RequestBody.create(MediaType.parse("application/octet-stream"),file)); //builder.addFormDataPart("file","aa.png",builder.build()); Request request = new Request.Builder() .url(url) .post(builder.build()) .build(); client.newCall(request).enqueue(callback); } }