热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Android基础教程6recyleviewer

上一篇我们实现了一个简单的创建日记记录的页面,今天我们就来实现一个展示所有日记记录的页面。回忆一下,activity_notes_page.xml布局

上一篇我们实现了一个简单的创建日记记录的页面,今天我们就来实现一个展示所有日记记录的页面。

回忆一下,activity_notes_page.xml布局文件并没有特别指定fragment,任何activity托管fragment的场景,都可
以使用它。下面,为了让该布局更加通用,重命名它为activity_fragment.xml。

在这里插入图片描述

重命名完成后,Android Studio会自动为我们替换引用该文件的地方。

该项目大多都是采用fragment来实现,所以上篇中如下代码可能在每个Activity中都会出现,所以我们做进一步的抽象:

FragmentManager fragmentManager = getSupportFragmentManager();FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();NoteCreateFragment fragment = new NoteCreateFragment();fragmentTransaction.add(R.id.fragment_container, fragment);fragmentTransaction.commit();

新建CurrencyFragmentActivity 类,让其继承基类BaseActivity:

package com.qiushangge.likenotes.base;import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;public abstract class CurrencyFragmentActivity extends BaseActivity {/*** 重写父类initActivityView,此处用来挂载fragment*/@Overrideprotected void initActivityView() {FragmentManager fragmentManager = getSupportFragmentManager();Fragment fragment = fragmentManager.findFragmentById(getFragmentContainer());if (fragment == null) {fragment = createFragment();FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();fragmentTransaction.add(getFragmentContainer(), fragment);fragmentTransaction.commit();}}/*** 返回承载fragment的布局id* @return*/protected abstract int getFragmentContainer();/*** 如果fragment布局没有挂载对应的fragment,那么创建对应的fragment* @return*/protected abstract Fragment createFragment();}

这里我们重写了initActivityView方法,如果其子类仍然需要进行组件相关的初始化工作,那么继续重写即可。如NotePageActivity修改后的实现:

package com.qiushangge.likenotes.activity;import androidx.fragment.app.Fragment;import com.qiushangge.likenotes.R;
import com.qiushangge.likenotes.base.CurrencyFragmentActivity;
import com.qiushangge.likenotes.fragment.NoteCreateFragment;public class NotePageActivity extends CurrencyFragmentActivity {@Overrideprotected int getFragmentContainer() {return R.id.fragment_container;}@Overrideprotected Fragment createFragment() {return new NoteCreateFragment();}@Overrideprotected void initActivityData() {}@Overrideprotected void initActivityListener() {}@Overrideprotected int getActivityLayout() {return R.layout.activity_fragment;}@Overrideprotected void initActivityView() {super.initActivityView();}
}

接下来我们就应该创建我们的日记列表了,不过在开始之前我们先来学习下怎么在Android 中使用Gson库。

Gson是Google开源的一个JSON库,被广泛应用在Android开发中。

在Android Studio中添加Gson库

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

然后检查build.gradle文件
在这里插入图片描述

接下来我们再来了解一下Android中的 SharedPreferences。

Sharedpreferences是Android平台上一个轻量级的存储类,用来保存应用程序的各种配置信息,其本质是一个以“键-值”对的方式保存数据的xml文件,其文件保存在/data/data//shared_prefs目录下。

使用Sharedpreferences保存数据可以分为下面几个步骤:


1.使用Activity类的getSharedPreferences方法获得SharedPreferences对象
2.使用SharedPreferences接口的edit获得SharedPreferences.Editor对象
3.通过SharedPreferences.Editor接口的putXXX方法保存key-value对
4.通过SharedPreferences.Editor接口的commit方法保存key-value对


获取数据可以通过下面的步骤:


1.使用Activity类的getSharedPreferences方法获得SharedPreferences对象
2.通过SharedPreferences对象的getXXX方法获取数据


其中getSharedPreferences 方法原型如下:

public abstract SharedPreferences getSharedPreferences (String name, int mode)

mode的可选值为:
MODE_PRIVATE:只能被自己的应用程序访问

原来还有

MODE_WORLD_READABLE:除了自己访问外还可以被其它应该程序读取
MODE_WORLD_WRITEABLE:除了自己访问外还可以被其它应该程序读取和写入

不过这两个参数在API level 17开始就不推荐使用了。

ok,上一篇我们写完日记后,点击保存按钮会提示保存成功,这里我们利用上面提到的知识点保存日记,并且我们的重新创建一个日记列表用来展示所有的日记。

