> 文档中心 > HarmonyOS应用开发--基于TextField和Image伪富文本的MyNotePad[便签][API V6]

HarmonyOS应用开发--基于TextField和Image伪富文本的MyNotePad[便签][API V6]

HarmonyOS应用开发--基于TextField和Image伪富文本的MyNotePad[便签][API V6]

  • 1. 名称
  • 2. 功能描述
  • 3. app实现关键技巧
    •   3.1 滑动笔记列表更改显示空间、左滑笔记条目显示删除按键右滑消失
    •   3.2 点击“选择”每个笔记条目左侧出现选定框、同时下方显示“取消”与“删除”
    •   3.3 搜索功能
    •   3.4 伪富文本编辑功能(文本和图片)
    •   3.5 获取笔记文件夹的目录结构(重要操作)(存储在该应用沙盒中,而非外部该应用私有存储)
  • 4. 源代码
    •   4.0 工程源文件目录结构
    •   4.1 Java源代码
      •    4.1.1 NoteListItem.java
      •    4.1.2 NoteDataManager.java
      •    4.1.3 NoteDetailInfoList.java
      •    4.1.4 NoteListItemProvider.java
      •    4.1.5 RecordComponentItem.java
      •    4.1.6 EditAbilitySlice.java
      •    4.1.7 MainAbilitySlice.java
      •    4.1.8 EditAbility.java
      •    4.1.9 MainAbility.java
      •    4.1.10 MyApplication.java
    •   4.2 XML源代码
      •    4.2.1 UI背景 XML源代码
        •     4.2.1.1 background_ddl1_textfieldbutton.xml
        •     4.2.1.2 background_item_rootdl.xml
        •     4.2.1.3 background_rootdl_ddl1_1.xml
      •   4.2.2 主页面与子布局UI XML源代码
        •     4.2.2.1 ability_edit.xml
        •     4.2.2.2 ability_main.xml
        •     4.2.2.3 edit_image_sublayout.xml
        •     4.2.2.4 edit_textfield_sublayout.xml
        •     4.2.2.5 main_listcontainer_itemlayout.xml
  • 5. config.json
  • 6. app运行视频(远程真机调试运行)

1. 名称

将本次app命名为:MyNotePad、我的笔记本,app图标采用默认图标,设置app名称即可。
项目已经放置在gitee中:MyNotePad

2. 功能描述

  • 对于鸿蒙应用开发API V6来说可能还不具备富文本组件,翻阅有关的文档富文本组件的函数一些要到AP1 V8才生效,再网上也没有找到有关于富文本的api鸿蒙组件用法。因此,决定使用TextField和Image两大组件以及ScrollView组件去模拟一个富文本组件,称为伪富文本
  • 具有便签笔记编辑功能,可以编辑文本,还可以插入图片,最后保存在应用沙盒的存储空间中
  • 在编辑时,在输入框向左滑动,在其右边侧显示一个删除按钮;向右滑动,则隐藏这个删除按钮实现了这一安卓手机常见的便捷功能。当然,还可以长按文本输入框或图片进行删除。
  • 实现了从系统相册或文件中选取图片,然后进行解码操作,显示到Image组件中。实现了在保存时,将已经解码的图片再编码保存在应用沙盒创建的文件夹中。
  • 实现了对应用沙盒存储的读取与写入操作
  • 实现了创建一系列文件夹,并通过设计好的存储结构,生成文件目录的结构,方便存储或读取时直接获取文件的File变量调用。
  • 在使用ListContainer展示笔记列表时候,上滑笔记列表,则会隐藏上部区域扩大列表竖向范围,下滑笔记列表,则会显示原有功能区域,实现了现在app常见的功能操作
  • 在点击“选择”后,会在笔记列表每个条目的左侧出现一个点击选择的区域,若是选中,则显示一个绿色的对号,若是不想选中,则不显示绿色对号,实现了现在app常见的列表条目删除管理功能。
  • 实现了通过关键句子搜索匹配的笔记功能,如果有,则直接加载该笔记,进入编辑页面。如果没有,则显示toast提示文字!

3. app实现关键技巧

  3.1 滑动笔记列表更改显示空间、左滑笔记条目显示删除按键右滑消失

