# HarmonyOS应用开发--基于TextField和Image伪富文本的MyNotePad[便签][API V6]
# 1. 名称
将本次app命名为:MyNotePad、我的笔记本,app图标采用默认图标,设置app名称即可。
项目已经放置在gitee中:[MyNotePad](https://gitee.com/tdtxyzhh/harmonyos-applicationset/tree/master/MyNotepad)
# 2. 功能描述
- 对于鸿蒙应用开发API V6来说可能还不具备富文本组件,翻阅有关的文档富文本组件的函数一些要到AP1 V8才生效,再网上也没有找到有关于富文本的api鸿蒙组件用法。因此,决定使**用TextField和Image两大组件以及ScrollView组件去模拟一个富文本组件,称为伪富文本**。
- 具有便签笔记编辑功能,可以编辑文本,还可以插入图片,最后**保存在应用沙盒的存储空间中**。
- 在编辑时,**在输入框向左滑动,在其右边侧显示一个删除按钮;向右滑动,则隐藏这个删除按钮**。**实现了这一安卓手机常见的便捷功能**。当然,还可以长按文本输入框或图片进行删除。
- 实现了从系统相册或文件中选取图片,然后进行解码操作,显示到Image组件中。实现了在保存时,将已经解码的图片再编码保存在应用沙盒创建的文件夹中。
- 实现了**对应用沙盒存储的读取与写入操作**。
- 实现了创建一系列文件夹,并通过设计好的存储结构,生成文件目录的结构,方便存储或读取时直接获取文件的File变量调用。
- 在使用ListContainer展示笔记列表时候,**上滑笔记列表,则会隐藏上部区域扩大列表竖向范围,下滑笔记列表,则会显示原有功能区域,实现了现在app创建的功能操作**。
- **在点击“选择”后,会在笔记列表每个条目的左侧出现一个点击选择的区域,若是选中,则显示一个绿色的对号,若是不想选中,则不显示绿色对号,实现了现在app创建的列表条目删除管理功能。**
- 实现了**通过关键句子搜索匹配的笔记功能**,如果有,则直接加载该笔记,进入编辑页面。如果没有,则显示toast提示文字!
# 3. app实现关键技巧
## 3.1 滑动笔记列表更改显示空间、左滑笔记条目显示删除按键右滑消失
![在这里插入图片描述](https://img-blog.csdnimg.cn/8421094cc00a4971bc7380c91fd60f24.gif#pic_center)
实现技巧:
- 当上滑笔记列表时,触发触摸事件,判断出是在上滑,则让上部的布局容器组件设为HIDE,此时上部不占用空间,则就扩大了列表竖向显示空间。当下滑列表时候,判断出是在下滑,则让上部的布局容器组件设为VISIBLE,则就达到还原的目的。
- 当在某个笔记条目上左滑时候,触发触摸事件,判断出是在左滑,则将最右侧的红色“删除”按钮设置为VISIBLE。当向右滑动时,将其设置为HIDE,即可实现这一常见的删除效果。
## 3.2 点击“选择”每个笔记条目左侧出现选定框、同时下方显示“取消”与“删除”
![在这里插入图片描述](https://img-blog.csdnimg.cn/c8d72f1cdd5d4ce9b89acc59beaa2dda.gif#pic_center)
实现技巧:
- ListContainer的子布局是复用的、动态加载的,在编写子布局XML中,让其左侧的点击选择Text默认设置为HIDE,当用户点击“选择”时,会遍历ListContainer目前已经加载的所有Component,然后将其每个左侧的点击选择框设置为VISABLE即可。
- 当点击“取消”时候,同样按照上述的遍历方法,将每个点选框设置为HIDE,Text的文本设置为“N”,文本颜色设置为WHIE。
- 如果点击的某个点选框此时的文本是“N”,则将其文本设置为“✔”,文本颜色设置为“GREEN”;如果点击的某个点选框此时的文本是“✔”,则Text的文本设置为“N”,文本颜色设置为WHIE。即可达到点击之后,出现选择或不选则的效果。
- 点击“删除”是,会遍历ListContainer此时已经加载的组件,当其左侧点选框文本内容是“✔”,通过ListContainer的数据源列表(一个泛型ArrayList)获取该笔记所在文件夹的File变量,然后将该文件夹中的所有文件通过遍历的方法删除,最后,从该数据源列表中去除该项数据,最后刷新ListContainer即可。
-
## 3.3 搜索功能
![在这里插入图片描述](https://img-blog.csdnimg.cn/4cb1467bcbbe4d268957faf0b8472058.gif#pic_center)
实现技巧:
- 遍历此时ListContainer中所有的笔记简略文本,通过使用indexOf(搜索输入框的文本)判断有没有匹配的笔记条目,如果有则直接打开该笔记,如果没有,则显示Toast提示。
## 3.4 伪富文本编辑功能(文本和图片)
![在这里插入图片描述](https://img-blog.csdnimg.cn/0ec635a027cf49af95d5119d75c80631.gif#pic_center)
实现技巧:
- 首先需要有一个ScrollView组件,然后需要根据需要动态的往里面增加TextField或Image组件,并且会有一个recordlist(一个泛型ArrayList)记录当前编辑区域的组件顺序(以便存储数据时按照此顺序编制文件名、读取数据时按照此文件名顺序恢复),即可实现“ 伪富文本”功能。期待后续API推出的富文本组件!
- 点击“保存”,会首先判断第一个文本输入框中是否为空,如果不为空则保存,为空则显示Toast提示。保存时,需要遍历recordlist中的每项,按照每项中的组件类型标识,如果是TextField则按照文本文件的存储方法,使用相应的流处理存储,如果是Image则需要将其先进行编码操作同时构建目标文件将其打包进去。此时记录保存状态为true。
## 3.5 获取笔记文件夹的目录结构(重要操作)(存储在该应用沙盒中,而非外部该应用私有存储)
**本便签的文件夹组织结构示意图如下:**
![在这里插入图片描述](https://img-blog.csdnimg.cn/8b68f46296e341ceb93869f70c6bfd88.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAVERUWA==,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
自动获取每天的日期,创建每日文件夹dayfolder,其中的文件夹则是该日按照编辑顺序每条笔记的文件夹thisnotefolder,在该文件夹中,按照recordlist所记录的组件顺序,给文件命名,进行存储。如果当日文件夹中已经有两个文件,那么该日第三个笔记要存储的文件夹名称会顺序递增(使用dayfolder.list().length+1)
【生成usernote文件夹目录结构】**使用一个ArrayList泛型列表(ArrayList 《StructFile》 dayfolders = new ArrayList<>()),其中该类型的类StructFile中有两个变量,其中一个变量File dayfile用来保存某日文件夹的File,另一个变量File[ ] dayfile_notelistfiles用来保存该日文件夹中的所有笔记File**。这样就生成了usernote文件夹的结构,把所有文件夹的“把柄”都捏在了手中,便于操作!**示意图如下:**
![在这里插入图片描述](https://img-blog.csdnimg.cn/3dbb8de6c26c4556ac301bc5920c116f.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAVERUWA==,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
# 4. 源代码
## 4.0 工程源文件目录结构
![在这里插入图片描述](https://img-blog.csdnimg.cn/12e4bd0594a949fd91a651254a2399cc.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAVERUWA==,size_18,color_FFFFFF,t_70,g_se,x_16#pic_center)
## 4.1 Java源代码
### 4.1.1 NoteListItem.java
```java
package com.tdtxdcxm.mynotepad.listcontaineritem;
import java.io.File;
public class NoteListItem {
private String text = null;
private File file = null;
private String notedate = null;
public NoteListItem(String text,File file) {
this.text = text;
this.file = file;
getNoteDate();
}
public String getText() {
return text;
}
public File getFile() {
return file;
}
public String getNoteDate() {
System.out.println("getNote file:"+file);
if(file != null){
notedate = file.getParentFile().getName();
}
return notedate;
}
public String getShortText(){
getNoteDate();
System.out.println("getshorttext检查:"+text+","+notedate+","+file.toString());
if(text != null && notedate != null && file != null){
return notedate+"\n"+text;
}
return "error";
}
}
```
### 4.1.2 NoteDataManager.java
```java
package com.tdtxdcxm.mynotepad.notedata;
import com.tdtxdcxm.mynotepad.listcontaineritem.NoteListItem;
import com.tdtxdcxm.mynotepad.notedetails.NoteDetailInfoList;
import ohos.aafwk.ability.AbilitySlice;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import java.io.*;
import java.util.ArrayList;
class StructFile{
private File dayfile = null;
private File[] dayfile_notelistfiles = null;
public File getDayfile() {
return dayfile;
}
public File[] getDayfile_notelistfiles() {
return dayfile_notelistfiles;
}
public StructFile(File dayfile) {
this.dayfile = dayfile;
this.dayfile_notelistfiles = dayfile.listFiles();
}
}
public class NoteDataManager {
public static File usernote = new File("/data/user/0/com.tdtxdcxm.mynotepad/usernote");
public static ArrayList<StructFile> dayfolders = new ArrayList<>();
public static boolean isgenerate = false;
public static void generateUserNoteDir(){
dayfolders.clear();
File[] usernotelistfiles = usernote.listFiles();
if(usernotelistfiles != null){
for(int i = 0;i < usernotelistfiles.length;i++){
dayfolders.add(new StructFile(usernotelistfiles[i]));
}
isgenerate = true;
}
else{
isgenerate = false;
}
}
public static void checkUserNoteDir(){
System.out.println(usernote.toString()+"开始输出usernote文件夹中全部目录结构:--《《");
for(int i = 0;i < dayfolders.size();i++){
System.out.println(dayfolders.get(i).getDayfile().toString()+":--{");
File[] files = dayfolders.get(i).getDayfile_notelistfiles();
for(int j = 0;j < files.length;j++){
System.out.println(files[j].toString());
}
System.out.println(dayfolders.get(i).getDayfile().toString()+":--}");
}
System.out.println(usernote.toString()+"输出usernote文件夹中全部目录结构完成!--》》");
}
public static void isUserNoteExist(){
if(usernote.exists()){
System.out.println("usernote is 存在!");
return;
}
System.out.println("usernote is 不存在!");
}
public static void readAllNoteMataForList(ArrayList<NoteListItem> listcontainerItems){
listcontainerItems.clear();//确保是空列表
for(int i = 0;i < dayfolders.size();i++){
File[] files = dayfolders.get(i).getDayfile_notelistfiles();
for(int j = 0;j < files.length;j++){
File[] detailsfiles = files[j].listFiles();
if(detailsfiles.length != 0){
try{
BufferedReader bufferedReader = new BufferedReader( new InputStreamReader( new FileInputStream(detailsfiles[0]) ));
StringBuilder stringBuilder = new StringBuilder();
String t = null;
while ((t = bufferedReader.readLine()) != null) {
stringBuilder.append(t);
}
System.out.println(stringBuilder.toString());
listcontainerItems.add(new NoteListItem(stringBuilder.toString(),files[j]));
bufferedReader.close();
}
catch (FileNotFoundException e){
e.printStackTrace();
}
catch (IOException e){
e.printStackTrace();
}
}
}
}
for(int i = 0;i < listcontainerItems.size();i++){
System.out.println("检查listcontaineritem列表内容:"+listcontainerItems.get(i).getShortText());
}
}
public static ImageSource.SourceOptions sourceOptions(){
ImageSource.SourceOptions options = new ImageSource.SourceOptions();
options.formatHint = "image/jpeg";
return options;
}
public static ArrayList<NoteDetailInfoList> readSomeNoteDetails(File file, AbilitySlice abilitySlice){
System.out.println("readSomeNoteDetails检查file-------->>"+file);
ArrayList<NoteDetailInfoList> noteDetailInfoLists = new ArrayList<>();
File[] files = file.listFiles();
for(int i = 0;i < files.length;i++){
if(files[i].getName().endsWith("txt")){
try{
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(files[i])));
StringBuilder stringBuilder = new StringBuilder();
String t = null;
while ((t = bufferedReader.readLine()) != null) {
stringBuilder.append(t);
}
System.out.println(stringBuilder.toString());
noteDetailInfoLists.add(new NoteDetailInfoList(stringBuilder.toString(),file,0));
bufferedReader.close();
}
catch (FileNotFoundException e){
e.printStackTrace();
}
catch (IOException e){
e.printStackTrace();
}
}
if(files[i].getName().endsWith("jpeg")){
try{
FileInputStream fileInputStream = new FileInputStream(files[i]);
ImageSource imageSource = ImageSource.create(fileInputStream.getFD(),sourceOptions());
PixelMap pixelMap = imageSource.createPixelmap(null);
fileInputStream.close();
noteDetailInfoLists.add(new NoteDetailInfoList(pixelMap,file,1));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return noteDetailInfoLists;
}
public static File deleteFolderFiles(File folder){
//删除某文件夹中的所有文件
File[] filelist = folder.listFiles();
for(int i = 0;i < filelist.length;i++){
try
{
filelist[i].delete();
}
catch (SecurityException e){
e.printStackTrace();
}
}
return folder;
}
private NoteDataManager(){
}
}
```
### 4.1.3 NoteDetailInfoList.java
```java
package com.tdtxdcxm.mynotepad.notedetails;
import java.io.File;
public class NoteDetailInfoList {
public final String[] typename = {"TextField","Image"};
public int type = -1;
//会保存String或PixelMap的引用,使用时根据type强制类型转换即可!
public Object object = null;
public File thisnotefoldername = null;
public String getName(){
if(type == 0 || type == 1){
return typename[type];
}
return null;
}
public Object getObject() {
return object;
}
public File getThisnotefoldername() {
return thisnotefoldername;
}
public NoteDetailInfoList(Object object, File thisnotefoldername, int type) {
this.object = object;
this.thisnotefoldername = thisnotefoldername;
this.type = type;
}
}
```
### 4.1.4 NoteListItemProvider.java
```java
package com.tdtxdcxm.mynotepad.provider;
import com.tdtxdcxm.mynotepad.ResourceTable;
import com.tdtxdcxm.mynotepad.listcontaineritem.NoteListItem;
import com.tdtxdcxm.mynotepad.notedata.NoteDataManager;
import ohos.aafwk.ability.AbilitySlice;
import ohos.agp.components.*;
import ohos.agp.utils.Color;
import ohos.multimodalinput.event.MmiPoint;
import ohos.multimodalinput.event.TouchEvent;
import java.util.List;
public class NoteListItemProvider extends BaseItemProvider {
private float x1 = 0,x2 = 0,y1 = 0,y2 = 0;
private List<NoteListItem> list;
private AbilitySlice slice;
public static NoteListItemProvider noteListItemProvider = null;
public static DirectionalLayout main_rootdl_ddl1 = null;
public NoteListItemProvider(List<NoteListItem> list,AbilitySlice slice) {
this.list = list;
this.slice = slice;
}
@Override
public int getCount() {
return list != null?list.size():0;
}
@Override
public Object getItem(int i) {
if(list == null || (i < 0 || i >= list.size())){
return null;
}
return list.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public Component getComponent(int i, Component component, ComponentContainer componentContainer) {
final Component cmpt;
if(component == null){
cmpt = LayoutScatter.getInstance(slice).parse(ResourceTable.Layout_main_listcontainer_itemlayout,null,false);
}
else{
cmpt = component;
}
NoteListItem noteListItem = list.get(i);
Text selecttxt = (Text) cmpt.findComponentById(ResourceTable.Id_item_selecttxt);
selecttxt.setText("N");
selecttxt.setTextColor(Color.WHITE);
selecttxt.setVisibility(Component.HIDE);
Text text = (Text) cmpt.findComponentById(ResourceTable.Id_item_text);
text.setText(noteListItem.getShortText());
NoteListItemProvider.noteListItemProvider = this;
Button button = (Button) cmpt.findComponentById(ResourceTable.Id_item_deletebut);
button.setVisibility(Component.HIDE);
selecttxt.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
System.out.println("selecttxt is["+selecttxt.getText()+"]");
if(selecttxt.getText().equals("N")){
selecttxt.setText("✔");
selecttxt.setTextColor(Color.GREEN);
return;
}
if(selecttxt.getText().equals("✔")){
selecttxt.setText("N");
selecttxt.setTextColor(Color.WHITE);
return;
}
}
});
text.setTouchEventListener(new Component.TouchEventListener() {
@Override
public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
int action = touchEvent.getAction();
if(action == TouchEvent.PRIMARY_POINT_DOWN){
MmiPoint mmiPoint = touchEvent.getPointerPosition(0);
x1 = mmiPoint.getX();
y1 = mmiPoint.getY();
}
if(action == TouchEvent.PRIMARY_POINT_UP){
MmiPoint mmiPoint = touchEvent.getPointerPosition(0);
x2 = mmiPoint.getX();
y2 = mmiPoint.getY();
if(x1 < x2 && Math.abs(y2 - y1) <= 90.0){
button.setVisibility(Component.HIDE);
}
if(x1 > x2 && Math.abs(y2 - y1) <= 90.0){
button.setVisibility(Component.VISIBLE);
}
if(y1 > y2 && Math.abs(x2 - x1) <= 90.0){
main_rootdl_ddl1.setVisibility(Component.HIDE);
}
if(y1 < y2 && Math.abs(x2 - x1) <= 90.0){
main_rootdl_ddl1.setVisibility(Component.VISIBLE);
}
}
return true;
}
});
button.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
System.out.println("list.get(i).getFile() is"+list.get(i).getFile());
NoteDataManager.deleteFolderFiles(list.get(i).getFile());
list.remove(i);
NoteListItemProvider.this.notifyDataChanged();
}
});
return cmpt;
}
}
```
### 4.1.5 RecordComponentItem.java
```java
package com.tdtxdcxm.mynotepad.record;
import ohos.agp.components.Component;
public class RecordComponentItem {
public final String[] typename = {"TextField","Image"};
public Component component;
public int type = -1;
public RecordComponentItem(Component component, int type) {
this.component = component;
this.type = type;
}
public String getName() {
return "{"+type+":"+typename[type]+"}";
}
}
```
### 4.1.6 EditAbilitySlice.java
```java
package com.tdtxdcxm.mynotepad.slice;
import com.tdtxdcxm.mynotepad.ResourceTable;
import com.tdtxdcxm.mynotepad.notedata.NoteDataManager;
import com.tdtxdcxm.mynotepad.notedetails.NoteDetailInfoList;
import com.tdtxdcxm.mynotepad.record.RecordComponentItem;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.ability.DataAbilityHelper;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.components.*;
import ohos.agp.utils.LayoutAlignment;
import ohos.agp.window.dialog.CommonDialog;
import ohos.agp.window.dialog.IDialog;
import ohos.agp.window.dialog.ToastDialog;
import ohos.media.image.ImagePacker;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.photokit.metadata.AVStorage;
import ohos.multimodalinput.event.MmiPoint;
import ohos.multimodalinput.event.TouchEvent;
import ohos.utils.net.Uri;
import java.io.*;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
public class EditAbilitySlice extends AbilitySlice {
private File thisnotefoldername;//保存正在编辑笔记到某个文件夹,该文件夹的File实例
private float x1,x2,y1,y2;
//用于记录当前编辑笔记的组件顺序。例如:当前编辑区域按顺序有一个输入框-图片-图片-输入框,则recordlist按此顺序记录。
private ArrayList<RecordComponentItem> recordlist = new ArrayList<>();
private DirectionalLayout edit_rootdl,edit_rootdl_ddl3;
private Button edit_rootdl_ddl1_1_nobut,edit_rootdl_ddl1_1_savebut;
private ScrollView edit_rootdl_ddl2_scrollview;
private DirectionalLayout edit_rootdl_ddl2_scrollview_ddl;
private TextField ddl2_scrollview_ddl_solidtfd;
private Button edit_rootdl_ddl3_clearbut,edit_rootdl_ddl3_wantimagebut;
boolean isgetimage = false;//判断是否成功从相册或文件夹中获取到图片文件
boolean issave = false;//判断是不是第一次保存,如果是第一次保存该笔记内容,则首先生成一个文件夹,该文件中将存放文本和图片文件
boolean issavebutpress = false;//判断笔记内容变化后,是否点击了保存按钮;笔记内容变化:各个文本输入框内容变化、图片的插入或删除、输入框的插入或删除
public void checkPrintlnRecordList() {
for(int j = 0;j < recordlist.size();j++){
if(j == 0){
System.out.println("开始检查recordlist值:");
}
if(j == recordlist.size() - 1){
System.out.println(j+"----->>>"+recordlist.get(j).getName());
System.out.println("检查recordlist值完成!");
continue;
}
System.out.println(j+"----->>>"+recordlist.get(j).getName());
}
}
public void clearRecordListComponents(){
for(int i = 1;i < recordlist.size();i++){
edit_rootdl_ddl2_scrollview_ddl.removeComponent(recordlist.get(i).component);
}
recordlist.clear();
recordlist.add(new RecordComponentItem(edit_rootdl_ddl2_scrollview_ddl,0));
checkPrintlnRecordList();
}
private void selectPicture(){
//参照教程
Intent intent = new Intent();
Operation operation = new Intent.OperationBuilder()
.withAction("android.intent.action.GET_CONTENT")
.build();
intent.setOperation(operation);
intent.addFlags(Intent.FLAG_NOT_OHOS_COMPONENT);
intent.setType("image/*");
startAbilityForResult(intent,9);
}
@Override
public void onAbilityResult(int requestCode, int resultCode, Intent resultData){
//参照教程修改
if(resultData == null){
isgetimage = false;
return;
}
if(requestCode == 9){
DirectionalLayout directionalLayout = getNewImage();
String chooseImgUri=resultData.getUriString();
DataAbilityHelper helper=DataAbilityHelper.creator(this.getContext());
ImageSource imageSource = null;
String chooseImgId=null;
if(chooseImgUri.lastIndexOf("%3A")!=-1){
chooseImgId = chooseImgUri.substring(chooseImgUri.lastIndexOf("%3A")+3);
}
else {
chooseImgId = chooseImgUri.substring(chooseImgUri.lastIndexOf('/')+1);
}
Uri uri=Uri.appendEncodedPathToUri(AVStorage.Images.Media.EXTERNAL_DATA_ABILITY_URI,chooseImgId);
try {
FileDescriptor fd = helper.openFile(uri, "r");
imageSource = ImageSource.create(fd, null);
PixelMap pixelMap = imageSource.createPixelmap(null);
((Image)directionalLayout.getComponentAt(0)).setPixelMap(pixelMap);
System.out.println("isgetimage is :"+isgetimage);
edit_rootdl_ddl2_scrollview_ddl.addComponent(directionalLayout);
recordlist.add(new RecordComponentItem(directionalLayout,1));
directionalLayout = getNewTextField();
edit_rootdl_ddl2_scrollview_ddl.addComponent(directionalLayout);
recordlist.add(new RecordComponentItem(directionalLayout,0));
isgetimage = false;
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if (imageSource != null) {
imageSource.release();
}
}
}
}
public void toastShow(String s){
ToastDialog toastDialog = new ToastDialog(this.getContext());
toastDialog.setText(s);
toastDialog.setTransparent(true);
toastDialog.setDuration(100);
toastDialog.setAlignment(LayoutAlignment.CENTER);
toastDialog.show();
}
public void commonDialogRemoveShow(String title,String content,Component component){
CommonDialog commonDialog = new CommonDialog(this.getContext());
commonDialog.setTitleText(title);
commonDialog.setContentText(content);
commonDialog.setSize(500,400);
commonDialog.setButton(1, "确认", new IDialog.ClickedListener() {
@Override
public void onClick(IDialog iDialog, int i) {
int index = component.getComponentParent().getChildIndex(component);
component.getComponentParent().removeComponent(component);
recordlist.remove(index);
checkPrintlnRecordList();//检查recordlist列表的值
issavebutpress = false;//输入框发生删除,则视为笔记内容发生变化,将issavebutpress立即置为false
commonDialog.destroy();
}
});
commonDialog.setButton(2, "取消", new IDialog.ClickedListener() {
@Override
public void onClick(IDialog iDialog, int i) {
commonDialog.destroy();
}
});
commonDialog.show();
}
public DirectionalLayout getNewTextField(){
DirectionalLayout directionalLayout = (DirectionalLayout) LayoutScatter.getInstance(this.getContext()).parse(ResourceTable.Layout_edit_textfield_sublayout,null,false);
TextField textField= (TextField) directionalLayout.getComponentAt(0);
Button button = (Button) directionalLayout.getComponentAt(1);
button.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
commonDialogRemoveShow("文本删除提示","是否删除所指内容?",directionalLayout);
}
});
textField.addTextObserver(new Text.TextObserver() {
@Override
public void onTextUpdated(String s, int i, int i1, int i2) {
issavebutpress = false;//一旦检查到文本输入框内容发生变化,则立即将issavebutpress置为false
}
});
textField.setTouchEventListener(new Component.TouchEventListener() {
@Override
public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
if(touchEvent.getAction() == TouchEvent.PRIMARY_POINT_DOWN){
MmiPoint mmiPoint = touchEvent.getPointerPosition(0);
x1 = mmiPoint.getX();
y1 = mmiPoint.getY();
}
if(touchEvent.getAction() == TouchEvent.PRIMARY_POINT_UP){
MmiPoint mmiPoint = touchEvent.getPointerPosition(0);
x2 = mmiPoint.getX();
y2 = mmiPoint.getY();
if(x1 > x2 && Math.abs(y1 - y2) <= 100){
button.setVisibility(Component.VISIBLE);
}
if(x1 < x2 && Math.abs(y1 - y2) <= 100){
button.setVisibility(Component.HIDE);
}
}
return true;
}
});
textField.setLongClickedListener(new Component.LongClickedListener() {
@Override
public void onLongClicked(Component component) {
commonDialogRemoveShow("文本删除提示","是否删除所指内容?",directionalLayout);
}
});
return directionalLayout;
}
public DirectionalLayout getNewImage(){
DirectionalLayout directionalLayout = (DirectionalLayout) LayoutScatter.getInstance(this.getContext()).parse(ResourceTable.Layout_edit_image_sublayout,null,false);
Image image = (Image) directionalLayout.getComponentAt(0);
System.out.println("-------------->"+image);
directionalLayout.setLongClickedListener(new Component.LongClickedListener() {
@Override
public void onLongClicked(Component component) {
commonDialogRemoveShow("图片删除提示","是否删除所指图片?",directionalLayout);
issavebutpress = false;//一旦图片从文本中删除,则视为笔记内容发生变化,立即将issavebutpress置为false
}
});
image.setLongClickedListener(new Component.LongClickedListener() {
@Override
public void onLongClicked(Component component) {
commonDialogRemoveShow("图片删除提示","是否删除所指图片?",directionalLayout);
issavebutpress = false;//一旦图片从文本中删除,则视为笔记内容发生变化,立即将issavebutpress置为false
}
});
return directionalLayout;
}
public void encodeAndSaveImage(PixelMap pixelMap,File thisnotefoldername,int orderfilename){
ImagePacker imagePacker = ImagePacker.create();
String filepath = Paths.get(thisnotefoldername.toString(),orderfilename+".jpeg").toString();
File targetfile = new File(filepath);
try
{
FileOutputStream fileOutputStream = new FileOutputStream(targetfile);
ImagePacker.PackingOptions packingOptions = new ImagePacker.PackingOptions();
packingOptions.format = "image/jpeg";
packingOptions.numberHint=1;
packingOptions.quality = 100;
imagePacker.initializePacking(fileOutputStream,packingOptions);
imagePacker.addImage(pixelMap);
imagePacker.finalizePacking();
fileOutputStream.close();
}
catch (FileNotFoundException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void saveTextField(File thisnotefoldername,TextField textField,int index){
File file = new File(thisnotefoldername.toString()+"/"+index+".txt");
try
{
FileOutputStream fileOutputStream = new FileOutputStream(file);
fileOutputStream.write(textField.getText().getBytes());
fileOutputStream.flush();
fileOutputStream.close();
}
catch (FileNotFoundException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void showDir(){
String DatabaseDir = this.getDatabaseDir().toString();
String PreferencesDir = this.getPreferencesDir().toString();
File DataDirfile = new File(this.getDataDir().toString()+"/usernote");
DataDirfile.mkdir();//创建usernote文件夹
NoteDataManager.isUserNoteExist();
String noteeach = DataDirfile.toString();
System.out.println("新建的笔记记录文件夹路径:"+noteeach);
String DataDir = this.getDataDir().toString();
String CacheDir = this.getCacheDir().toString();
String CodeCacheDir = this.getCodeCacheDir().toString();
String FilesDir = this.getFilesDir().toString();
//String ExternalCacheDir = this.getExternalCacheDir().toString();
//String ExternalFilesDir = this.getExternalFilesDir("hello").toString();
File file = null;
/*
file = new File(this.getExternalCacheDir().getParent().toString()+"/want");
try
{
file.mkdir();
}
catch (Exception e){
e.printStackTrace();
}
*/
file = new File(this.getExternalCacheDir().getParent());
String ss = file.toString();
System.out.println("ss--->>>"+ss);
String[] slist = file.list();
for(int i = 0;i < slist.length;i++){
System.out.println("------->>>>>>"+slist[i]);
}
/*
System.out.println("-----------------------------------------------");
slist = this.getExternalCacheDir().list();
System.out.println("slist.size():"+slist.length);
for(int i = 0;i < slist.length;i++){
System.out.println("------->>>>>>"+slist[i]);
}
System.out.println("外部应用私有ExternalCacheDir-->>"+ExternalCacheDir);
System.out.println("外部应用私有ExternalFilesDir-->>"+ExternalFilesDir);
System.out.println("-----------------------------------------------");
*/
System.out.println("开始输出文件目录检查:");
System.out.println("数据库DatabaseDir-->>"+DatabaseDir);
System.out.println("偏好键值对数据库PreferencesDir-->>"+PreferencesDir);
System.out.println("沙盒DataDir-->>"+DataDir);
System.out.println("沙盒CacheDir-->>"+CacheDir);
System.out.println("沙盒CodeCacheDir-->>"+CodeCacheDir);
System.out.println("沙盒FilesDir-->>"+FilesDir);
System.out.println("输出文件目录检查完成!");
}
public File createThisNoteFolder(){
File file;
Date date = new Date();//获取点击保存按钮时的时间
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");//对该时间按照“年月日”格式化
String todayfoldername = simpleDateFormat.format(date);//将格式化后的日期字符串当作今日文件夹名称
System.out.println("当前日期为---》"+todayfoldername);
file = new File(this.getDataDir().toString()+"/usernote/"+todayfoldername);//获取当日文件夹的File实例
if(file.exists() == false){
//如果当日文件夹不存在,则说明用户今天第一次使用软件点击保存按钮,则需要创建当日文件夹
file.mkdir();//创建该文件夹
}
String thisnotefoldername = file.toString()+"/"+String.valueOf(file.list().length+1);//给本次笔记命名一个文件夹名称
System.out.println("thisnotefoldername-->>"+thisnotefoldername);
file = new File(thisnotefoldername);//获得本次笔记文件夹File实例
file.mkdir();//创建该文件夹,在当日文件夹中放置
File check_usernote_folderlist = new File(this.getDataDir().toString()+"/usernote");
String[] usernotelist = check_usernote_folderlist.list();
for(int i = 0;i < usernotelist.length;i++){
System.out.println("-------check usernote>>>>>>"+usernotelist[i]);
}
return file;
}
public void initEASliceComponents(){
edit_rootdl = (DirectionalLayout) findComponentById(ResourceTable.Id_edit_rootdl);
edit_rootdl_ddl1_1_nobut = (Button) findComponentById(ResourceTable.Id_edit_rootdl_ddl1_1_nobut);
edit_rootdl_ddl1_1_savebut = (Button) findComponentById(ResourceTable.Id_edit_rootdl_ddl1_1_savebut);
edit_rootdl_ddl2_scrollview = (ScrollView) findComponentById(ResourceTable.Id_edit_rootdl_ddl2_scrollview);
edit_rootdl_ddl2_scrollview_ddl = (DirectionalLayout) findComponentById(ResourceTable.Id_edit_rootdl_ddl2_scrollview_ddl);
ddl2_scrollview_ddl_solidtfd = (TextField) findComponentById(ResourceTable.Id_ddl2_scrollview_ddl_solidtfd);
ddl2_scrollview_ddl_solidtfd.setHint("这里不能为空,非空才能保存!");
recordlist.add(new RecordComponentItem(edit_rootdl_ddl2_scrollview_ddl,0));
edit_rootdl_ddl3 = (DirectionalLayout) findComponentById(ResourceTable.Id_edit_rootdl_ddl3);
edit_rootdl_ddl3_clearbut = (Button) findComponentById(ResourceTable.Id_edit_rootdl_ddl3_clearbut);
edit_rootdl_ddl3_wantimagebut = (Button) findComponentById(ResourceTable.Id_edit_rootdl_ddl3_wantimagebut);
/*<***********************************给顶部取消和保存设置监听器******************************/
edit_rootdl_ddl1_1_nobut.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
if(issavebutpress == false){
toastShow("未保存!");
}
else{
toastShow("已经保存!");
}
terminateAbility();
}
});
edit_rootdl_ddl1_1_savebut.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
if(recordlist.size() == 1 && ddl2_scrollview_ddl_solidtfd.getText().equals("")){
ddl2_scrollview_ddl_solidtfd.clearFocus();
toastShow("内容为空,不能保存!");
return;
}
if(issave == true){
NoteDataManager.deleteFolderFiles(thisnotefoldername);
System.out.println("已经删除了该笔记文件夹中所有txt和image!【Warning】");
}
if(issave == false){
thisnotefoldername = createThisNoteFolder();
issave = true;
}
checkPrintlnRecordList();
for(int i = 0;i < recordlist.size();i++){
if(recordlist.get(i).type == 1){
Image image= (Image)((DirectionalLayout)recordlist.get(i).component).getComponentAt(0);
encodeAndSaveImage(image.getPixelMap(),thisnotefoldername,i);
}
if(recordlist.get(i).type == 0){
TextField textField = (TextField) ((DirectionalLayout)recordlist.get(i).component).getComponentAt(0);
saveTextField(thisnotefoldername,textField,i);
}
}
String[] ls = thisnotefoldername.list();
for(int i = 0;i < ls.length;i++){
System.out.println("检查--------------》》》》》》"+ls[i]);
}
NoteDataManager.generateUserNoteDir();
NoteDataManager.checkUserNoteDir();
toastShow("已经保存!");
ddl2_scrollview_ddl_solidtfd.clearFocus();
issavebutpress = true;//已经按了保存按钮
}
});
/*************************************给顶部取消和保存设置监听器****************************>*/
/*<********************************给底部清除、照片设置监听器****************************/
edit_rootdl_ddl3_clearbut.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
ddl2_scrollview_ddl_solidtfd.clearFocus();
ddl2_scrollview_ddl_solidtfd.setText("");
clearRecordListComponents();
}
});
edit_rootdl_ddl3_wantimagebut.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
selectPicture();
}
});
/**********************************给底部清除、照片设置监听器**************************>*/
/*<*****************************给固有文本输入框设置文本内容变化监听****************************/
ddl2_scrollview_ddl_solidtfd.addTextObserver(new Text.TextObserver() {
@Override
public void onTextUpdated(String s, int i, int i1, int i2) {
issavebutpress = false;//一旦固有存在的文本输入框内容发生变化,立即将issavebutpress置为false
if(s.equals("") == false){
edit_rootdl_ddl3.setVisibility(Component.VISIBLE);
edit_rootdl_ddl1_1_savebut.setVisibility(Component.VISIBLE);
}
else{
edit_rootdl_ddl3.setVisibility(Component.HIDE);
edit_rootdl_ddl1_1_savebut.setVisibility(Component.HIDE);
}
}
});
/*******************************给固有文本输入框设置文本内容变化监听**************************>*/
}
@Override
protected void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_edit);
if(intent.getStringParam("type").equals("add")){
initEASliceComponents();
}
if(intent.getStringParam("type").equals("detail")){
File file = new File(intent.getStringParam("thisnotefoldername"));
thisnotefoldername = file;
issave = true;
System.out.println("type:detail检查---》issave is:"+issave+",thisnotefoldername is:"+thisnotefoldername);
initEASliceComponents();
ArrayList<NoteDetailInfoList> noteDetailInfoLists = NoteDataManager.readSomeNoteDetails(file,this);
for(int i = 0;i < noteDetailInfoLists.size();i++){
if(i == 0){
ddl2_scrollview_ddl_solidtfd.setText((String) (noteDetailInfoLists.get(i).object));
continue;
}
if(noteDetailInfoLists.get(i).type == 0){
DirectionalLayout directionalLayout = getNewTextField();
TextField textField = (TextField) directionalLayout.getComponentAt(0);
textField.setText((String) (noteDetailInfoLists.get(i).object));
edit_rootdl_ddl2_scrollview_ddl.addComponent(directionalLayout);
recordlist.add(new RecordComponentItem(directionalLayout,0));
}
if(noteDetailInfoLists.get(i).type == 1){
DirectionalLayout directionalLayout = getNewImage();
Image image = (Image) directionalLayout.getComponentAt(0);
image.setPixelMap((PixelMap) (noteDetailInfoLists.get(i).object));
edit_rootdl_ddl2_scrollview_ddl.addComponent(directionalLayout);
recordlist.add(new RecordComponentItem(directionalLayout,1));
}
}
}
String[] permission = {"ohos.permission.READ_USER_STORAGE","ohos.permission.WRITE_USER_STORAGE"};
requestPermissionsFromUser(permission,0);
showDir();
}
@Override
protected void onActive() {
super.onActive();
}
@Override
protected void onInactive() {
super.onInactive();
}
@Override
protected void onForeground(Intent intent) {
super.onForeground(intent);
}
@Override
protected void onBackground() {
super.onBackground();
}
@Override
protected void onStop() {
super.onStop();
}
}
```
### 4.1.7 MainAbilitySlice.java
```java
package com.tdtxdcxm.mynotepad.slice;
import com.tdtxdcxm.mynotepad.ResourceTable;
import com.tdtxdcxm.mynotepad.listcontaineritem.NoteListItem;
import com.tdtxdcxm.mynotepad.notedata.NoteDataManager;
import com.tdtxdcxm.mynotepad.provider.NoteListItemProvider;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.components.*;
import ohos.agp.utils.Color;
import ohos.agp.utils.LayoutAlignment;
import ohos.agp.window.dialog.ToastDialog;
import ohos.multimodalinput.event.MmiPoint;
import ohos.multimodalinput.event.TouchEvent;
import java.util.ArrayList;
public class MainAbilitySlice extends AbilitySlice {
private ArrayList<NoteListItem> listcontainerlist = new ArrayList<>();
private float x1,y1,x2,y2;
private DirectionalLayout main_rootdl_ddl1,main_rootdl_ddl2,main_rootdl_ddl3;
private DirectionalLayout main_rootdl_ddl1_1,main_rootdl_ddl1_2;
private ListContainer main_rootdl_ddl2_listcontainer;
private TextField main_rootdl_ddl1_1_tfd;
private Button main_rootdl_ddl1_1_searchbut;
private Text main_rootdl_ddl1_2_text;
private Button main_rootdl_ddl1_2_selectbut,main_rootdl_ddl1_2_addbut;
private Button main_rootdl_ddl3_nobut,main_rootdl_ddl3_delbut;
public void toastShow(String s){
ToastDialog toastDialog = new ToastDialog(this.getContext());
toastDialog.setText(s);
toastDialog.setTransparent(true);
toastDialog.setDuration(100);
toastDialog.setAlignment(LayoutAlignment.CENTER);
toastDialog.show();
}
public void initListContainer(){
NoteDataManager.generateUserNoteDir();
NoteDataManager.checkUserNoteDir();
NoteDataManager.readAllNoteMataForList(listcontainerlist);
NoteListItemProvider noteListItemProvider = new NoteListItemProvider(listcontainerlist,this);
NoteListItemProvider.noteListItemProvider = noteListItemProvider;
main_rootdl_ddl2_listcontainer.setItemProvider(noteListItemProvider);
main_rootdl_ddl2_listcontainer.setItemClickedListener(new ListContainer.ItemClickedListener() {
@Override
public void onItemClicked(ListContainer listContainer, Component component, int i, long l) {
Intent intent = new Intent();
intent.setParam("type","detail");
//将装有该笔记文本和图像的文件夹当作参数传入
intent.setParam("thisnotefoldername",listcontainerlist.get(i).getFile().toString());
Operation operation = new Intent.OperationBuilder()
.withDeviceId("")
.withBundleName("com.tdtxdcxm.mynotepad")
.withAbilityName("com.tdtxdcxm.mynotepad.EditAbility")
.build();
intent.setOperation(operation);
startAbilityForResult(intent,11);
}
});
}
public void initMASComponents(){
main_rootdl_ddl1 = (DirectionalLayout) findComponentById(ResourceTable.Id_main_rootdl_ddl1);
main_rootdl_ddl2 = (DirectionalLayout) findComponentById(ResourceTable.Id_main_rootdl_ddl2);
main_rootdl_ddl3 = (DirectionalLayout) findComponentById(ResourceTable.Id_main_rootdl_ddl3);
NoteListItemProvider.main_rootdl_ddl1 = main_rootdl_ddl1;
main_rootdl_ddl1_1 = (DirectionalLayout) findComponentById(ResourceTable.Id_main_rootdl_ddl1_1);
main_rootdl_ddl1_2 = (DirectionalLayout) findComponentById(ResourceTable.Id_main_rootdl_ddl1_2);
main_rootdl_ddl2_listcontainer = (ListContainer) findComponentById(ResourceTable.Id_main_rootdl_ddl2_listcontainer);
main_rootdl_ddl1_1_tfd = (TextField) findComponentById(ResourceTable.Id_main_rootdl_ddl1_1_tfd);
main_rootdl_ddl1_1_searchbut = (Button) findComponentById(ResourceTable.Id_main_rootdl_ddl1_1_searchbut);
main_rootdl_ddl1_2_text = (Text) findComponentById(ResourceTable.Id_main_rootdl_ddl1_2_text);
main_rootdl_ddl1_2_selectbut = (Button) findComponentById(ResourceTable.Id_main_rootdl_ddl1_2_selectbut);
main_rootdl_ddl1_2_addbut = (Button) findComponentById(ResourceTable.Id_main_rootdl_ddl1_2_addbut);
main_rootdl_ddl3_nobut = (Button) findComponentById(ResourceTable.Id_main_rootdl_ddl3_nobut);
main_rootdl_ddl3_delbut = (Button) findComponentById(ResourceTable.Id_main_rootdl_ddl3_delbut);
/******************************************搜索按钮监听器*******************************************/
main_rootdl_ddl1_1_searchbut.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
main_rootdl_ddl1_1_tfd.clearFocus();
String text = main_rootdl_ddl1_1_tfd.getText();
if(listcontainerlist.size() != 0){
for(int i = 0;i < listcontainerlist.size();i++){
String s = listcontainerlist.get(i).getText();
if(s.indexOf(text) != -1){
Intent intent = new Intent();
intent.setParam("type","detail");
//将装有该笔记文本和图像的文件夹当作参数传入
intent.setParam("thisnotefoldername",listcontainerlist.get(i).getFile().toString());
Operation operation = new Intent.OperationBuilder()
.withDeviceId("")
.withBundleName("com.tdtxdcxm.mynotepad")
.withAbilityName("com.tdtxdcxm.mynotepad.EditAbility")
.build();
intent.setOperation(operation);
startAbilityForResult(intent,11);
return;
}
}
main_rootdl_ddl1_1_tfd.setText("");
toastShow("未找到该关键字匹配的笔记!");
}
else{
main_rootdl_ddl1_1_tfd.setText("");
toastShow("当前无任何笔记!请新建笔记!");
}
}
});
/******************************************搜索按钮监听器*******************************************/
/****************************************标题文本按钮监听器*****************************************/
main_rootdl_ddl1_2_text.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
main_rootdl_ddl1_1_tfd.clearFocus();
}
});
/****************************************标题文本按钮监听器*****************************************/
/*<********************************给2个功能按键设置监听器**********************************************/
main_rootdl_ddl1_2_selectbut.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
main_rootdl_ddl1_1_tfd.clearFocus();
main_rootdl_ddl3.setVisibility(Component.VISIBLE);
int count = NoteListItemProvider.noteListItemProvider.getCount();
for(int i = 0;i < count;i++){
DirectionalLayout directionalLayout = (DirectionalLayout) main_rootdl_ddl2_listcontainer.getComponentAt(i);
directionalLayout.getComponentAt(0).setVisibility(Component.VISIBLE);
}
}
});
main_rootdl_ddl1_2_addbut.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
main_rootdl_ddl1_1_tfd.clearFocus();
Intent intent = new Intent();
intent.setParam("type","add");
Operation operation = new Intent.OperationBuilder()
.withDeviceId("")
.withBundleName("com.tdtxdcxm.mynotepad")
.withAbilityName("com.tdtxdcxm.mynotepad.EditAbility")
.build();
intent.setOperation(operation);
startAbilityForResult(intent,10);
}
});
/*********************************给2个功能按键设置监听器********************************************>*/
/*<********************************给listContainer设置触摸滑动监听器******************************************/
main_rootdl_ddl2_listcontainer.setTouchEventListener(new Component.TouchEventListener() {
@Override
public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
main_rootdl_ddl1_1_tfd.clearFocus();
int action = touchEvent.getAction();
if(action == TouchEvent.PRIMARY_POINT_DOWN){
MmiPoint mmiPoint = touchEvent.getPointerPosition(0);
x1 = mmiPoint.getX();
y1 = mmiPoint.getY();
}
if(action == TouchEvent.PRIMARY_POINT_UP){
MmiPoint mmiPoint = touchEvent.getPointerPosition(0);
x2 = mmiPoint.getX();
y2 = mmiPoint.getY();
if(y1 > y2 && Math.abs(x2 - x1) <= 90.0){
main_rootdl_ddl1.setVisibility(Component.HIDE);
//main_rootdl_ddl3.setVisibility(Component.HIDE);
}
if(y1 < y2 && Math.abs(x2 - x1) <= 90.0){
main_rootdl_ddl1.setVisibility(Component.VISIBLE);
//main_rootdl_ddl3.setVisibility(Component.VISIBLE);
}
}
return true;
}
});
/**********************************给listContainer设置触摸滑动监听器****************************************>*/
/*<********************************给底部两按钮设置监听器******************************************/
main_rootdl_ddl3_nobut.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
main_rootdl_ddl3.setVisibility(Component.HIDE);
int count = NoteListItemProvider.noteListItemProvider.getCount();
for(int i = 0;i < count;i++){
DirectionalLayout directionalLayout = (DirectionalLayout) main_rootdl_ddl2_listcontainer.getComponentAt(i);
Text text = (Text) directionalLayout.getComponentAt(0);
text.setVisibility(Component.HIDE);
text.setText("N");
text.setTextColor(Color.WHITE);
}
}
});
main_rootdl_ddl3_delbut.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
if(main_rootdl_ddl2_listcontainer.getChildCount() != 0){
int n = main_rootdl_ddl2_listcontainer.getChildCount();
System.out.println("n----->>>>"+n);
ArrayList<NoteListItem> t = new ArrayList<>();
for(int i = 0; i< n;i++){
DirectionalLayout directionalLayout = (DirectionalLayout) main_rootdl_ddl2_listcontainer.getComponentAt(i);
Text text = (Text) directionalLayout.getComponentAt(0);
if(text.getText().equals("✔")){
NoteDataManager.deleteFolderFiles(listcontainerlist.get(i).getFile());
}
else{
t.add(listcontainerlist.get(i));
}
}
listcontainerlist.clear();
for(int i = 0;i < t.size();i++){
listcontainerlist.add(t.get(i));
}
NoteListItemProvider.noteListItemProvider.notifyDataChanged();
System.out.println("已经刷新数据了!!!!!!!!!");
t.clear();
}
}
});
/*<********************************给底部两按钮设置监听器******************************************/
}
@Override
public void onAbilityResult(int requestCode, int resultCode, Intent resultData){
System.out.println("回到了MainAbility中!");
NoteDataManager.readAllNoteMataForList(listcontainerlist);
NoteListItemProvider.noteListItemProvider.notifyDataChanged();
}
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
initMASComponents();
initListContainer();
}
@Override
protected void onActive() {
super.onActive();
}
@Override
protected void onInactive() {
super.onInactive();
}
@Override
protected void onForeground(Intent intent) {
super.onForeground(intent);
}
@Override
protected void onBackground() {
super.onBackground();
}
@Override
protected void onStop() {
super.onStop();
}
}
```
### 4.1.8 EditAbility.java
```java
package com.tdtxdcxm.mynotepad;
import com.tdtxdcxm.mynotepad.slice.EditAbilitySlice;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
public class EditAbility extends Ability {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setMainRoute(EditAbilitySlice.class.getName());
}
}
```
### 4.1.9 MainAbility.java
```java
package com.tdtxdcxm.mynotepad;
import com.tdtxdcxm.mynotepad.slice.MainAbilitySlice;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
public class MainAbility extends Ability {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setMainRoute(MainAbilitySlice.class.getName());
}
}
```
### 4.1.10 MyApplication.java
```java
package com.tdtxdcxm.mynotepad;
import ohos.aafwk.ability.AbilityPackage;
public class MyApplication extends AbilityPackage {
@Override
public void onInitialize() {
super.onInitialize();
}
}
```
## 4.2 XML源代码
### 4.2.1 UI背景 XML源代码
---
#### 4.2.1.1 background_ddl1_textfieldbutton.xml
```xml
<?xml version="1.0" encoding="UTF-8" ?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:shape="rectangle">
<corners
ohos:radius="100"/>
</shape>
```
---
#### 4.2.1.2 background_item_rootdl.xml
```xml
<?xml version="1.0" encoding="UTF-8" ?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:shape="rectangle">
<stroke
ohos:width="3vp"
ohos:color="#FFF1F3FF"/>
</shape>
```
---
#### 4.2.1.3 background_rootdl_ddl1_1.xml
```xml
<?xml version="1.0" encoding="UTF-8" ?>
<shape xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:shape="rectangle">
<corners
ohos:radius="100"/>
<stroke
ohos:width="2vp"
ohos:color="#8322B869"/>
<solid
ohos:color="#FFFFFFFF"/>
</shape>
```
### 4.2.2 主页面与子布局UI XML源代码
#### 4.2.2.1 ability_edit.xml
```xml
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:id="$+id:edit_rootdl"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:orientation="vertical"
ohos:alignment="center">
<DirectionalLayout
ohos:id="$+id:edit_rootdl_ddl1"
ohos:height="0"
ohos:weight="0.5"
ohos:width="match_parent"
ohos:orientation="vertical"
ohos:alignment="horizontal_center">
<DirectionalLayout
ohos:id="$+id:edit_rootdl_ddl1_1"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:orientation="horizontal"
ohos:alignment="vertical_center">
<Button
ohos:id="$+id:edit_rootdl_ddl1_1_nobut"
ohos:height="match_parent"
ohos:width="0"
ohos:weight="2"
ohos:text="取消"
ohos:text_color="#FFC39526"
ohos:text_size="20vp"
ohos:text_alignment="center">
</Button>
<Button
ohos:id="$+id:edit_rootdl_ddl1_1_zwbut"
ohos:height="match_parent"
ohos:width="0"
ohos:weight="6"
ohos:visibility="invisible"
ohos:text=" "
ohos:text_color="#FFFFFFFF"
ohos:text_size="20vp"
ohos:text_alignment="vertical_center">
</Button>
<Button
ohos:id="$+id:edit_rootdl_ddl1_1_savebut"
ohos:height="match_parent"
ohos:width="0"
ohos:weight="2"
ohos:text="保存"
ohos:text_size="20vp"
ohos:text_color="#FFC39526"
ohos:text_alignment="center">
</Button>
</DirectionalLayout>
</DirectionalLayout>
<DirectionalLayout
ohos:id="$+id:edit_rootdl_ddl2"
ohos:height="0"
ohos:weight="8"
ohos:width="match_parent"
ohos:orientation="vertical"
ohos:alignment="horizontal_center"
ohos:background_element="#FFF6F4E7">
<ScrollView
ohos:id="$+id:edit_rootdl_ddl2_scrollview"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:rebound_effect="true"
ohos:orientation="vertical">
<DirectionalLayout
ohos:id="$+id:edit_rootdl_ddl2_scrollview_ddl"
ohos:height="match_content"
ohos:width="match_parent"
ohos:orientation="vertical"
ohos:alignment="horizontal_center">
<TextField
ohos:id="$+id:ddl2_scrollview_ddl_solidtfd"
ohos:height="match_content"
ohos:width="match_parent"
ohos:multiple_lines="true"
ohos:max_characters="2500"
ohos:selection_color="blue"
ohos:hint_color="gray"
ohos:hint="输入您的笔记内容......"
ohos:text_size="18vp"
ohos:text_alignment="start"
ohos:background_element="#FFD2E9D2">
</TextField>
</DirectionalLayout>
</ScrollView>
</DirectionalLayout>
<DirectionalLayout
ohos:id="$+id:edit_rootdl_ddl3"
ohos:height="0"
ohos:weight="0.5"
ohos:width="match_parent"
ohos:visibility="hide"
ohos:orientation="horizontal"
ohos:alignment="vertical_center"
ohos:background_element="#FFFFFFFF">
<Button
ohos:id="$+id:edit_rootdl_ddl3_clearbut"
ohos:height="match_parent"
ohos:width="0"
ohos:weight="1"
ohos:text="清空"
ohos:text_size="20vp"
ohos:text_alignment="center">
</Button>
<Button
ohos:id="$+id:edit_rootdl_ddl3_wantimagebut"
ohos:height="match_parent"
ohos:width="0"
ohos:weight="1"
ohos:text="图片"
ohos:text_size="20vp"
ohos:text_alignment="center">
</Button>
</DirectionalLayout>
</DirectionalLayout>
```
---
#### 4.2.2.2 ability_main.xml
```xml
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:id="$+id:main_rootdl"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:orientation="vertical"
ohos:alignment="center">
<DirectionalLayout
ohos:id="$+id:main_rootdl_ddl1"
ohos:height="0"
ohos:weight="1.2"
ohos:width="match_parent"
ohos:orientation="vertical"
ohos:alignment="horizontal_center">
<DirectionalLayout
ohos:id="$+id:main_rootdl_ddl1_1"
ohos:height="0"
ohos:weight="1"
ohos:width="match_parent"
ohos:margin="10vp"
ohos:padding="2vp"
ohos:orientation="horizontal"
ohos:alignment="vertical_center"
ohos:background_element="$graphic:background_rootdl_ddl1_1">
<TextField
ohos:id="$+id:main_rootdl_ddl1_1_tfd"
ohos:height="match_parent"
ohos:width="0"
ohos:weight="8"
ohos:hint="输入关键字......"
ohos:hint_color="gray"
ohos:text_color="blue"
ohos:text_size="20vp"
ohos:text_alignment="center"
ohos:background_element="$graphic:background_ddl1_textfieldbutton">
</TextField>
<Button
ohos:id="$+id:main_rootdl_ddl1_1_searchbut"
ohos:height="match_parent"
ohos:width="0"
ohos:weight="2"
ohos:text="搜索"
ohos:text_size="20vp"
ohos:text_color="#FF3B8A0F"
ohos:text_alignment="center"
ohos:background_element="$graphic:background_ddl1_textfieldbutton">
</Button>
</DirectionalLayout>
<DirectionalLayout
ohos:id="$+id:main_rootdl_ddl1_2"
ohos:height="0"
ohos:weight="1"
ohos:width="match_parent"
ohos:orientation="horizontal"
ohos:alignment="vertical_center"
ohos:background_element="#FFFFFFFF">
<Text
ohos:id="$+id:main_rootdl_ddl1_2_text"
ohos:height="match_parent"
ohos:width="0"
ohos:weight="5.5"
ohos:left_padding="3vp"
ohos:text="便签"
ohos:text_color="#FFB31FC3"
ohos:auto_font_size="true"
ohos:text_alignment="left">
</Text>
<Button
ohos:id="$+id:main_rootdl_ddl1_2_selectbut"
ohos:height="match_parent"
ohos:width="0"
ohos:weight="1.5"
ohos:right_margin="6vp"
ohos:text="选择"
ohos:text_color="#FF41D7C6"
ohos:text_size="25vp"
ohos:text_alignment="center">
</Button>
<Button
ohos:id="$+id:main_rootdl_ddl1_2_addbut"
ohos:height="match_parent"
ohos:width="0"
ohos:weight="1.5"
ohos:text="+"
ohos:text_size="35vp"
ohos:text_color="#FF41D7C6"
ohos:text_alignment="center">
</Button>
</DirectionalLayout>
</DirectionalLayout>
<DirectionalLayout
ohos:id="$+id:main_rootdl_ddl2"
ohos:height="0"
ohos:weight="8.2"
ohos:width="match_parent"
ohos:orientation="vertical"
ohos:alignment="horizontal_center"
ohos:background_element="#28E7F6E7">
<ListContainer
ohos:id="$+id:main_rootdl_ddl2_listcontainer"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:orientation="vertical"
ohos:rebound_effect="true">
</ListContainer>
</DirectionalLayout>
<DirectionalLayout
ohos:id="$+id:main_rootdl_ddl3"
ohos:height="0"
ohos:weight="0.6"
ohos:width="match_parent"
ohos:visibility="hide"
ohos:orientation="horizontal"
ohos:alignment="vertical_center"
ohos:background_element="#FFFFFFFF">
<Button
ohos:id="$+id:main_rootdl_ddl3_nobut"
ohos:height="match_parent"
ohos:width="0"
ohos:weight="1"
ohos:text="取消"
ohos:text_size="20vp"
ohos:text_color="black"
ohos:text_alignment="center">
</Button>
<Button
ohos:id="$+id:main_rootdl_ddl3_delbut"
ohos:height="match_parent"
ohos:width="0"
ohos:weight="1"
ohos:text="删除"
ohos:text_size="20vp"
ohos:text_color="black"
ohos:text_alignment="center">
</Button>
</DirectionalLayout>
</DirectionalLayout>
```
---
#### 4.2.2.3 edit_image_sublayout.xml
```xml
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_content"
ohos:width="match_parent"
ohos:orientation="vertical"
ohos:alignment="horizontal_center"
ohos:background_element="#2D9F9B9B">
<Image
ohos:height="300vp"
ohos:width="match_content"
ohos:scale_mode="zoom_center"
>
</Image>
</DirectionalLayout>
```
---
#### 4.2.2.4 edit_textfield_sublayout.xml
```xml
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_content"
ohos:width="match_parent"
ohos:orientation="horizontal"
ohos:alignment="vertical_center">
<TextField
ohos:height="match_content"
ohos:width="0"
ohos:weight="9"
ohos:multiple_lines="true"
ohos:max_characters="2500"
ohos:selection_color="blue"
ohos:hint_color="gray"
ohos:hint="输入您的笔记内容......"
ohos:text_size="18vp"
ohos:text_alignment="start"
ohos:background_element="#FFD2E9D2">
</TextField>
<Button
ohos:height="match_parent"
ohos:width="0"
ohos:weight="1"
ohos:visibility="hide"
ohos:text="删除"
ohos:text_color="red"
ohos:text_size="18vp"
ohos:text_alignment="center">
</Button>
</DirectionalLayout>
```
---
#### 4.2.2.5 main_listcontainer_itemlayout.xml
```xml
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:id="$+id:item_rootdl"
ohos:height="50vp"
ohos:width="match_parent"
ohos:orientation="horizontal"
ohos:alignment="vertical_center"
ohos:background_element="$graphic:background_item_rootdl">
<Text
ohos:id="$+id:item_selecttxt"
ohos:height="match_parent"
ohos:width="0"
ohos:weight="1"
ohos:text="N"
ohos:auto_font_size="true"
ohos:text_color="white"
ohos:visibility="hide">
</Text>
<Text
ohos:id="$+id:item_text"
ohos:height="match_parent"
ohos:width="0"
ohos:weight="8"
ohos:multiple_lines="true"
ohos:max_text_lines="3"
ohos:text="测试"
ohos:text_size="18vp"
ohos:text_alignment="start"
ohos:text_color="black">
</Text>
<Button
ohos:id="$+id:item_deletebut"
ohos:height="match_parent"
ohos:width="0"
ohos:weight="1"
ohos:visibility="hide"
ohos:text="删除"
ohos:text_color="red"
ohos:text_size="18vp"
ohos:text_alignment="center">
</Button>
</DirectionalLayout>
```
# 5. config.json
```json
{
"app": {
"bundleName": "com.tdtxdcxm.mynotepad",
"vendor": "tdtxdcxm",
"version": {
"code": 1000000,
"name": "1.0.0"
}
},
"deviceConfig": {},
"module": {
"package": "com.tdtxdcxm.mynotepad",
"name": ".MyApplication",
"mainAbility": "com.tdtxdcxm.mynotepad.MainAbility",
"deviceType": [
"phone",
"tablet"
],
"distro": {
"deliveryWithInstall": true,
"moduleName": "entry",
"moduleType": "entry",
"installationFree": false
},
"abilities": [
{
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
],
"orientation": "unspecified",
"visible": true,
"name": "com.tdtxdcxm.mynotepad.MainAbility",
"icon": "$media:icon",
"description": "$string:mainability_description",
"label": "$string:entry_MainAbility",
"type": "page",
"launchType": "standard"
},
{
"orientation": "unspecified",
"name": "com.tdtxdcxm.mynotepad.EditAbility",
"icon": "$media:icon",
"description": "$string:editability_description",
"label": "$string:entry_EditAbility",
"type": "page",
"launchType": "standard"
}
],
"reqPermissions": [
{
"name": "ohos.permission.READ_USER_STORAGE"
},
{
"name": "ohos.permission.WRITE_USER_STORAGE"
}
],
"metaData": {
"customizeData": [
{
"name": "hwc-theme",
"value": "androidhwext:style/Theme.Emui.NoTitleBar",
"extra": ""
}
]
}
}
}
```
# 6. app运行视频(远程真机调试运行)
[基于TextField和Image伪富文本的笔记本便签](https://live.csdn.net/v/embed/186017)