创建NoteListActivity和NoteListFragment类,并将NoteListActivity设置为启动类:
在这里插入图片描述

接下来我们实现NoteListActivity和NoteListFragment类:

public class NoteListActivity extends CurrencyFragmentActivity {@Overrideprotected int getFragmentContainer() {return R.id.fragment_container;}@Overrideprotected Fragment createFragment() {return new NoteListFragment();}@Overrideprotected void initActivityData() {}@Overrideprotected void initActivityListener() {}@Overrideprotected int getActivityLayout() {return R.layout.activity_fragment;}
}

public class NoteListFragment extends BaseFragment {@Overrideprotected int getFragmentLayout() {return R.layout.fragment_note_list;}@Overrideprotected void initFragmentData() {}@Overrideprotected void initFragmentListener() {}@Overrideprotected void initFragmentView() {}
}

接下来我们还需要添加NoteListFragment 对应的布局文件fragment_note_list:

"1.0" encoding="utf-8"?>
xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical">

ok,此时我们运行程序,界面是一片空白什么都没有显示。

我们要显示的是日记的列表,所以这里我们推荐使用目前功能更为齐全的recyclerview。

第一步如同添加Gson一样,添加recyclerview的依赖,这里选择androids.recycleview.网上不少教程还是会推荐大家使用v7支持包,android推出的androidx我还是作为首选项,当然了选择v7也可以的。

在Android Studio中添加recycleview

在这里插入图片描述

我们不会详细去介绍recyclerview的具体内容,这里我们就开发中的简单使用为例来实现我们的项目。如果需要更为细致的教程,请大家自行查阅,更高级的使用如果遇到我们在做解释。

在布局文件中使用recycleview

在我们的fragment_note_list.xml使用recycleview很简单:

xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_marginTop="16dp"android:layout_marginBottom="16dp"tools:context=".fragment.NoteListFragment">android:id="@+id/note_recycle_view"android:layout_width="match_parent"android:layout_height="match_parent"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" />

这里我们为我们的RecyclerView 添加id方便后续的使用。

RecyclerView视图与fragment 关联

NoteListFragment.java:
定义变量:

private RecyclerView recyclerView;private RecyclerView.Adapter adapter;private RecyclerView.LayoutManager layoutManager;

关联RecyclerView视图