在这里插入图片描述
实现技巧:

  • 当上滑笔记列表时,触发触摸事件,判断出是在上滑,则让上部的布局容器组件设为HIDE,此时上部不占用空间,则就扩大了列表竖向显示空间。当下滑列表时候,判断出是在下滑,则让上部的布局容器组件设为VISIBLE,则就达到还原的目的。
  • 当在某个笔记条目上左滑时候,触发触摸事件,判断出是在左滑,则将最右侧的红色“删除”按钮设置为VISIBLE。当向右滑动时,将其设置为HIDE,即可实现这一常见的删除效果。

  3.2 点击“选择”每个笔记条目左侧出现选定框、同时下方显示“取消”与“删除”

在这里插入图片描述
实现技巧:

  • ListContainer的子布局是复用的、动态加载的,在编写子布局XML中,让其左侧的点击选择Text默认设置为HIDE,当用户点击“选择”时,会遍历ListContainer目前已经加载的所有Component,然后将其每个左侧的点击选择框设置为VISABLE即可。
  • 当点击“取消”时候,同样按照上述的遍历方法,将每个点选框设置为HIDE,Text的文本设置为“N”,文本颜色设置为WHIE。
  • 如果点击的某个点选框此时的文本是“N”,则将其文本设置为“✔”,文本颜色设置为“GREEN”;如果点击的某个点选框此时的文本是“✔”,则Text的文本设置为“N”,文本颜色设置为WHIE。即可达到点击之后,出现选择或不选则的效果。
  • 点击“删除”是,会遍历ListContainer此时已经加载的组件,当其左侧点选框文本内容是“✔”,通过ListContainer的数据源列表(一个泛型ArrayList)获取该笔记所在文件夹的File变量,然后将该文件夹中的所有文件通过遍历的方法删除,最后,从该数据源列表中去除该项数据,最后刷新ListContainer即可。

  3.3 搜索功能

在这里插入图片描述
实现技巧:

  • 遍历此时ListContainer中所有的笔记简略文本,通过使用indexOf(搜索输入框的文本)判断有没有匹配的笔记条目,如果有则直接打开该笔记,如果没有,则显示Toast提示。

  3.4 伪富文本编辑功能(文本和图片)

在这里插入图片描述
实现技巧:

  • 首先需要有一个ScrollView组件,然后需要根据需要动态的往里面增加TextField或Image组件,并且会有一个recordlist(一个泛型ArrayList)记录当前编辑区域的组件顺序(以便存储数据时按照此顺序编制文件名、读取数据时按照此文件名顺序恢复),即可实现“ 伪富文本”功能。期待后续API推出的富文本组件!
  • 点击“保存”,会首先判断第一个文本输入框中是否为空,如果不为空则保存,为空则显示Toast提示。保存时,需要遍历recordlist中的每项,按照每项中的组件类型标识,如果是TextField则按照文本文件的存储方法,使用相应的流处理存储,如果是Image则需要将其先进行编码操作同时构建目标文件将其打包进去。此时记录保存状态为true。

  3.5 获取笔记文件夹的目录结构(重要操作)(存储在该应用沙盒中,而非外部该应用私有存储)

本便签的文件夹组织结构示意图如下:
在这里插入图片描述
实现技巧:

  • 自动获取每天的日期,创建每日文件夹dayfolder,其中的文件夹则是该日按照编辑顺序每条笔记的文件夹thisnotefolder,在该文件夹中,按照recordlist所记录的组件顺序,给文件命名,进行存储。如果当日文件夹中已经有两个文件,那么该日第三个笔记要存储的文件夹名称会顺序递增(使用dayfolder.list().length+1)
  • 【生成usernote文件夹目录结构】使用一个ArrayList泛型列表(ArrayList 《StructFile》 dayfolders = new ArrayList()),其中该类型的类StructFile中有两个变量,其中一个变量File dayfile用来保存某日文件夹的File,另一个变量File[ ] dayfile_notelistfiles用来保存该日文件夹中的所有笔记File。这样就生成了usernote文件夹的结构,把所有文件夹的“把柄”都捏在了手中,便于操作!示意图如下:
    在这里插入图片描述

4. 源代码

  4.0 工程源文件目录结构

在这里插入图片描述

  4.1 Java源代码

   4.1.1 NoteListItem.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

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

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

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

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

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[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

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

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

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

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

<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

<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

<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

<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

<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

<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

<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

<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

{  "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伪富文本的笔记本便签

UCloud