Android——Fresco、EventBus、GreenDao、Butterknife、Retrofit综合使用

一、案例效果图

      

二、技能描述

 

通过Retrofit进行网络请求数据,要求后两个参数(下方接口地址中的10和1)通过注解方式传进去,

使用RecyclerView进行列表展示,请求到数据之后,使用GreenDao进行数据缓存,当进入页面时,

先从数据库中取数据,进行展示,再进行网络请求,有数据就更新,没有网络情况下只显示数据库中数据。

进入页面后判断网络状态,通过EventBus发送网络状态并Toast显示,使用ButterKnife进行视图注入,

使用Fresco进行列表图片展示。

接口地址

http://gank.io/api/data/Android/10/1

三、实现思路

 

1. 实现整体页面布局,下方5个底部菜单选项,上方添加5个Fragment

2. 导入Fresco,EventBus,GreenDao,Butterknife,Retrofit等的依赖

3. 进入页面后进行网络状态判断,判断后把状态通过EventBus进行发送并Toast显示

4. 创建试题类型,并通过GreenDao生成相应的表结构,进入页面后,进行数据库查询,

将查询到到的数据保存到List中

5. 使用RecyclerView进行列表展示,为RecyclerView创建适配器,使用ButterKnife为ViewHolder注入视图,

重写适配器方法,通过Fresco展示图片

6. 为RecyclerView设置适配器,当有网络时进行网络请求,初始化Retrofit对象,创建接口类,通过注解的方式

设置参数,执行网络请求自动解析数据,如果数据不为空的情况则更新List并更新数据库,刷新列表数据,

7. 断开网络,重新进入,测试数据库缓存是否生效

添加依赖

添加greendao的依赖需要先在APP下的build.gradle进行配置

 

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
        mavenCentral()//加入greendao
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.3'
        classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2'//加入greendao
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

在项目的build.gradle中添加依赖

 

 

apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao'//加入greendao
android {
    compileSdkVersion 26
    buildToolsVersion "26.0.2"
    defaultConfig {
        applicationId "com.bwie.com.oneweekdemo"
        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'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:26.+'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'
    compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'  //Retrofit2所需要的包
    compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'  //ConverterFactory的Gson依赖包

    compile'org.greenrobot:greendao:3.2.2'//greendao
    compile'org.greenrobot:greendao-generator:3.2.2'//greendao

    compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'//recyclerview
    compile 'com.hjm:BottomTabBar:1.1.1'//底部导航栏
    compile 'org.greenrobot:eventbus:3.1.1'//enentbus

    compile 'com.jakewharton:butterknife:8.8.1'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'//butterknife

    compile 'com.facebook.fresco:fresco:0.12.0'//fresco


}
//加入greendao
greendao {
    schemaVersion 1
    daoPackage 'com.bwie.com.oneweekdemo.gen'
    targetGenDir 'src/main/java'
}

网络权限

 

 

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

ResultsBean(参考)

 

 

@Entity
public class ResultsBean {
    @Id
    private String _id;
    private String createdAt;
    private String desc;
    private String publishedAt;
    private String source;
    private String type;
    private String url;
    private boolean used;
    private String who;
    @Convert(columnType = String.class, converter = StringConverter.class)
    private List<String> images;

 

 

User中有一种List类型的数据也需要保存到数据库中,该如何处理呢?

答案很简单,可以转换一下思路,遍历List数据,然后将所有的String对象都append到一个StringBuilder中,

然后保存在数据库中即可。事实上,GreenDao已经为我们考虑到了这种情况,因此才有了 PropertyConverter

这个接口

StringConverter

 

/**
 * Created by Wangrx on 2017/12/2.
 */

public class StringConverter implements PropertyConverter<List<String>, String> {

    @Override
    public List<String> convertToEntityProperty(String databaseValue) {
        if (databaseValue == null) {
            return null;
        }
        else {
            List<String> list = Arrays.asList(databaseValue.split(","));
            return list;
        }
    }

    @Override
    public String convertToDatabaseValue(List<String> entityProperty) {
        if(entityProperty==null){
            return null;
        }
        else{
            StringBuilder sb= new StringBuilder();
            for(String link:entityProperty){
                sb.append(link);
                sb.append(",");
            }
            return sb.toString();
        }
    }
}

BlogService接口定义

 

/**
* Created by Wangrx on 2017/12/2.
*/

public interface BlogService {
@GET("10/1")
Call<JavaBean> getUrl();

}

RetrofitUtils(Retrofit封装)/**
* Created by Wangrx on 2017/12/2.
*/

public class RetrofitUtils {
private static volatile RetrofitUtils instance;
private Retrofit retrofit;

private RetrofitUtils(){

}
private RetrofitUtils(String baseUrl){
retrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(baseUrl)
.build();
}
public static RetrofitUtils getInstance(String baseUrl){
if (instance==null){
synchronized (RetrofitUtils.class){
if (null==instance){
instance = new RetrofitUtils(baseUrl);

}
}
}
return instance;

}
public static RetrofitUtils getInstance(){
if (null == instance){
return getInstance("http://gank.io/api/data/Android/");
}
return instance;
}
public Retrofit getRetrofit(){
return retrofit;
}

}

DBUtils(greendao封装)/**
* Created by Wangrx on 2017/12/2.
*/

public class DBUtils {
private static volatile DBUtils instance;
private final ResultsBeanDao dao;

public DBUtils(Context context){
DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(context, "resultsbean.db", null);
SQLiteDatabase database = helper.getWritableDatabase();
DaoMaster daoMaster = new DaoMaster(database);
DaoSession daoSession = daoMaster.newSession();
dao = daoSession.getResultsBeanDao();

}
public static DBUtils getInstance(Context context){
if (null==instance){
synchronized (DBUtils.class){
if (null==instance){
instance = new DBUtils(context);
}
}
}
return instance;
}
public ResultsBeanDao getDao(){
return dao;
}

}

BaseApplication(存放本地数据,继承Application,初始化Fresco/**
* Created by Wangrx on 2017/12/2.
*/

public class BaseApplication extends Application{
private static BaseApplication instance;
private List<ResultsBean> list;
@Override
public void onCreate() {
super.onCreate();
instance=this;
Fresco.initialize(this);//初始化Fresco类
}
public static BaseApplication getInstance(){
return instance;
}
public List<ResultsBean> getData(){
if (list==null){
list=new ArrayList<>();
}
return list;
}
public void setData(List<ResultsBean> list){
this.list = list;
}
}

MessageEvent(EventBus定义事件的类)/**
* Created by Wangrx on 2017/12/2.
*/

public class MessageEvent {
private boolean connected;

public boolean isConnected() {
return connected;
}

public void setConnected(boolean connected) {
this.connected = connected;
}
}

MainActivitypublic class MainActivity extends AppCompatActivity {


private BottomTabBar mb;

@Override
protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//注册
EventBus.getDefault().register(this);
mb = (BottomTabBar) findViewById(R.id.bottom_tab_bar);
mb.init(getSupportFragmentManager())
.setImgSize(50, 50)
.setFontSize(8)
.setTabPadding(4, 6, 10)
.setChangeColor(Color.RED, Color.DKGRAY)
.addTabItem("首页", R.mipmap.shouye, FragmentShow.class)
.addTabItem("分类", R.mipmap.fenlei, FragmentFen.class)
.addTabItem("优惠", R.mipmap.youhui, FragmentYou.class)
.addTabItem("购物车", R.mipmap.gouwuche, FragmentCart.class)
.addTabItem("我的", R.mipmap.people, FragmentMy.class)
.isShowDivider(true)
.setOnTabChangeListener(new BottomTabBar.OnTabChangeListener() {
@Override
public void onTabChange(int position, String name) {
}
});


}
@Subscribe()
public void getConnected(MessageEvent event){
if (event.isConnected()){
Toast.makeText(this, "当前网络状态良好", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(this, "当前网络不可用", Toast.LENGTH_SHORT).show();
}


}

@Override
public void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}

}

FragmentShow/**
* Created by Wangrx on 2017/12/2.
*/

public class FragmentShow extends Fragment{
private Retrofit retrofit;
private ResultsBeanDao dao;
private List<ResultsBean> data;
private RecyclerView recyView;
private MyAdapter adapter;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

View view = View.inflate(getContext(), R.layout.fragmertshow, null);
recyView = view.findViewById(R.id.recy_view);

return view;
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
dao = DBUtils.getInstance(getContext()).getDao();
boolean connected = isNetworkConnected(getActivity());
Log.i("zzz", "onCreate: "+connected);
MessageEvent event = new MessageEvent();
event.setConnected(connected);
EventBus.getDefault().post(event);
initView();


}
private void initView() {
data = BaseApplication.getInstance().getData();
LinearLayoutManager manager = new LinearLayoutManager(getContext());
recyView.setLayoutManager(manager);
adapter = new MyAdapter(getContext(), data);
recyView.setAdapter(adapter);
if (data == null || data.size() == 0) {
Log.i("zzz", "内存中无数据");
//从数据库中取
List<ResultsBean> dataFromDB = getDataFromDB();
//数据库中也是空
if (dataFromDB==null||dataFromDB.size()==0){
Log.i("zzz", "数据控中为空");
//从网络中取数据
getDataFromNet();
}else {
Log.i("zzz", "数据库中不为空");
putDataToMemory(dataFromDB);
}
}
if (data==null||data.size()==0){
Log.i("zzz", "内存中无数据");
List<ResultsBean> dataFromDB = getDataFromDB();
if (dataFromDB==null||dataFromDB.size()==0){
Log.i("zzz", "数据库中为空");
getDataFromNet();
}else {

putDataToMemory(dataFromDB);
}
}



}

public void getDataFromNet(){
retrofit = RetrofitUtils.getInstance().getRetrofit();
BlogService service = retrofit.create(BlogService.class);
Call<JavaBean> call = service.getUrl();
call.enqueue(new Callback<JavaBean>() {
@Override
public void onResponse(Call<JavaBean> call, Response<JavaBean> response) {
List<ResultsBean> results = response.body().getResults();
Log.i("zzz", "onResponse: "+data.toString());
if (results!=null){
Log.i("zzz", "网络不为空");
putDataToMemory(results);
for (ResultsBean databean:results){
dao.insertOrReplace(databean);
}
}

}

@Override
public void onFailure(Call<JavaBean> call, Throwable t) {
Toast.makeText(getContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}

private void putDataToMemory(List<ResultsBean> list) {
Log.i("zzz", "向内存中存数据");
data.clear();
data.addAll(list);
adapter.notifyDataSetChanged();
BaseApplication.getInstance().setData(data);
}

//从数据库中取数据
public List<ResultsBean> getDataFromDB(){
Log.i("zzz", "从数据库中取");
//查询所有数据
List<ResultsBean> dataBeen = dao.loadAll();
if (dataBeen==null||dataBeen.size()==0){
Log.i("zzz", "null");
}else {
Log.i("zzz", "getDataFromDB: "+dataBeen.size());
}
return dataBeen;
}
public boolean isNetworkConnected(Context context) {
if (context != null) {
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
if (mNetworkInfo != null) {
return mNetworkInfo.isAvailable();
}
}
return false;
}

}

MyAdapter(多条目加载)/**
* Created by Wangrx on 2017/12/2.
*/

public class MyAdapter extends RecyclerView.Adapter {

public static final int TYPE_ONE_IMAGE = 0;
public static final int TYPE_TWO_IMAGE = 1;



private Context context;
private List<ResultsBean> list;

public MyAdapter(Context context, List<ResultsBean> list) {
this.context = context;
this.list = list;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
RecyclerView.ViewHolder holder = null;
switch (viewType) {
case 0:
view = View.inflate(context, R.layout.item, null);
holder = new OneViewHolder(view);
break;
case 1:
view = View.inflate(context, R.layout.twoitem, null);
holder = new TwoViewHolder(view);
}
return holder;
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
switch (getItemViewType(position)) {
case 0:
OneViewHolder holderOne = (OneViewHolder) holder;
holderOne.itemDesc.setText(list.get(position).getDesc());
holderOne.itemType.setText(list.get(position).getType());
break;
case 1:
TwoViewHolder holdertwo = (TwoViewHolder) holder;
List<String> images = list.get(position).getImages();
if (images != null && images.size() != 0) {
// Glide.with(context).load(images.get(0)).into(holdertwo.itemImg);
holdertwo.itemImage.setImageURI(images.get(0));
}

holdertwo.itemDesc.setText(list.get(position).getDesc());
holdertwo.itemType.setText(list.get(position).getType());
}

}

@Override
public int getItemViewType(int position) {

List<String> images = list.get(position).getImages();
if (images != null && images.size() != 0) {
return TYPE_TWO_IMAGE;
} else {
return TYPE_ONE_IMAGE;
}
}

@Override
public int getItemCount() {
return list.size();
}

public class OneViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.item_desc)
TextView itemDesc;
@BindView(R.id.item_type)
TextView itemType;

public OneViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}

public class TwoViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.item_image)
SimpleDraweeView itemImage;
@BindView(R.id.item_desc)
TextView itemDesc;
@BindView(R.id.item_type)
TextView itemType;

public TwoViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}

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.bwie.com.oneweekdemo.MainActivity">
    <com.hjm.bottomtabbar.BottomTabBar
        android:id="@+id/bottom_tab_bar"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >
    </com.hjm.bottomtabbar.BottomTabBar>


</RelativeLayout>

 

 

 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值