harmonyos应用开发

HarmonyOS应用开发--基于TextField和Image伪富文本的MyNotePad

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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值