@Override@Overrideprotected void initFragmentView() {//获取recyclerView组件recyclerView = fragmentRoot.findViewById(R.id.note_recycle_view);//使用布局管理器layoutManager = new LinearLayoutManager(getActivity());recyclerView.setLayoutManager(layoutManager);//指定适配器adapter = new NoteListAdapter();recyclerView.setAdapter(adapter);}

其中android为我们提供了常见的三种布局管理器:


1、LinearLayoutManager 线性布局管理器,支持横向、纵向。

2、 GridLayoutManager 网格布局管理器

3、 StaggeredGridLayoutManager 瀑布流式布局管理器


到这里我们的准备工作还没有完成,首先呢还得准备一个列表内容怎么显示的布局文件note_list_item.xml:

xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="wrap_content">android:id="@+id/tv_note_title"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="8dp"android:textStyle="bold"app:layout_constraintTop_toTopOf="parent" />android:id="@+id/tv_note_content"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="8dp"app:layout_constraintTop_toBottomOf="@id/tv_note_title" />android:id="@+id/tv_note_create_date"android:layout_width="match_parent"android:layout_height="wrap_content"android:textAlignment="viewEnd"app:layout_constraintTop_toBottomOf="@id/tv_note_content" />

讲述的有些乱,不过呢基本上按着流程走的,见谅。

为RecyclerView准备适配器

新建NoteListAdapter类,让这个适配器继承RecyclerView.Adapter,并为其指定泛型为NoteListAdapter.ViewHolder.其中ViewHolder为NoteListAdapter的一个内部类。

在这里插入图片描述


public class NoteListAdapter extends RecyclerView.Adapter<NoteListAdapter.ViewHolder> {private List<NoteItem> noteItemList;/*** 通过构造函数传入数据源* &#64;param noteItems 数据源*/public NoteListAdapter(List<NoteItem> noteItems) {noteItemList &#61; noteItems;}/*** 创建ViewHolder实例* &#64;param parent* &#64;param viewType* &#64;return*/&#64;NonNull&#64;Overridepublic ViewHolder onCreateViewHolder(&#64;NonNull ViewGroup parent, int viewType) {View view &#61; LayoutInflater.from(parent.getContext()).inflate(R.layout.note_list_item, parent, false);ViewHolder holder &#61; new ViewHolder(view);return holder;}/*** 对RecyclerView子项进行赋值* &#64;param holder* &#64;param position 当前数据项索引*/&#64;Overridepublic void onBindViewHolder(&#64;NonNull ViewHolder holder, int position) {NoteItem noteItem &#61; noteItemList.get(position);holder.noteTitle.setText(noteItem.getNoteTitle());holder.noteContent.setText(noteItem.getNoteContent());holder.noteCreateDate.setText(noteItem.getDateCreate().toString());}/*** 获取数据项大小* &#64;return*/&#64;Overridepublic int getItemCount() {return noteItemList.size();}/*** 构造函数需要传入view参数&#xff0c;通常为RecyclerView子项的最外层布局&#xff0c;这里就是note_list_item*/static class ViewHolder extends RecyclerView.ViewHolder {TextView noteTitle;TextView noteContent;TextView noteCreateDate;public ViewHolder(&#64;NonNull View itemView) {super(itemView);noteTitle &#61; itemView.findViewById(R.id.tv_note_title);noteContent &#61; itemView.findViewById(R.id.tv_note_content);noteCreateDate &#61; itemView.findViewById(R.id.tv_note_create_date);}}
}

前面我们已经将NoteListFragment.java中关联RecyclerView的代码在initFragmentView方法中已经写过了&#xff0c;这里在来完善下。

首先导入NoteListAdapter&#xff0c;然后为适配器准备数据。

由于我们的日记列表和创建日记的页面还没有整合在一块&#xff0c;所以这里我们先简单模拟下数据。

public class NoteListFragment extends BaseFragment {private RecyclerView recyclerView;private RecyclerView.Adapter adapter;private RecyclerView.LayoutManager layoutManager;> private List<NoteItem> noteItemList &#61; new ArrayList<>();&#64;Overrideprotected int getFragmentLayout() {return R.layout.fragment_note_list;}&#64;Override> protected void initFragmentData() {
>
> for (int i &#61; 0; i < 20; i&#43;&#43;) {
>
> NoteItem noteItem &#61; new NoteItem();
> noteItem.setNoteTitle("标题".concat(String.valueOf(i)));
> noteItem.setNoteContent("内容".concat(String.valueOf(i)));
> noteItem.setDateCreate(new Date());
> noteItemList.add(noteItem);
> }
> }&#64;Overrideprotected void initFragmentListener() {}&#64;Overrideprotected void initFragmentView() {//获取recyclerView组件recyclerView &#61; fragmentRoot.findViewById(R.id.note_recycle_view);//使用布局管理器layoutManager &#61; new LinearLayoutManager(getActivity());recyclerView.setLayoutManager(layoutManager);//指定适配器> adapter &#61; new NoteListAdapter(noteItemList);recyclerView.setAdapter(adapter);}
}

运行程序&#xff1a;
在这里插入图片描述
好了&#xff0c;到此为止我们就实现了一个最简单的RecyclerView展示列表。

不知道大家有没有注意到,我们在initFragmentView中使用了noteItemList数据&#xff0c;但是该数据却在initFragmentData被初始化&#xff0c;我们看看父类中的顺序
在这里插入图片描述
虽然我们的列表显示出来了&#xff0c;但是将一些基础数据的初始化放在组件初始化之前更为符合逻辑&#xff0c;所以我们修改一下两者的顺序&#xff0c;同理还有BaseActivity中的代码。


推荐阅读
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了brain的意思、读音、翻译、用法、发音、词组、同反义词等内容,以及脑新东方在线英语词典的相关信息。还包括了brain的词汇搭配、形容词和名词的用法,以及与brain相关的短语和词组。此外,还介绍了与brain相关的医学术语和智囊团等相关内容。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 推荐系统遇上深度学习(十七)详解推荐系统中的常用评测指标
    原创:石晓文小小挖掘机2018-06-18笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值, ... [详细]
  • Android JSON基础,音视频开发进阶指南目录
    Array里面的对象数据是有序的,json字符串最外层是方括号的,方括号:[]解析jsonArray代码try{json字符串最外层是 ... [详细]
author-avatar
宋紫紫云__
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有