Fresco图片加载+Eventbus跳转传值+Retrofit请求数据+GreenDao操作数据+Mvp分层+RecyclerView展示数据+ButtonKnife生成控件

效果图:    

  


效果图描述:

首页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();
    }
}

  1. <application  
  2.         android:name=".MyApplication" 


清单文件中加入权限

[html]  view plain  copy
  1. <uses-permission android:name="android.permission.INTERNET" />  



请求网络获得的数据生成实体类

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





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值