> 文档中心 > 自学HarmonyOS应用开发(75)- 显示拍摄结果

自学HarmonyOS应用开发(75)- 显示拍摄结果

照片拍摄完成接下来的动作就是确认拍照结果。我们的实现方法是对前面文章中用到的文件浏览器功能进行扩展,从而实现一个简单的照片浏览器功能。

增加照片浏览器画面

照片浏览器画面使用下面的布局

<xwg.dynamiclayout.DynamicLayout    xmlns:ohos="http://schemas.huawei.com/res/ohos"    ohos:height="match_parent"    ohos:width="match_parent"    ohos:background_element="$graphic:main_ability_title_background"    ohos:orientation="vertical">    <xwg.fileitems.FileListContainer ohos:id="$+id:list_container" ohos:height="0" ohos:weight="300" ohos:width="match_parent" ohos:layout_alignment="left"/>    <xwg.dynamiclayout.LayoutSeparator ohos:id="$+id:seperator" ohos:height="20vp" ohos:width="match_parent" ohos:background_element="#7F7F7F"/>    <DirectionalLayout ohos:id="$+id:detail_view_container" ohos:width="match_parent" ohos:height="0" ohos:weight = "300"/>

代码中用到的FileListContainer,LayoutSeparator都在之前的文章中有过说明,这里就不再赘述了。

和这个布局文件配套的页面文件如下:​​​​​​​

public class BrowserSlice  extends AbilitySlice {    static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00101, "MainAbilitySlice");    @Override    public void onStart(Intent intent) { setUIContent(ResourceTable.Layout_browser_ability); String path = intent.getStringParam("Path"); initListContainer(path);    }    @Override    public void onActive() { super.onActive();    }    @Override    public void onForeground(Intent intent) { super.onForeground(intent);    }    FileListContainer.SelectedListener listener = new FileListContainer.SelectedListener() { @Override public void onItemSelected(FileListContainer listContainer, BrowserItem item) {     HiLog.info(LABEL, "MainAbilitySlice.onItemSelected, item=%{public}s!", item.getName());     ComponentContainer container =      (ComponentContainer)(BrowserSlice.this.findComponentById(ResourceTable.Id_detail_view_container));     item.buildView(container);     container.invalidate(); }    };    private void initListContainer(String path) { FileListContainer container = (FileListContainer)findComponentById(ResourceTable.Id_list_container); container.setSelectedListener(listener); container.setRootDir(path);    }}

准备ListContainer相关类

稍微需要说明的是,这个BrowserSlice类会在onStart方法中从Intent参数中获取一个浏览起始路径并通过调用setRootDir方法将这个路径传递给FileListContainer组件。

而FileListContainer组件又将这个路径传递给BrowerItemProvider:​​​​​​​

public class FileListContainer extends ListContainer {    public void setRootDir(String path){ fileItemProvider = new BrowserItemProvider(this.mContext, new BrowserItem.DirChangeListener() {     @Override     public void dirChanged(File dir) {  changeDir(dir);     } }); fileItemProvider.setRoot(path); setItemProvider(fileItemProvider);    }

BrowerItemProvider在接受的起始路径时遍历该目录下的所有文件,如果找到扩展名为jpg的文件,就会生成用来表示照片文件的ImageItem。具体处理见代码第18行。​​​​​​​

public class BrowserItemProvider extends BaseItemProvider {    ...    public void setRoot(String path){ File root = new File(path); setCurrentDir(root);    }    ...    public void setCurrentDir(File dir) { list.clear(); int index = 0; File[] files = dir.listFiles(); if(files != null) {     for (File file : files) {  if (file.isDirectory()) {      list.add(new DirItem(context, file, index++, dirChangeListener));  } else {      if(file.getName().endsWith(".jpg")){   list.add(new ImageItem(context, file, index++));      }else {   list.add(new FileItem(context, file, index++));      }  }     } }    }}

ImageItem是为了表示照片文件而增加的新类。​​​​​​​

public class ImageItem extends BrowserItem {    static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00104, "ImageItem");    File file = null;    public ImageItem(Context context, File file, int index) { super(context, file.getName(), index); this.file = file;    }    @Override    public int getComponentId(){ return ResourceTable.Id_image_layout;    }    @Override    public Component createUiComponent(){ HiLog.info(LABEL, "ImageItem.createUiComponent of %{public}s", name); return LayoutScatter.getInstance(context).parse(ResourceTable.Layout_image_item, null, false);    }    @Override    public void buildView(ComponentContainer container) { container.removeAllComponents(); DirectionalLayout image_container = (DirectionalLayout) LayoutScatter.getInstance(context).parse(  ResourceTable.Layout_image_container,  null,  false); Image image = (Image)image_container.findComponentById(ResourceTable.Id_image); ImageSource.SourceOptions srcOpts = new ImageSource.SourceOptions(); srcOpts.formatHint = "image/png"; String pathName = this.file.getPath(); ImageSource imageSource = ImageSource.create(pathName, srcOpts); PixelMap pixelMapNoOptions = imageSource.createPixelmap(null); image.setPixelMap(pixelMapNoOptions);        container.addComponent(image_container);    }}

当用户选择照片文件,照片浏览器需要表示其内容时,ImageItem的buildView方法会被调用并按照如下步骤表示照片。

  1. 解析布局文件image_container.xml。

    <DirectionalLayout    xmlns:ohos="http://schemas.huawei.com/res/ohos"    ohos:id="$+id:image_layout"    ohos:height="match_content"    ohos:width="match_parent"    ohos:left_margin="16vp"    ohos:right_margin="16vp"    ohos:orientation="vertical"    ohos:background_element="#7f7f7f">    <Image ohos:id="$+id:image" ohos:height="match_parent" ohos:width="match_parent" ohos:padding="4vp" ohos:layout_alignment="left"/>​​​​​​​
  2. 读取照片文件并生成Image对象

  3. 将Image对象设置到image_container布局中的Image组件上。

  4. image_container布局动态装配在照片浏览器页面的布局文件中。

动作效果视频

动作效果视频

参考资料

相机示例代码

https://gitee.com/openharmony/app_samples/tree/master/media/Camera

权限开发概述

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/security-permissions-overview-0000000000029883

权限开发指导

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/security-permissions-guidelines-0000000000029886

应用权限列表

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/security-permissions-available-0000001051089272

作者著作介绍

《实战Python设计模式》是作者去年3月份出版的技术书籍,该书利用Python 的标准GUI 工具包tkinter,通过可执行的示例对23 个设计模式逐个进行说明。这样一方面可以使读者了解真实的软件开发工作中每个设计模式的运用场景和想要解决的问题;另一方面通过对这些问题的解决过程进行说明,让读者明白在编写代码时如何判断使用设计模式的利弊,并合理运用设计模式。

对设计模式感兴趣而且希望随学随用的读者通过本书可以快速跨越从理解到运用的门槛;希望学习Python GUI 编程的读者可以将本书中的示例作为设计和开发的参考;使用Python 语言进行图像分析、数据处理工作的读者可以直接以本书中的示例为基础,迅速构建自己的系统架构。


觉得本文有帮助?请分享给更多人。

关注微信公众号【面向对象思考】轻松学习每一天!

面向对象开发,面向对象思考!