效果图:
效果图描述:
首页RecycierView 点击条目,使用 Eventbus传值给第二个activity,展示数据
Retrofit的get方式展示recyclerview,fresco加载图片,添加到数据库greendao,
点击条目发送Eventbus黏性事件给SecondActivity,展示字段数据。
涉及到了greendao,在工程的gradle里面加入两行(蓝色的)
buildscript { repositories { google() jcenter() mavenCentral() // add repository } dependencies { classpath 'com.android.tools.build:gradle:3.0.1' classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } }
在项目的gradle里面做更改,并且导入依赖(标红的)
apply plugin: 'com.android.application' apply plugin: 'org.greenrobot.greendao' // apply plugin android { compileSdkVersion 26 defaultConfig { applicationId "com.example.exercise_05_retrofit_greendao_eventbus_fresco" minSdkVersion 19 targetSdkVersion 26 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } greendao { targetGenDir 'src/main/java'
daoPackage 'com.dhw.everyweek.adapter.dao' // 自己的包名.dao
schemaVersion 1 } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:26.1.0' implementation 'com.android.support.constraint:constraint-layout:1.0.2' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.1' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' //butterknife两个依赖 compile 'com.jakewharton:butterknife:8.8.1' annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1' //retrofit的两个依赖 compile 'com.squareup.retrofit2:retrofit:2.3.0' compile 'com.squareup.retrofit2:converter-gson:2.3.0' //eventbus的依赖 compile 'org.greenrobot:eventbus:3.1.1' //fresco的依赖 compile 'com.facebook.fresco:fresco:1.5.0' //greendao两个依赖 compile 'org.greenrobot:greendao:3.2.2' compile 'net.zetetic:android-database-sqlcipher:3.5.7@aar' //recyclerview依赖 compile 'com.android.support:recyclerview-v7:25.3.1' }
新建IApplication 继承Application ,并在清单文件中配置
import android.app.Application; import com.facebook.drawee.backends.pipeline.Fresco; import org.greenrobot.greendao.database.Database; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; /** * 用于全局配置初始化异步加载类 */ public class MyApplication extends Application { //设置公共变量 public static DaoSession session; public static GetDataInterface request; @Override public void onCreate() { super.onCreate(); //1. 用于全局配置初始化Fresco 图片加载 Fresco.initialize(this); //2. 用于全局配置初始化Retrofit 网络请求 //构建Retrofit类,初始化参数 Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://v.juhe.cn") .addConverterFactory(GsonConverterFactory.create()) .build(); //创建网络请求接口实例 request = retrofit.create(GetDataInterface.class); //3. 用于全局配置初始化GreenDao数据库 DaoMaster.DevOpenHelper database = new DaoMaster.DevOpenHelper(this, "database"); Database db = database.getWritableDb(); //获取能读能写的数据库 session = new DaoMaster(db).newSession(); } }
- <application
- android:name=".MyApplication"
清单文件中加入权限
请求网络获得的数据生成实体类
DataBean
(标红的必须写)
//数据库不能操作内部类,需把接口返回的实体数据抽取为1个单独类(自己实现)
@Entity//必须写的 public class DataBean { @Id(autoincrement =true)//自增private Long tid;//自己加的字段
点击锤子按钮会自动生成dao包中的三个类
新建接口GetDataInterface ,这里提供了两种方法,get传参 post传参
/** * 创建网络请求接口实例类 * 分 2 种 请求方式:@GET @POST * * @Path: 所有在网址中的参数(URL的问号前面) * @Query: URL问号后面的参数 * @QueryMap: 相当于多个@Query * @Field: 用于POST请求,提交单个数据 * @Body: 相当于多个@Field,以对象的形式提交 * @FormUrlEncoded: 用于修饰Field注解和FieldMap注解; * 使用该注解,表示请求正文将使用表单网址编码。 * 字段应该声明为参数,并用@Field注释或FieldMap注释。 * 使用FormUrlEncoded注解的请求将具”application / x-www-form-urlencoded” MIME类型。 * 字段名称和值将先进行UTF-8进行编码,再根据RFC-3986进行URI编码. */ public interface GetDataInterface { /** * get请求 * @param key * @return */ @GET("/toutiao/index") Call<NewsBean> get(@Query("key") String key); /** * post请求 * @param key * @return */ @FormUrlEncoded @POST("/toutiao/index") Call<NewsBean> post(@Field("key") String key); }
使用MVP三层编写数据
1.model层
/** * model接口实现类 */ public class MyModel { /** * get请求 * @param callBack */ public void getData(final ModelCallBack callBack){ //设置接口请求的key值 Call<NewsBean> call = MyApplication.request.get("c4479ad58f41e7f78a8fa073d0b1f1b5"); //发起异步请求 call.enqueue(new Callback<NewsBean>() { @Override public void onResponse(Call<NewsBean> call, Response<NewsBean> response) { //获取响应的数据,保存在数据库中 NewsBean bean = response.body(); MyApplication.session.getDataBeanDao().insertInTx(bean.getResult().getData()); //请求成功时返回数据 callBack.onSuccess(bean); } @Override public void onFailure(Call<NewsBean> call, Throwable t) { //请求失败时返回数据 callBack.onFailure(new Exception("")); } }); } /** * post请求 * @param callBack */ public void postData(final ModelCallBack callBack){ //设置接口请求的key值 Call<NewsBean> call = MyApplication.request.post("c4479ad58f41e7f78a8fa073d0b1f1b5"); //发起异步请求 call.enqueue(new Callback<NewsBean>() { @Override public void onResponse(Call<NewsBean> call, Response<NewsBean> response) { //获取响应的数据,保存在数据库中 NewsBean bean = response.body(); MyApplication.session.getDataBeanDao().insertInTx(bean.getResult().getData()); //请求成功时返回数据 callBack.onSuccess(bean); } @Override public void onFailure(Call<NewsBean> call, Throwable t) { //请求失败时返回数据 callBack.onFailure(new Exception("")); } }); } }
model层接口
/** * model类接口,成功和失败的方法 */ public interface ModelCallBack { public void onSuccess(NewsBean bean); public void onFailure(Exception e); }
2.view层
/** * view层接口类,请求成功与失败的方法 */ public interface MyView { public void onSuccess(NewsBean bean); public void onFailure(Exception e); }
3.presenter层
/** * Presenter层,进行view层与model数据的交互 */ public class MyPresenter { private MyView myView; private MyModel myModel; public MyPresenter(MyView myView) { this.myView = myView; this.myModel = new MyModel(); } /** * get请求数据交互 */ public void get(){ myModel.getData(new ModelCallBack() { @Override public void onSuccess(NewsBean bean) { //数据交互时,为防止内存泄露,设置view层数据为空 if (myView != null){ myView.onSuccess(bean); } } @Override public void onFailure(Exception e) { //数据交互时,为防止内存泄露,设置view层数据为空 if (myView != null){ myView.onFailure(e); } } }); } /** * post请求数据交互 */ public void post(){ myModel.postData(new ModelCallBack() { @Override public void onSuccess(NewsBean bean) { //数据交互时,为防止内存泄露,设置view层数据为空 if (myView != null){ myView.onSuccess(bean); } } @Override public void onFailure(Exception e) { //数据交互时,为防止内存泄露,设置view层数据为空 if (myView != null){ myView.onFailure(e); } } }); } }
回调到view层MainActivity
//UI操作,实现view层 public class MainActivity extends AppCompatActivity implements MyView{ @BindView(R.id.recyclerView) RecyclerView recyclerView; private MyPresenter presenter; private MyAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); //创建Presenter层实例,与view层交互 presenter = new MyPresenter(this); //get请求方式 presenter.get(); //设置布局管理器以及布局适配器 LinearLayoutManager manager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false); adapter = new MyAdapter(this); recyclerView.setLayoutManager(manager); recyclerView.setAdapter(adapter); //遍历查询数据库中的所有数据 List<DataBean> list = MyApplication.session.getDataBeanDao().loadAll(); for (DataBean listBean : list){ System.out.println("查询:"+listBean.toString()); } } @Override public void onSuccess(NewsBean bean) { //请求成功时添加数据 adapter.addData(bean); } @Override public void onFailure(Exception e) { System.out.println("数据出错:"+e); } }activity_main.xml
<?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.dhw.everyweek.MainActivity"> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent"></android.support.v7.widget.RecyclerView> </LinearLayout>
适配器MyAdapter
//RecyclerView展示数据适配器 public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> { private Context context; private List<DataBean> list; public MyAdapter(Context context) { this.context = context; } //添加数据 public void addData(NewsBean bean) { if (list == null) { list = new ArrayList<>(); } list.addAll(bean.getResult().getData()); notifyDataSetChanged(); } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { //添加布局视图 View view = View.inflate(context, R.layout.adapter, null); return new MyViewHolder(view); } @Override public void onBindViewHolder(MyViewHolder holder, final int position) { holder.draweeView.setImageURI(list.get(position).getThumbnail_pic_s()); holder.title.setText(list.get(position).getTitle()); //点击跳转传值 holder.title.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //携带实体类数据,实现点击跳转,发送黏性事件 EventBusBean busBean = new EventBusBean(list.get(position).getThumbnail_pic_s(), list.get(position).getTitle()); EventBus.getDefault().postSticky(busBean); context.startActivity(new Intent(context, SecondActivity.class)); } }); } @Override public int getItemCount() { return list == null ? 0 : list.size(); } static class MyViewHolder extends RecyclerView.ViewHolder { @BindView(R.id.draweeView) SimpleDraweeView draweeView; @BindView(R.id.title) TextView title; public MyViewHolder(View itemView) { super(itemView); ButterKnife.bind(this,itemView); } } }
adapter.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:fresco="http://schemas.android.com/apk/res-auto" android:padding="6dp" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <com.facebook.drawee.view.SimpleDraweeView android:id="@+id/draweeView" android:layout_width="100dp" android:layout_height="100dp" android:layout_marginLeft="6dp" fresco:placeholderImage="@drawable/app_default" fresco:placeholderImageScaleType="fitCenter" fresco:actualImageScaleType="focusCrop" fresco:failureImage="@drawable/load_error_image" fresco:failureImageScaleType="fitCenter" fresco:roundAsCircle="true"/> <TextView android:id="@+id/title" android:textSize="18sp" android:textStyle="bold" android:layout_marginLeft="6dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical"/> </LinearLayout>
Eventbus新建EventBusBean类传值
/** * EventBus传值的实体类 */ public class EventBusBean { public String url; public String title; public EventBusBean(String url, String title) { this.url = url; this.title = title; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } }
Myadapter适配器的条目点击事件里面,Eventbus发布一个黏性事件,点击携带数据跳转
在SecondActivity.java中接收数据并显示
//EventBus的传值通信接收页 public class SecondActivity extends AppCompatActivity { @BindView(R.id.draweeView) SimpleDraweeView draweeView; @BindView(R.id.title) TextView title; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); ButterKnife.bind(this); //初始化EventBus,注册EventBus,订阅黏性事件 EventBus.getDefault().register(this); } //主线程UI,注册粘性订阅事件,黏性事件处理函数 @Subscribe(threadMode = ThreadMode.MAIN,sticky = true)//这种写法达到粘性的目的 public void receiveSticky(EventBusBean busBean){ draweeView.setImageURI(busBean.getUrl()); title.setText(busBean.getTitle()); } //在onDestory()方法中取消订阅:防止内存溢出 @Override protected void onDestroy() { super.onDestroy(); EventBus.getDefault().removeAllStickyEvents(); EventBus.getDefault().unregister(this); } }
activity_second.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:fresco="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.dhw.everyweek.SecondActivity"> <com.facebook.drawee.view.SimpleDraweeView android:id="@+id/draweeView" android:layout_width="188dp" android:layout_height="188dp" android:layout_gravity="center" android:layout_marginTop="218dp" fresco:actualImageScaleType="focusCrop" fresco:failureImage="@drawable/load_error_image" fresco:failureImageScaleType="fitCenter" fresco:placeholderImage="@drawable/app_default" fresco:placeholderImageScaleType="fitCenter" fresco:roundAsCircle="true" /> <TextView android:text="标题" android:id="@+id/title" android:textSize="21sp" android:textStyle="bold" android:gravity="center" android:layout_marginTop="18dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical"/> </LinearLayout>
Fresco加载图片的素材:
1. app_deafult.jpg
2. load_error_image.jpg