服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Android - Android使用Realm数据库实现App中的收藏功能(代码详解)

Android使用Realm数据库实现App中的收藏功能(代码详解)

2022-12-06 14:51_彼岸雨敲窗_ Android

这篇文章主要介绍了Android使用Realm数据库实现App中的收藏功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

前 言

App数据持久化功能是每个App必不可少的功能,而Android最常用的数据持久化方式主要有以下的五种方式:

  1. 使用SharedPreferences存储数据;
  2. 文件存储数据;
  3. SQLite数据库存储数据;
  4. 使用ContentProvider存储数据;
  5. 网络存储数据。

其中前四种都是缓存数据到本地,这篇主要讲的是使用第三种方式来实现App中的收藏功能,不过不用Android原生自带SQLite数据库来存储数据,而是使用第三方的Realm数据库来来存储数据。

Realm 本质上是一个嵌入式数据库,他并不是基于SQLite所构建的。它拥有自己的数据库存储引擎,可以高效且快速地完成数据库的构建操作。和SQLite不同的是,它允许你在持久层直接和数据对象工作。在它之上是一个函数式风格的查询api,众多的努力让它比传统的SQLite 操作更快 。

Realm不仅支持Android的接入,还支持IOS的接入。那么接下来就使用Realm数据库实现Android App中的收藏功能吧。

需求分析

要使用Realm数据库实现App中的收藏功能,需要实现以下几个功能和步骤:

  1. 在Android项目接入Realm数据库;
  2. 创建收藏数据库表;
  3. 实现对收藏数据库表进行增删查的操作;
  4. 数据库表增删查时界面实时渲染和更新。
  5.  

接入Realm数据库

然后在AS的外层build.gradle里的buildscript.dependencies添加Realm数据库相关的依赖

?
1
2
3
4
5
6
buildscript {
 dependencies {
 ...
 classpath "io.realm:realm-gradle-plugin:6.0.1"
 }
}

然后在AS的内层build.gradle里添加Realm数据库相关的依赖

在顶部 apply plugin: ‘com.android.application' 下添加 apply plugin: ‘realm-android' 的声明,如下图

Android使用Realm数据库实现App中的收藏功能(代码详解)

在定义的Application里初始化数据库相关的配置(包括数据库名称和版本号,具体代码看Demo源码)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* 数据库相关的配置
*
* @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();
}
}

创建收藏数据库表
首先先创建一张收藏数据库表,代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
 * 电影收藏数据库表名
 */
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作为该表的主键,也是数据在表里的唯一性。

收藏数据库表的增删查
添加影视数据到到数据库的操作(增)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/**
* 添加收藏数据到本地数据库
*
* @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数据插入数据到数据库的操作,这是一样异步插入数据的方式。在业务场景的需要,可以改新增和更新数据的插入方式,比如插入数据时如果数据库中已经存在了该数据则进行更新操作,否则进行了新增操作。

从数据库中删除一条影视数据的操作(删)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 通过键值对来删除指定收藏数据
*
* @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);
  }
 });
 }
});
}

 

从数据库中删除全部影视数据的操作(删)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 清除全部收藏的数据库内容
*/
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("暂无收藏数据可删除");
  return;
 }
 movieCollectDBModels.deleteAllFromRealm();
 ToastUtil.showToast("收藏数据已全部清空");
 }
});
 
}

从数据库中查询全部影视数据的操作(查)

?
1
2
3
4
5
6
7
8
9
10
11
/**
 * 查询所有的收藏数据
 *
 * @param listener
 */
 public void queryAllCollectData(RealmChangeListener<RealmResults<MovieCollectDBModel>> listener) {
 RealmResults<MovieCollectDBModel> movieCollectDBModels = mRealm.where(MovieCollectDBModel.class)
  .sort("createdTime", Sort.DESCENDING)
  .findAllAsync();
 movieCollectDBModels.addChangeListener(listener);
 }

当前用户进入收藏界面的时候,需要从数据库中拉取全部的收藏数据,可以刚才添加收藏时间进行倒序排序。

数据库表增删查时界面的渲染和更新
当用户进入主页的时候,首次从网络获取数据,然后遍历一下网络获取数据是否已经有数据操作收藏数据库中,如果有的话则需要提示用户该数据已经被收藏并更改收藏图标。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
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) {
  // 跳转至我的收藏界面
  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<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);
 }
 
 // 查询本地收藏数据库中是否存在收藏的数据(更改收藏图标用的)
 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<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();
 }
}

收藏界面的代码,包括查询和删除操作。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
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;
   // 加载数据
   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<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) {
  // 根据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中的收藏功能(代码详解)

apk安装包下载体验地址:

可以扫描以下二维码进行下载安装,或者点击以下链接 http://app.fukaimei.top/MovieCollect 进行下载安装体验。

总结

到此这篇关于Android使用Realm数据库实现App中的收藏功能(代码详解)的文章就介绍到这了,更多相关android realm数据库实现app收藏内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/fukaimei/article/details/105089870

延伸 · 阅读

精彩推荐