實現效果:
1, 使用Retrofit + RxJava獲取網絡數據
將下載的數據存入數據庫(要求使用greenDAO)
數據庫存儲完畢後,讀取全部數據並展示在RecyclerView上
圖片使用Glide展示
點擊item的刪除實現數據庫中數據的刪除並更新UI
// Glide
compile 'com.github.bumptech.glide:glide:4.5.0'
// Retrofit
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
// RxJava+Retrofit
compile 'io.reactivex.rxjava2:rxjava:2.1.5'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
// AVLoadingIndicatorView,相當於進度條,有豐富的正在加載中的動畫
compile 'com.wang.avi:library:1.0.5'
implementation 'com.android.support:recyclerview-v7:27.0.2'
implementation 'com.android.support:appcompat-v7:27.0.2'
// app模塊下的build.gradle中添加:
compile 'org.greenrobot:greendao:3.2.2'
-----------------------------------------------------------------------
classpath 'com.android.tools.build:gradle:3.0.1'
// greenDAO
// 整個工程中的build.gradle中添加:
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
/**
* 下載過程中,展示數據之前,展示加載進度UI控件AVLoadingIndicatorView
* 1、各種導包,各種佈局
* 使用Retrofit + RxJava下載數據
* 數據在RecyclerView上展示文字,圖片使用Glide(版本4,只能用在studio3上)框架加載,圓角
*/
// http://www.qubaobei.com/ios/cf/dish_list.php?stage_id=1&limit=10&page=1
public class MainActivity extends AppCompatActivity {
protected AVLoadingIndicatorView mLoadingView;
protected RecyclerView mRecyclerView;
private Retrofit mRetrofit;
private FoodAdaoter mAdaoter;
private DataBeanDao mDao;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.activity_main);
// 初始化greenDAO
mDao = MyApplication.getDaoSession()
.getDataBeanDao();
initView();
loadData();
}
private void loadData() {
// 構建retrofit
mRetrofit = new Retrofit.Builder()
.baseUrl("http://www.qubaobei.com/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
// 獲取接口實例,並獲取其中的觀察者
FoodHttpService httpService = mRetrofit.create(FoodHttpService.class);
Observable<FoodBean> observable = httpService.getObservable(1);
// 自動下載數據並設置數據源, 指定數據下載線程爲子線程,數據變換
observable.subscribeOn(Schedulers.io())
.map(new Function<FoodBean, List<DataBean>>() {
@Override
public List<DataBean> apply(FoodBean foodBean) throws Exception {
return foodBean.getData();
}
})
// 換回主線程展示
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<List<DataBean>>() {
@Override
public void accept(List<DataBean> dataBeans) throws Exception {
// 下載數據成功,存入數據庫
for (DataBean data : dataBeans) {
data.set_id(System.currentTimeMillis());
mDao.insert(data);
}
// 存儲完畢後,從數據庫讀取數據
List<DataBean> datas = mDao.queryBuilder()
.build()
.list();
mAdaoter.addDatas(datas);
// 成功展示數據後,隱藏正在加載進度視圖
mLoadingView.setVisibility(View.GONE);
}
});
}
private void initView() {
mLoadingView = (AVLoadingIndicatorView) findViewById(R.id.loading_view);
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
// 適配器伴隨RecyclerView誕生而誕生,直接綁定,等數據獲取到了再展示
mAdaoter = new FoodAdaoter(this);
mRecyclerView.setAdapter(mAdaoter);
}
}
public class FoodAdaoter extends RecyclerView.Adapter<FoodAdaoter.ViewHolder> {
private final DataBeanDao mDao;
private Context mContext;
private List<DataBean> mDatas;
public FoodAdaoter(Context context) {
mContext = context;
mDatas = new ArrayList<>();
// 初始化Dao,用於刪除數據
mDao = MyApplication.getDaoSession()
.getDataBeanDao();
}
// 添加數據
public void addDatas(List<DataBean> datas) {
mDatas.addAll(datas);
notifyDataSetChanged();
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(mContext)
.inflate(R.layout.item_food, parent, false);
return new ViewHolder(itemView);
}
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
final DataBean data = mDatas.get(position);
holder.mTitleTextView.setText(data.getTitle());
// 請求加載圖片的配置項,可以擴展圓角,圓圖等功能
// 注意:該配置項是Glide4版本獨有的功能,需要studio3使用
RequestOptions options = new RequestOptions();
// 變換爲圓角
options.transform(new RoundedCorners(200));
// 使用Glide框架展示圖片
Glide.with(mContext)
.load(data.getPic())
.apply(options)// 應用我們額外的配置項
.into(holder.mPicImageView);
// 刪除數據按鈕點擊監聽
holder.mDeleteBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 刪除數據庫對應數據
mDao.delete(data);
// 刪除UI界面上item對應展示的數據並刷新
mDatas.remove(position);
notifyDataSetChanged();
Toast.makeText(mContext, "成功刪除第" + position + "條數據", Toast.LENGTH_SHORT).show();
}
});
}
@Override
public int getItemCount() {
return mDatas == null ? 0 : mDatas.size();
}
static class ViewHolder extends RecyclerView.ViewHolder {
Button mDeleteBtn;
TextView mTitleTextView;
ImageView mPicImageView;
public ViewHolder(View itemView) {
super(itemView);
mDeleteBtn = itemView.findViewById(R.id.delete_btn);
mTitleTextView = itemView.findViewById(R.id.title_tv);
mPicImageView = itemView.findViewById(R.id.pic_iv);
}
}
}
public class MyApplication extends Application {
private static DaoSession sDaoSession;
@Override
public void onCreate() {
super.onCreate();
initGreenDAO();
}
private void initGreenDAO() {
DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "food.db");
Database db = helper.getWritableDb();
sDaoSession = new DaoMaster(db).newSession();
}
public static DaoSession getDaoSession() {
return sDaoSession;
}
}
FoodBean--DataBean
public interface FoodHttpService {
@GET("ios/cf/dish_list.php?stage_id=1&limit=10")
Observable<FoodBean> getObservable(@Query("page") int page);
}
activity-main
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.wang.avi.AVLoadingIndicatorView
app:indicator_color="@color/colorAccent"
android:layout_centerInParent="true"
android:id="@+id/loading_view"
app:indicator="Pacman"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
item+food
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/title_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/delete_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:background="#f00"
android:text="刪除"
android:textColor="#fff" />
<ImageView
android:id="@+id/pic_iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/title_tv" />
</RelativeLayout>