(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

最新文章

  1. 0x00到0xFF二进制数值中1的的个数
  2. JavaScript原生DOM操作API总结
  3. asp.net MVC中如何用Membership类和自定义的数据库进行登录验证
  4. C#中调用Windows API的要点 .
  5. Seafile V4.1 安装笔记
  6. 【剑指offer】面试题39扩展:平衡二叉树
  7. Python 学习日记(第二周)
  8. %f使用时的注意事项
  9. (NO.00001)iOS游戏SpeedBoy Lite成形记(十九)
  10. 第五节《Git基本操作》
  11. Postgresql_根据执行计划优化SQL
  12. Memcached 总结 启动多个Memcached服务 配置文件详解
  13. Find a way HDU - 2612
  14. Java命令学习系列(五)——jhat
  15. centos6下通用二进制格式安装MySQL过程
  16. springcloud 熔断处理
  17. nRF5 SDK for Mesh(六) BLE MESH 的 基础概念
  18. Websphere Application Server 环境配置与应用部署最佳实践
  19. ASP.NET MVC 4.0 中使用NPOI 2.2.0 按模板生成Excel报表
  20. 2019.03.26 读书笔记 关于for与foreach

热门文章

  1. Linux部署Nacos
  2. java常见字节大小存储问题
  3. synchronized和Lock的区别是什么?
  4. 什么是 spring 的内部 bean?
  5. ThreadLocal是什么?使用场景有哪些?
  6. java-第三方工具去做一些校验
  7. Java 面试问题列表包含的主题?
  8. 1_开环系统和闭环系统_反馈控制_Open/Closed Loop System_Feedback
  9. js 关于setTimeout和Promise执行顺序问题
  10. H5打造属于自己的视频播放器(JS篇2)