RecyclerView + SQLite 简易备忘录-----中(2)
(3)RecyclerView的实现 ---中间的内容
RecyclerView是一个比ListView更加强大的滚动控件。要使用这个控件需要先在项目的build.gradle中添加RecyclerView库的依赖。这个内容在第一节就讲过,此处按下不表。
然后在布局文件中加入RecyclerView的控件。---->然后新建一个布局文件recycler_item.xml,在这里写RecyclerView的子项布局。
以上布局步骤在前面的小节中已经讲过。现在看看他们的具体实现。
上一节代码讲到:
adapter = new MemoAdapter(MainActivity.this,arr);
StaggeredGridLayoutManager st = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(st);
recyclerView.setAdapter(adapter);
。
MemoAdapter是一个备忘录适配器,通过这个适配器将arr集合中的数据和RecyclerView联系起来。
怎么联系的呢?
先来看看MemoAdapter这个类。
该类有一个构造方法,三个重写方法,一个内部类,一条注解和一个自定义方法setFiler(List<MemoBean> filterList)。
先看构造方法
//构造器,第一个参数是上下文,第二个参数是传入的带有备忘录所有数据的集合
public MemoAdapter(Context mcontext, List<MemoBean> arr) {
this.mcontext = mcontext;
this.arr = arr;
}
来看内部类:
/*该内部类继承RecyclerView.ViewHolder。然后在ViewHolder的主构造方法中传入一个View参数,
这个参数通常就是RecyclerView子项的最外层布局。
通过这个最外层布局的参数,那么我们就可以通过findViewById()方法来获取布局中各组件的实例了。*/
public class ViewHolder extends RecyclerView.ViewHolder{
TextView item_title,item_content,item_time;
ImageView item_img;
LinearLayout item_layout;
public ViewHolder(@NonNull View itemView) {
super(itemView);
item_title = itemView.findViewById(R.id.item_title);
item_content = itemView.findViewById(R.id.item_content);
item_time = itemView.findViewById(R.id.item_time);
item_img = itemView.findViewById(R.id.item_image);
item_layout = itemView.findViewById(R.id.item_layout);
}
}
来看onCreateViewHolder()方法:第一个参数是要创建的View的父View,第二个参数是要创建的这个View类型。
@NonNull
@Override //该方法是用于创建ViewHolder的实例.
// 在这个布局中将子项布局recycler_item加载进来,然后创建一个ViewHolder的实例,并把加载出来的布局传入构造函数当中,最后将ViewHolder的实例返回。
public MemoAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mcontext).inflate(R.layout.recycler_item,parent,false);
ViewHolder mholder = new ViewHolder(view);
return mholder;
}
使用LayoutInflater来将recycler_item这个子项加载进来。它的inflate()方法接收三个参数。
第一个参数是:要加载布局文件的id。
第二个参数是:给加载好的布局中添加一个父布局。
第三个参数指定为false,表示只让我们在父布局中声明的layout属性生效,但不会为这个View添加父布局。
来看onBindViewHolder()方法:第一个参数是一个ViewHolder,第二个是位置参数。
@Override //该方法用于对RecyclerView子项的数据复制,会在每个子项被滚动到屏幕内的时候执行
public void onBindViewHolder(@NonNull MemoAdapter.ViewHolder mholder, int position) {
final MemoBean memoBean = arr.get(position);
mholder.item_title.setText(memoBean.getTitle());
mholder.item_content.setText(memoBean.getContent());
mholder.item_time.setText(memoBean.getTime());
Glide.with(mcontext).load(memoBean.getImgpath()).into(mholder.item_img);
if(memoBean.getImgpath() ==null){ //如果图片地址为空,则不显示图片
// Toast.makeText(mcontext,"memoBean.getImgpath()"+memoBean.getImgpath(),Toast.LENGTH_LONG).show();
mholder.item_img.setVisibility(View.GONE);
}
/* 以上代码都是对子项的数据进行赋值,每个子项被滚动到屏幕的时候的时候执行。 */
//长按删除
mholder.item_layout.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
AlertDialog.Builder dialog = new AlertDialog.Builder(mcontext); //弹出一个AlertDialog进行确认。
dialog.setMessage("确定删除吗?");
dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() { //如果点击确认,就从数据库里删除,并从arr集合中移出,然后刷新该页面。
@Override
public void onClick(DialogInterface dialogInterface, int i) {
myDbHelper = new MyDbHelper(mcontext);
database = myDbHelper.getWritableDatabase();
database.delete("tb_memory","_id=?",new String[]{arr.get(position).getId()}); //从数据库里删除
arr.remove(position); //从arr集合中移出
Toast.makeText(mcontext,"删除成功",Toast.LENGTH_LONG).show();
notifyItemChanged(position); //然后刷新该页面,局部刷新,还有其他的刷新方法,这里不讲
dialogInterface.dismiss();
}
});
dialog.setNegativeButton("取消",null);
dialog.setCancelable(false);
dialog.create();
dialog.show();
return false;
}
});
//点击显示
mholder.item_layout.setOnClickListener(new View.OnClickListener() { //如果对子项进行点击,就启动AddInfoActivity,这里我们将该子项的id一起传入AddInfoActivity,因为我们还要在AddInfoActivity中进行判断。
@Override //判断什么?在AddInfoActivity中,如果该id存在,那么我们就将该id的内容显示到页面中。如果不存在,那应当是从悬浮按钮点击进入的该Activity,则显示添加页面。
public void onClick(View view) {
Intent intent = new Intent(mcontext, AddInfoActivity.class);
intent.putExtra("_id",arr.get(position).getId());
Toast.makeText(mcontext,"_id"+arr.get(position).getId(),Toast.LENGTH_LONG).show();
startActivity(intent);
}
});
}
来看getItemCount()方法:
public int getItemCount() {
return arr.size();
}
很简单,没啥好说的。
来看ViewHolder这个内部类:
/*该内部类继承RecyclerView.ViewHolder。然后在ViewHolder的主构造方法中传入一个View参数,
这个参数通常就是RecyclerView子项的最外层布局。
通过这个最外层布局的参数,那么我们就可以通过findViewById()方法来获取布局中各组件的实例了。*/
public class ViewHolder extends RecyclerView.ViewHolder{
TextView item_title,item_content,item_time;
ImageView item_img;
LinearLayout item_layout;
public ViewHolder(@NonNull View itemView) {
super(itemView);
item_title = itemView.findViewById(R.id.item_title);
item_content = itemView.findViewById(R.id.item_content);
item_time = itemView.findViewById(R.id.item_time);
item_img = itemView.findViewById(R.id.item_image);
item_layout = itemView.findViewById(R.id.item_layout);
}
}
来看setFiler(List<MemoBean> filterList)方法:
接收一个MemoBean类型的集合,该集合为过滤后的数据,将该集合直接赋值给arr,再刷新界面。
就成功的将搜索的数据展示了出来。
//该方法用于搜索时过滤数据。
public void setFiler(List<MemoBean> filterList){
arr = filterList;
notifyDataSetChanged();
}
以上就是MemoAdapter的全部内容。
好的,再回到MainActivity的那段代码:
adapter = new MemoAdapter(MainActivity.this,arr);
StaggeredGridLayoutManager st = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(st);
recyclerView.setAdapter(adapter);
在这里新建了一个MemoAdapter的适配器adapter。
下一句代码StaggeredGridLayoutManager是什么?
RecyclerView给我们内置了两种布局排列方式:GirdLayoutManager 网格布局
和 StaggeredGridLayoutManager 瀑布流布局
StaggeredGridLayoutManager(布局的列数,布局的排列方向)。
StaggeredGridLayoutManager.VERTICAL表示会让布局纵向排列。
所以recyclerView.setLayoutManager(st);的意思是:指定布局方式为:纵向排列的两行。
最后通过recyclerView.setAdapter(adapter);的方法完成适配器的设置。
(4)SearchView的实现 ---搜索功能
现在我们来看看搜索功能的完整实现。
SearchView是搜索框组件,它可以让用户在文本框内输入汉字,并允许通过监听器监控用户输入,当用户用户输入完成后提交搜索按钮时,也通过监听器执行实际的搜索。
有一个常用的方法setOnQueryTextListener(SearchView.OnQueryTextListener listener):为该搜索框设置事件监听器。我们只需通过该方法即可实现搜索功能。
1.首先,通过绑定控件msearch = findViewById(R.id.search);的方式获取到SearchView组件的对象。
2.继承OnQueryTextListener接口,并实现里面的两个方法。
onQueryTextSubmit(String s):单击搜索按钮时激发该方法。
onQueryTextChange(String s):用户输入字符时激发该方法。
在该方法中调用filter(s)方法。s为用户输入的字符串。
来看看filter(String text)方法:
private List<MemoBean> filter(String text){
filterS = new ArrayList<>();
for(MemoBean memoBean:arr){
if(memoBean.getTitle().contains(text) || memoBean.getContent().contains(text) || memoBean.getTime().contains(text)){
filterS.add(memoBean);
}
}
return filterS;
}
很简单的逻辑,新建了一个MemoBean类型的集合,用于存符合搜索条件的数据,并将其返回。
用for循环遍历arr集合。这个集合里有备忘录的所有内容。如果用户输入的内容 是 集合里的标题,或者内容,或者时间的子字符串,就将该条数据添加给filterS。
回到@Override
public boolean onQueryTextChange(String s) {
filterS = filter(s);
adapter.setFiler(filterS);
return false;
}
现在我们的filterS里装满了符合搜索条件的数据,通过适配器里的setFiler(filterS)方法将页面刷新,将结果显示出来。
2.直接msearch.setOnQueryTextListener(this);
效果图:
(5)FAB的实现 ----悬浮按钮
这个组件已经在前面讲过了。
再看下布局代码:
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/btn_add"
android:src="@drawable/add"
app:fabSize="normal"
android:backgroundTint="#66CCCC"
android:elevation="5dp"
app:rippleColor="#66CCCC"
android:layout_gravity="bottom|right"
android:layout_margin="50dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
然后在MainActivity中实现点击跳转就好了:
private void btnOnClicknext(){
btn_add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this,AddInfoActivity.class);
startActivity(intent);
finish();
}
});
}
跳转后,启动AddInfoActivity,进入添加备忘录的页面。
-------
源码:https://github.com/Xiang-MY/MemoDemo
RecyclerView + SQLite 简易备忘录-----中(2)的更多相关文章
- RecyclerView + SQLite 简易备忘录-----中(1)
在上一节讲完了登录界面的内容,现在随着Activity的跳转,来到MainActivity. 1.主界面activity_main.xml 由上图,activity_main.xml的内容很简单. 首 ...
- RecyclerView + SQLite 简易备忘录-----下
最后就是添加备忘录的界面了.同时也是显示备忘录内容的界面. 1.activity_add_info.xml 也是比较简陋的一个页面设计. 顶部是一个自定义的Toolbar,剩下的部分都是ScrollV ...
- RecyclerView + SQLite 简易备忘录-----上
先看效果 图一只是做了简单的页面,没有连接数据库,刚写完页面才想起备忘录好像不需要登录------但用SharedPreferences写了个记住密码. 图二是主页面,实现了搜索,添加,删除,修改几个 ...
- C# 在SQLite数据库中存储图像 z
C# 在SQLite数据库中存储图像 更多 0 C# SQLite 建表语句 CREATE TABLE [ImageStore]([ImageStore_Id] INTEGER NOT NULL ...
- 将 flask 中的 session 存储到 SQLite 数据库中
将 flask 中的 session 存储到 SQLite 数据库中 使用 flask 构建服务器后端时,常需要在浏览器端存储 cookie 用于识别不同用户,根据不同的 cookie 判断出当前请求 ...
- 网络采集软件核心技术剖析系列(6)---将任意博主的全部博文下载到SQLite数据库中并通过Webbrower显示(将之前的内容综合到一起)
一 本系列随笔目录及本节代码下载 自己开发的豆约翰博客备份专家软件工具问世3年多以来,深受广大博客写作和阅读爱好者的喜爱.同时也不乏一些技术爱好者咨询我,这个软件里面各种实用的功能是如何实现的. 该软 ...
- SQLite数据库中rowid使用
SQLite数据库中rowid使用 SQLite中每个表都默认包含一个隐藏列rowid,使用WITHOUT ROWID定义的表除外.通常情况下,rowid可以唯一的标记表中的每个记录.表中插入的第 ...
- SQLite 3 中的数据类型
SQLite使用动态类型系统,在SQLite中,值的数据类型和值本身,而不是和它的容器,关联在一起的.SQLite的动态类型系统和其他数据库引擎的静态类型系统是兼容的,这样在静态类型的数据库上执行的S ...
- Mysql(或者sqlite), Mongo中update Column + 1
Mysql(或者sqlite), Mongo中update Column + 1 有类似以下需求,在数据库表里有一个字段,记录了一个count,然后又时候需要在count的基础上加上某个数字,比如1. ...
随机推荐
- 第3 章 802.11 MAC
一 前言 802.11 规格的关键在于MAC(介质访问控制层),属于数据链路层,它定义了数据帧怎样在介质上进行传输.MAC 位于各种物理层之上,控制数据的传输.不同的物理层可以提供不同的传输速度,不过 ...
- Prometheus+alertmanager告警配置-2
prometheus 告警 prometheus 通过alertmanager进行告警 实现监控告警的步骤: 在prometheus中定义告警规则rule_files alertmanager配置告警 ...
- kafka 学习(二--前言)
kafka 现在在企业应用和互联网项目中的应用越来越多了,本篇文章就从 kafka 的基础开始带你一展 kafka 的宏图 1. 什么是 Kafka Kafka 是一个分布式流式平台,它有三个关键能力 ...
- python 装饰器函数基础知识
1.装饰器的本质--一个闭包函数 2.装饰器的功能--在不改变原函数及其调用方式情况下对原函数功能进行拓展 3.带参数和返回值的装饰器 def timer(func): @wraps(func) #使 ...
- redis 为什么是单线程的?
一.Redis为什么是单线程的? 因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽.既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理 ...
- Spring 支持的 ORM?
Spring 支持以下 ORM:HibernateiBatisJPA (Java Persistence API)TopLinkJDO (Java Data Objects)OJB
- 有哪些类型的通知Advice?
Before - 这些类型的 Advice 在 joinpoint 方法之前执行,并使用 @Before 注解标记进行配置. After Returning - 这些类型的 Advice 在连接点方法 ...
- 用maven建立一个工程5
在命令行里面输入cd myapp再按回车 再输入mvn compile再按回车 再输入 cd target按回车 再输入cd../按回车 再输入mvn package按回车 最后输入java -cla ...
- centos云服务器配置redis外网可访问
找到这行,注释 bind 127.0.0.1 #bind 127.0.0.1 找到这行,修改 protected-mode yes protected-mode no 重启服务 ./redis-ser ...
- Vue报错之" [Vue warn]: Unknown custom element: <wzwzihello> - did you register the component correctly? For recursive components, make sure to provide the "name" option."
一.报错截图 [Vue warn]: Unknown custom element: <wzwzihello> - did you register the component corre ...