重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
这篇文章主要介绍了Android使用Realm数据库如何实现App中的收藏功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
成都创新互联专注于开原企业网站建设,响应式网站,商城网站开发。开原网站建设公司,为开原等地区提供建站服务。全流程按需定制制作,专业设计,全程项目跟踪,成都创新互联专业和态度为您提供的服务
App数据持久化功能是每个App必不可少的功能,而Android最常用的数据持久化方式主要有以下的五种方式:
使用SharedPreferences存储数据;
文件存储数据;
SQLite数据库存储数据;
使用ContentProvider存储数据;
网络存储数据。
其中前四种都是缓存数据到本地,这篇主要讲的是使用第三种方式来实现App中的收藏功能,不过不用Android原生自带SQLite数据库来存储数据,而是使用第三方的Realm数据库来来存储数据。
Realm 本质上是一个嵌入式数据库,他并不是基于SQLite所构建的。它拥有自己的数据库存储引擎,可以高效且快速地完成数据库的构建操作。和SQLite不同的是,它允许你在持久层直接和数据对象工作。在它之上是一个函数式风格的查询api,众多的努力让它比传统的SQLite 操作更快 。
Realm不仅支持Android的接入,还支持IOS的接入。那么接下来就使用Realm数据库实现Android App中的收藏功能吧。
需求分析
要使用Realm数据库实现App中的收藏功能,需要实现以下几个功能和步骤:
在Android项目接入Realm数据库;
创建收藏数据库表;
实现对收藏数据库表进行增删查的操作;
数据库表增删查时界面实时渲染和更新。
接入Realm数据库
然后在AS的外层build.gradle里的buildscript.dependencies
添加Realm数据库相关的依赖
buildscript { dependencies { ... classpath "io.realm:realm-gradle-plugin:6.0.1" } }
然后在AS的内层build.gradle里添加Realm数据库相关的依赖
在顶部 apply plugin: ‘com.android.application' 下添加 apply plugin: ‘realm-android' 的声明,如下图
在定义的Application里初始化数据库相关的配置(包括数据库名称和版本号,具体代码看Demo源码)
/** * 数据库相关的配置 * * @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(); } }
创建收藏数据库表
首先先创建一张收藏数据库表,代码如下:
/** * 电影收藏数据库表名 */ public class MovieCollectDBModel extends RealmObject { // 影视id,主键 @Required @PrimaryKey @Index private String movieId; // 影视名称 @Required private String movieName; // 影视海报、封面 @Required private String poster; // 影视标签 @Required private String movieLabel; // 影视类型 @Required private String videoType; // 添加到数据的时间 @Required private String createdTime; // 以下省略字段的 set 和 get }
该类继承于Realm的RealmObject类,其中字段movieId作为该表的主键,也是数据在表里的唯一性。
收藏数据库表的增删查
添加影视数据到到数据库的操作(增)
/** * 添加收藏数据到本地数据库 * * @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("收藏数据添加成功!"); ToastUtil.showToast(String.format("%s 已收藏", mvName)); } }, new Realm.Transaction.OnError() { @Override public void onError(Throwable error) { L.i("收藏数据添加失败:" + error.toString()); ToastUtil.showToast(String.format("%s 收藏失败", mvName)); } }); }
上面的代码是Realm数据插入数据到数据库的操作,这是一样异步插入数据的方式。在业务场景的需要,可以改新增和更新数据的插入方式,比如插入数据时如果数据库中已经存在了该数据则进行更新操作,否则进行了新增操作。
从数据库中删除一条影视数据的操作(删)
/** * 通过键值对来删除指定收藏数据 * * @param key * @param value */ public void deleteByKeyCollectData(String key, String value) { RealmResultsmovieCollectDBModels = mRealm.where(MovieCollectDBModel.class) .equalTo(key, value) .findAllAsync(); movieCollectDBModels.addChangeListener(new RealmChangeListener >() { @Override public void onChange(RealmResults movieCollectDBModels1) { if (movieCollectDBModels1.isEmpty()) return; mRealm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { movieCollectDBModels1.deleteFromRealm(0); } }); } }); }
从数据库中删除全部影视数据的操作(删)
/** * 清除全部收藏的数据库内容 */ public void deleteAllCollectData() { RealmResultsmovieCollectDBModels = mRealm.where(MovieCollectDBModel.class) .findAll(); mRealm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { if (movieCollectDBModels.isEmpty()) { ToastUtil.showToast("暂无收藏数据可删除"); return; } movieCollectDBModels.deleteAllFromRealm(); ToastUtil.showToast("收藏数据已全部清空"); } }); }
从数据库中查询全部影视数据的操作(查)
/** * 查询所有的收藏数据 * * @param listener */ public void queryAllCollectData(RealmChangeListener> listener) { RealmResults movieCollectDBModels = mRealm.where(MovieCollectDBModel.class) .sort("createdTime", Sort.DESCENDING) .findAllAsync(); movieCollectDBModels.addChangeListener(listener); }
当前用户进入收藏界面的时候,需要从数据库中拉取全部的收藏数据,可以刚才添加收藏时间进行倒序排序。
数据库表增删查时界面的渲染和更新
当用户进入主页的时候,首次从网络获取数据,然后遍历一下网络获取数据是否已经有数据操作收藏数据库中,如果有的话则需要提示用户该数据已经被收藏并更改收藏图标。
public class MainActivity extends AppCompatActivity { private MovieAdapter adapter; private ListmList = 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) { // 跳转至我的收藏界面 startActivity(new Intent(MainActivity.this, MovieCollectActivity.class)); } }); // 初始化本地数据库帮助类 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; // 加载数据 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("暂无更多的数据啦"); // 将不会再次触发加载更多事件 refreshLayout.finishLoadMoreWithNoMoreData(); refreshLayout.setEnableLoadMore(false); refreshLayout.finishLoadMore(); } }, 2000); } }); //触发自动刷新 refreshLayout.autoRefresh(); } private void initData() { // 模拟从网络获取到json数据 app\src\main\assets\movieData.json String jsonData = BaseUtil.getAssetsJson(this, "movieData.json"); // L.i("jsonData:" + jsonData); if (TextUtils.isEmpty(jsonData)) { ToastUtil.showToast("Json数据为空"); return; } if (mList != null) mList.clear(); // 将json数据解析为Java实体对象 MovieDataModel movieDataModel = new Gson().fromJson(jsonData, MovieDataModel.class); List 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); } // 查询本地收藏数据库中是否存在收藏的数据(更改收藏图标用的) queryAllCollectData(); try { // 设置适配器 homeMovieList.setLayoutManager(new GridLayoutManager(this, 3)); adapter = new MovieAdapter(this, mList); homeMovieList.setAdapter(adapter); } catch (Exception e) { e.printStackTrace(); } // 设置条目的点击事件 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) { // 如果已经收藏了则清除该条收藏 // 根据Id来删除一条数据 mRealmDBHelp.deleteByKeyCollectData("movieId", mvId); mList.get(position).setCollect(false); ToastUtil.showToast(String.format("%s 已取消收藏", mvName)); } else { // 添加收藏数据到本地数据库 mRealmDBHelp.addCollectToDB(mvId, mvName, movieImg, movieTag, videoType); mList.get(position).setCollect(true); } // 通知适配器数据改变重新更新界面 adapter.notifyDataSetChanged(); } @Override public void onItemLongClik(View view, int position) { } }); } /** * 查询本地收藏数据库中是否存在收藏的数据(更改收藏图标用的) */ private void queryAllCollectData() { mRealmDBHelp.queryAllCollectData(new RealmChangeListener >() { @Override public void onChange(RealmResults 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 ListmList = 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; // 加载数据 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("暂无更多的数据啦"); // 将不会再次触发加载更多事件 refreshLayout.finishLoadMoreWithNoMoreData(); refreshLayout.setEnableLoadMore(false); refreshLayout.finishLoadMore(); } }, 2000); } }); //触发自动刷新 refreshLayout.autoRefresh(); } private void initData() { queryAllCollectData(); } /** * 查询本地收藏数据库中所有的数据 */ private void queryAllCollectData() { mRealmDBHelp.queryAllCollectData(new RealmChangeListener >() { @Override public void onChange(RealmResults 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) { // 根据Id来删除一条数据 deleteByKeyCollectData(position); } @Override public void onItemLongClik(View view, int position) { } }); } /** * 根据Id来删除一条数据 * * @param position */ private void deleteByKeyCollectData(int position) { IOSMsgDialog.Companion.init(getSupportFragmentManager()) .setTitle("清除影视提示") .setMessage("是否要清除该条影视收藏的数据?") .setAnimStyle(R.style.LDialogScaleAnimation) .setNegativeButton("否", new View.OnClickListener() { @Override public void onClick(View v) { } }) .setPositiveButton("是", new View.OnClickListener() { @Override public void onClick(View v) { // 根据Id来删除一条数据 mRealmDBHelp.deleteByKeyCollectData("movieId", mList.get(position).getMovieId()); mList.remove(position); adapter.notifyDataSetChanged(); } }, Color.RED) .setDismissListener(new OnDialogDismissListener() { @Override public void onDismiss(DialogInterface dialog) { } }).setCancelableOutside(true).show(); } /** * 删除本地数据库中全部的收藏数据 */ private void deleteRealmDB() { IOSMsgDialog.Companion.init(getSupportFragmentManager()) .setTitle("清空全部收藏数据提示") .setMessage("是否要立即清空全部我的收藏的数据?如果要清除单条数据的话请点击单条数据列表。") .setAnimStyle(R.style.LDialogScaleAnimation) .setNegativeButton("否", new View.OnClickListener() { @Override public void onClick(View v) { } }) .setPositiveButton("是", new View.OnClickListener() { @Override public void onClick(View v) { // 清除全部收藏的数据库内容 mRealmDBHelp.deleteAllCollectData(); mList.clear(); empty_view.setVisibility(View.VISIBLE); movieCollectList.setVisibility(View.GONE); adapter.notifyDataSetChanged(); } }, Color.RED) .setDismissListener(new OnDialogDismissListener() { @Override public void onDismiss(DialogInterface dialog) { } }).setCancelableOutside(true).show(); } @Override protected void onDestroy() { super.onDestroy(); mRealmDBHelp.close(); } }
感谢你能够认真阅读完这篇文章,希望小编分享的“Android使用Realm数据库如何实现App中的收藏功能”这篇文章对大家有帮助,同时也希望大家多多支持创新互联,关注创新互联行业资讯频道,更多相关知识等着你来学习!