版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
【移動應(yīng)用開發(fā)技術(shù)】Android使用Realm數(shù)據(jù)庫如何實現(xiàn)App中的收藏功能
這篇文章主要介紹了Android使用Realm數(shù)據(jù)庫如何實現(xiàn)App中的收藏功能,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓在下帶著大家一起了解一下。App數(shù)據(jù)持久化功能是每個App必不可少的功能,而Android最常用的數(shù)據(jù)持久化方式主要有以下的五種方式:使用SharedPreferences存儲數(shù)據(jù);文件存儲數(shù)據(jù);SQLite數(shù)據(jù)庫存儲數(shù)據(jù);使用ContentProvider存儲數(shù)據(jù);網(wǎng)絡(luò)存儲數(shù)據(jù)。其中前四種都是緩存數(shù)據(jù)到本地,這篇主要講的是使用第三種方式來實現(xiàn)App中的收藏功能,不過不用Android原生自帶SQLite數(shù)據(jù)庫來存儲數(shù)據(jù),而是使用第三方的Realm數(shù)據(jù)庫來來存儲數(shù)據(jù)。Realm本質(zhì)上是一個嵌入式數(shù)據(jù)庫,他并不是基于SQLite所構(gòu)建的。它擁有自己的數(shù)據(jù)庫存儲引擎,可以高效且快速地完成數(shù)據(jù)庫的構(gòu)建操作。和SQLite不同的是,它允許你在持久層直接和數(shù)據(jù)對象工作。在它之上是一個函數(shù)式風(fēng)格的查詢api,眾多的努力讓它比傳統(tǒng)的SQLite操作更快。Realm不僅支持Android的接入,還支持IOS的接入。那么接下來就使用Realm數(shù)據(jù)庫實現(xiàn)AndroidApp中的收藏功能吧。需求分析要使用Realm數(shù)據(jù)庫實現(xiàn)App中的收藏功能,需要實現(xiàn)以下幾個功能和步驟:在Android項目接入Realm數(shù)據(jù)庫;創(chuàng)建收藏數(shù)據(jù)庫表;實現(xiàn)對收藏數(shù)據(jù)庫表進行增刪查的操作;數(shù)據(jù)庫表增刪查時界面實時渲染和更新。接入Realm數(shù)據(jù)庫然后在AS的外層build.gradle里的buildscript.dependencies添加Realm數(shù)據(jù)庫相關(guān)的依賴buildscript
{
dependencies
{
...
classpath
"io.realm:realm-gradle-plugin:6.0.1"
}
}然后在AS的內(nèi)層build.gradle里添加Realm數(shù)據(jù)庫相關(guān)的依賴在頂部applyplugin:‘com.android.application'下添加applyplugin:‘realm-android'的聲明,如下圖在定義的Application里初始化數(shù)據(jù)庫相關(guān)的配置(包括數(shù)據(jù)庫名稱和版本號,具體代碼看Demo源碼)
/**
*
數(shù)據(jù)庫相關(guān)的配置
*
*
@param
context
*/
private
void
initRealm(Context
context)
{
try
{
Realm.init(context);
RealmConfiguration
config
=
new
RealmConfiguration.Builder()
.name(RealmConstant.REALM_DB_NAME)
.schemaVersion(RealmConstant.REALM_DB_VERSION)
.build();
Realm.setDefaultConfiguration(config);
}
catch
(Exception
e)
{
e.printStackTrace();
}
}創(chuàng)建收藏數(shù)據(jù)庫表首先先創(chuàng)建一張收藏數(shù)據(jù)庫表,代碼如下:/**
*
電影收藏數(shù)據(jù)庫表名
*/
public
class
MovieCollectDBModel
extends
RealmObject
{
//
影視id,主鍵
@Required
@PrimaryKey
@Index
private
String
movieId;
//
影視名稱
@Required
private
String
movieName;
//
影視海報、封面
@Required
private
String
poster;
//
影視標(biāo)簽
@Required
private
String
movieLabel;
//
影視類型
@Required
private
String
videoType;
//
添加到數(shù)據(jù)的時間
@Required
private
String
createdTime;
//
以下省略字段的
set
和
get
}該類繼承于Realm的RealmObject類,其中字段movieId作為該表的主鍵,也是數(shù)據(jù)在表里的唯一性。收藏數(shù)據(jù)庫表的增刪查添加影視數(shù)據(jù)到到數(shù)據(jù)庫的操作(增)
/**
*
添加收藏數(shù)據(jù)到本地數(shù)據(jù)庫
*
*
@param
mvId
*
@param
mvName
*
@param
movieImg
*
@param
movieLabel
*
@param
videoType
*/
public
void
addCollectToDB(String
mvId,
String
mvName,
String
movieImg,
String
movieLabel,
String
videoType)
{
MovieCollectDBModel
movieCollectDBModel
=
new
MovieCollectDBModel();
movieCollectDBModel.setMovieId(mvId);
movieCollectDBModel.setMovieName(mvName);
movieCollectDBModel.setPoster(movieImg);
movieCollectDBModel.setMovieLabel(movieLabel);
movieCollectDBModel.setVideoType(videoType);
movieCollectDBModel.setCreatedTime(BaseUtil.getNowDateTimeFormat());
mTransaction
=
mRealm.executeTransactionAsync(new
Realm.Transaction()
{
@Override
public
void
execute(Realm
realm)
{
realm.copyToRealmOrUpdate(movieCollectDBModel);
}
},
new
Realm.Transaction.OnSuccess()
{
@Override
public
void
onSuccess()
{
L.i("收藏數(shù)據(jù)添加成功!");
ToastUtil.showToast(String.format("%s
已收藏",
mvName));
}
},
new
Realm.Transaction.OnError()
{
@Override
public
void
onError(Throwable
error)
{
L.i("收藏數(shù)據(jù)添加失敗:"
+
error.toString());
ToastUtil.showToast(String.format("%s
收藏失敗",
mvName));
}
});
}上面的代碼是Realm數(shù)據(jù)插入數(shù)據(jù)到數(shù)據(jù)庫的操作,這是一樣異步插入數(shù)據(jù)的方式。在業(yè)務(wù)場景的需要,可以改新增和更新數(shù)據(jù)的插入方式,比如插入數(shù)據(jù)時如果數(shù)據(jù)庫中已經(jīng)存在了該數(shù)據(jù)則進行更新操作,否則進行了新增操作。從數(shù)據(jù)庫中刪除一條影視數(shù)據(jù)的操作(刪)
/**
*
通過鍵值對來刪除指定收藏數(shù)據(jù)
*
*
@param
key
*
@param
value
*/
public
void
deleteByKeyCollectData(String
key,
String
value)
{
RealmResults<MovieCollectDBModel>
movieCollectDBModels
=
mRealm.where(MovieCollectDBModel.class)
.equalTo(key,
value)
.findAllAsync();
movieCollectDBModels.addChangeListener(new
RealmChangeListener<RealmResults<MovieCollectDBModel>>()
{
@Override
public
void
onChange(RealmResults<MovieCollectDBModel>
movieCollectDBModels1)
{
if
(movieCollectDBModels1.isEmpty())
return;
mRealm.executeTransaction(new
Realm.Transaction()
{
@Override
public
void
execute(Realm
realm)
{
movieCollectDBModels1.deleteFromRealm(0);
}
});
}
});
}從數(shù)據(jù)庫中刪除全部影視數(shù)據(jù)的操作(刪)
/**
*
清除全部收藏的數(shù)據(jù)庫內(nèi)容
*/
public
void
deleteAllCollectData()
{
RealmResults<MovieCollectDBModel>
movieCollectDBModels
=
mRealm.where(MovieCollectDBModel.class)
.findAll();
mRealm.executeTransaction(new
Realm.Transaction()
{
@Override
public
void
execute(Realm
realm)
{
if
(movieCollectDBModels.isEmpty())
{
ToastUtil.showToast("暫無收藏數(shù)據(jù)可刪除");
return;
}
movieCollectDBModels.deleteAllFromRealm();
ToastUtil.showToast("收藏數(shù)據(jù)已全部清空");
}
});
}從數(shù)據(jù)庫中查詢?nèi)坑耙晹?shù)據(jù)的操作(查)/**
*
查詢所有的收藏數(shù)據(jù)
*
*
@param
listener
*/
public
void
queryAllCollectData(RealmChangeListener<RealmResults<MovieCollectDBModel>>
listener)
{
RealmResults<MovieCollectDBModel>
movieCollectDBModels
=
mRealm.where(MovieCollectDBModel.class)
.sort("createdTime",
Sort.DESCENDING)
.findAllAsync();
movieCollectDBModels.addChangeListener(listener);
}當(dāng)前用戶進入收藏界面的時候,需要從數(shù)據(jù)庫中拉取全部的收藏數(shù)據(jù),可以剛才添加收藏時間進行倒序排序。數(shù)據(jù)庫表增刪查時界面的渲染和更新當(dāng)用戶進入主頁的時候,首次從網(wǎng)絡(luò)獲取數(shù)據(jù),然后遍歷一下網(wǎng)絡(luò)獲取數(shù)據(jù)是否已經(jīng)有數(shù)據(jù)操作收藏數(shù)據(jù)庫中,如果有的話則需要提示用戶該數(shù)據(jù)已經(jīng)被收藏并更改收藏圖標(biāo)。public
class
MainActivity
extends
AppCompatActivity
{
private
MovieAdapter
adapter;
private
List<MovieDataModel.DataBean>
mList
=
new
ArrayList<>();
private
RealmDBHelp
mRealmDBHelp;
private
boolean
refreshType;
@BindView(R.id.mTitleBar)
TitleBar
mTitleBar;
@BindView(R.id.homeMovieList)
RecyclerView
homeMovieList;
@BindView(R.id.refreshLayout)
RefreshLayout
refreshLayout;
@Override
protected
void
onCreate(Bundle
savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initRefresh();
}
private
void
initView()
{
ButterKnife.bind(this);
mTitleBar.setOnTitleBarListener(new
OnTitleBarListener()
{
@Override
public
void
onLeftClick(View
v)
{
}
@Override
public
void
onTitleClick(View
v)
{
}
@Override
public
void
onRightClick(View
v)
{
//
跳轉(zhuǎn)至我的收藏界面
startActivity(new
Intent(MainActivity.this,
MovieCollectActivity.class));
}
});
//
初始化本地數(shù)據(jù)庫幫助類
mRealmDBHelp
=
new
RealmDBHelp();
}
private
void
initRefresh()
{
//
開啟自動加載功能(非必須)
refreshLayout.setEnableAutoLoadMore(true);
refreshLayout.setOnRefreshListener(new
OnRefreshListener()
{
@Override
public
void
onRefresh(@NonNull
final
RefreshLayout
refreshLayout)
{
refreshLayout.getLayout().postDelayed(new
Runnable()
{
@Override
public
void
run()
{
refreshType
=
true;
//
加載數(shù)據(jù)
initData();
refreshLayout.finishRefresh();
refreshLayout.resetNoMoreData();//setNoMoreData(false);
}
},
2000);
}
});
refreshLayout.setOnLoadMoreListener(new
OnLoadMoreListener()
{
@Override
public
void
onLoadMore(@NonNull
final
RefreshLayout
refreshLayout)
{
refreshLayout.getLayout().postDelayed(new
Runnable()
{
@Override
public
void
run()
{
refreshType
=
false;
ToastUtil.showToast("暫無更多的數(shù)據(jù)啦");
//
將不會再次觸發(fā)加載更多事件
refreshLayout.finishLoadMoreWithNoMoreData();
refreshLayout.setEnableLoadMore(false);
refreshLayout.finishLoadMore();
}
},
2000);
}
});
//觸發(fā)自動刷新
refreshLayout.autoRefresh();
}
private
void
initData()
{
//
模擬從網(wǎng)絡(luò)獲取到j(luò)son數(shù)據(jù)
app\src\main\assets\movieData.json
String
jsonData
=
BaseUtil.getAssetsJson(this,
"movieData.json");
//
L.i("jsonData:"
+
jsonData);
if
(TextUtils.isEmpty(jsonData))
{
ToastUtil.showToast("Json數(shù)據(jù)為空");
return;
}
if
(mList
!=
null)
mList.clear();
//
將json數(shù)據(jù)解析為Java實體對象
MovieDataModel
movieDataModel
=
new
Gson().fromJson(jsonData,
MovieDataModel.class);
List<MovieDataModel.DataBean>
dataBeanList
=
movieDataModel.getData();
for
(MovieDataModel.DataBean
dataBean
:
dataBeanList)
{
MovieDataModel.DataBean
data
=
new
MovieDataModel.DataBean();
data.setMvid(dataBean.getMvid());
data.setName(dataBean.getName());
data.setPoster(dataBean.getPoster());
data.setUpdateStatus(dataBean.getUpdateStatus());
data.setTag(dataBean.getTag());
data.setVideo_type(dataBean.getVideo_type());
mList.add(data);
}
//
查詢本地收藏數(shù)據(jù)庫中是否存在收藏的數(shù)據(jù)(更改收藏圖標(biāo)用的)
queryAllCollectData();
try
{
//
設(shè)置適配器
homeMovieList.setLayoutManager(new
GridLayoutManager(this,
3));
adapter
=
new
MovieAdapter(this,
mList);
homeMovieList.setAdapter(adapter);
}
catch
(Exception
e)
{
e.printStackTrace();
}
//
設(shè)置條目的點擊事件
adapter.setItemClikListener(new
MovieAdapter.OnItemClikListener()
{
@Override
public
void
onItemClik(View
view,
int
position)
{
String
mvId
=
mList.get(position).getMvid();
String
mvName
=
mList.get(position).getName();
String
movieImg
=
mList.get(position).getPoster();
String
movieTag
=
mList.get(position).getTag();
String
videoType
=
mList.get(position).getVideo_type();
boolean
isCollect
=
mList.get(position).isCollect();
if
(isCollect)
{
//
如果已經(jīng)收藏了則清除該條收藏
//
根據(jù)Id來刪除一條數(shù)據(jù)
mRealmDBHelp.deleteByKeyCollectData("movieId",
mvId);
mList.get(position).setCollect(false);
ToastUtil.showToast(String.format("%s
已取消收藏",
mvName));
}
else
{
//
添加收藏數(shù)據(jù)到本地數(shù)據(jù)庫
mRealmDBHelp.addCollectToDB(mvId,
mvName,
movieImg,
movieTag,
videoType);
mList.get(position).setCollect(true);
}
//
通知適配器數(shù)據(jù)改變重新更新界面
adapter.notifyDataSetChanged();
}
@Override
public
void
onItemLongClik(View
view,
int
position)
{
}
});
}
/**
*
查詢本地收藏數(shù)據(jù)庫中是否存在收藏的數(shù)據(jù)(更改收藏圖標(biāo)用的)
*/
private
void
queryAllCollectData()
{
mRealmDBHelp.queryAllCollectData(new
RealmChangeListener<RealmResults<MovieCollectDBModel>>()
{
@Override
public
void
onChange(RealmResults<MovieCollectDBModel>
movieCollectDBModels)
{
if
(movieCollectDBModels.isEmpty())
{
return;
}
for
(MovieCollectDBModel
movieCollectDBModel
:
movieCollectDBModels)
{
for
(int
i
=
0;
i
<
mList.size();
i++)
{
if
(mList.get(i).getMvid().equals(movieCollectDBModel.getMovieId()))
{
mList.get(i).setCollect(true);
break;
}
}
}
}
});
}
@Override
protected
void
onStop()
{
super.onStop();
mRealmDBHelp.closeTransaction();
}
@Override
protected
void
onDestroy()
{
super.onDestroy();
mRealmDBHelp.close();
}
}收藏界面的代碼,包括查詢和刪除操作。public
class
MovieCollectActivity
extends
AppCompatActivity
{
private
RealmDBHelp
mRealmDBHelp;
private
List<MovieCollectModel>
mList
=
new
ArrayList<>();
private
MovieCollectAdapter
adapter;
private
boolean
refreshType;
@BindView(R.id.mTitleBar)
TitleBar
mTitleBar;
@BindView(R.id.movieCollectList)
RecyclerView
movieCollectList;
@BindView(R.id.empty_view)
RelativeLayout
empty_view;
@BindView(R.id.refreshLayout)
RefreshLayout
refreshLayout;
@Override
protected
void
onCreate(Bundle
savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_movie_collect);
initView();
initRefresh();
}
private
void
initView()
{
ButterKnife.bind(this);
mTitleBar.setOnTitleBarListener(new
OnTitleBarListener()
{
@Override
public
void
onLeftClick(View
v)
{
finish();
}
@Override
public
void
onTitleClick(View
v)
{
}
@Override
public
void
onRightClick(View
v)
{
deleteRealmDB();
}
});
mRealmDBHelp
=
new
RealmDBHelp();
}
private
void
initRefresh()
{
//
開啟自動加載功能(非必須)
refreshLayout.setEnableAutoLoadMore(true);
refreshLayout.setOnRefreshListener(new
OnRefreshListener()
{
@Override
public
void
onRefresh(@NonNull
final
RefreshLayout
refreshLayout)
{
refreshLayout.getLayout().postDelayed(new
Runnable()
{
@Override
public
void
run()
{
refreshType
=
true;
//
加載數(shù)據(jù)
initData();
refreshLayout.finishRefresh();
refreshLayout.resetNoMoreData();//setNoMoreData(false);
}
},
2000);
}
});
refreshLayout.setOnLoadMoreListener(new
OnLoadMoreListener()
{
@Override
public
void
onLoadMore(@NonNull
final
RefreshLayout
refreshLayout)
{
refreshLayout.getLayout().postDelayed(new
Runnable()
{
@Override
public
void
run()
{
refreshType
=
false;
ToastUtil.showToast("暫無更多的數(shù)據(jù)啦");
//
將不會再次觸發(fā)加載更多事件
refreshLayout.finishLoadMoreWithNoMoreData();
refreshLayout.setEnableLoadMore(false);
refreshLayout.finishLoadMore();
}
},
2000);
}
});
//觸發(fā)自動刷新
refreshLayout.autoRefresh();
}
private
void
initData()
{
queryAllCollectData();
}
/**
*
查詢本地收藏數(shù)據(jù)庫中所有的數(shù)據(jù)
*/
private
void
queryAllCollectData()
{
mRealmDBHelp.queryAllCollectData(new
RealmChangeListener<RealmResults<MovieCollectDBModel>>()
{
@Override
public
void
onChange(RealmResults<MovieCollectDBModel>
movieCollectDBModels)
{
if
(movieCollectDBModels.isEmpty())
{
return;
}
if
(mList
!=
null)
mList.clear();
for
(MovieCollectDBModel
movieCollectDBModel
:
movieCollectDBModels)
{
MovieCollectModel
data
=
new
MovieCollectModel();
data.setMovieId(movieCollectDBModel.getMovieId());
data.setMovieName(movieCollectDBModel.getMovieName());
data.setPoster(movieCollectDBModel.getPoster());
data.setMovieTag(movieCollectDBModel.getMovieLabel());
data.setVideoType(movieCollectDBModel.getVideoType());
data.setCreatedTime(movieCollectDBModel.getCreatedTime());
mList.add(data);
}
runOnUiThread(new
Runnable()
{
@Override
public
void
run()
{
parsingMovieList();
}
});
}
});
}
private
void
parsingMovieList()
{
movieCollectList.setLayoutManager(new
GridLayoutManager(this,
3));
adapter
=
new
MovieCollectAdapter(this,
mList);
movieCollectList.setAdapter(adapter);
if
(mList.isEmpty())
{
empty_view.setVisibility(View.VISIBLE);
movieCollectList.setVisibility(View.GONE);
}
else
{
movieCollectList.setVisibility(View.VISIBLE);
empty_view.setVisibility(View.GONE);
}
adapter.setItemClikListener(new
MovieCollectAdapter.OnItemClikListener()
{
@Override
public
void
onItemClik(View
view,
int
position)
{
//
根據(jù)Id來刪除一條數(shù)據(jù)
deleteByKeyCollectData(position);
}
@Override
public
void
onItemLongClik(View
view,
int
position)
{
}
});
}
/**
*
根據(jù)Id來刪除一條數(shù)據(jù)
*
*
@param
position
*/
private
void
deleteByKeyCollectData(int
position)
{
IOSMsgDialog.Companion.init(getSupportFragmentManager())
.setTitle("清除影視提示")
.setMessage("是否要清除該條影視收藏的數(shù)據(jù)?")
.setAnimStyle(R.style.LDialogS
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026年駐馬店上蔡縣事業(yè)單位引進高層次人才59名備考題庫有答案詳解
- 2026廣東茂名市生態(tài)環(huán)境局化州分局招聘勞務(wù)派遣人員3人備考題庫及答案詳解(易錯題)
- 2026廣西壯族自治區(qū)考試錄用人民檢察院檢察官助理工作137人備考題庫及完整答案詳解1套
- 2026四川九洲教育投資管理有限公司招聘語文教師等崗位3人考試參考題庫及答案解析
- 2026新疆前海集團有限責(zé)任公司招聘1人備考題庫及一套完整答案詳解
- 2025-2030中國雙膠紙市場營銷創(chuàng)新及競爭戰(zhàn)略規(guī)劃研究報告
- 2026年個人理財規(guī)劃與投資策略知識題集
- 2026廣西北海市農(nóng)業(yè)農(nóng)村局招錄公益性崗位人員1人備考題庫及答案詳解1套
- 2026上半年貴州事業(yè)單位聯(lián)考貴州省應(yīng)急管理廳招聘3人備考題庫及答案詳解一套
- 2025-2030中醫(yī)藥行業(yè)市場深度調(diào)研及發(fā)展趨勢與投資前景預(yù)測研究報告
- 自動駕駛系統(tǒng)關(guān)鍵技術(shù)
- 淮安市2023-2024學(xué)年七年級上學(xué)期期末歷史試卷(含答案解析)
- 完整工資表模板(帶公式)
- 家長要求學(xué)校換老師的申請書
- 奇瑞汽車QC小組成果匯報材料
- 闌尾腫瘤-課件
- CTT2000LM用戶手冊(維護分冊)
- 正式員工派遣單
- 新員工入職申請表模板
- 中外新聞事業(yè)史課程教學(xué)大綱
- LY/T 1357-2008歧化松香
評論
0/150
提交評論