本系列文章记录作者大三开学第一个月中学习HarmonyOS移动应用开发学习经历,此篇为《微信聊天界面》项目,实现功能有
1、聊天信息功能,包括图片、文字
2、发送定位功能
3、选择发送本机图片功能
4、拍照并发送图片功能
如果在真机调试请将config文件中包名换成自己的应用包名即可,申请权限有文件读写、位置获取、相机调用、麦克风调用。
手把手教你用鸿蒙HarmonyOS实现微信聊天界面(一)_MarsHys的博客-CSDN博客
手把手教你用鸿蒙HarmonyOS实现微信聊天界面(二)_MarsHys的博客-CSDN博客
聊天界面效果如图
在该聊天界面选择图片里主要组件是ListContainer其余就是顶栏的Text与底下的Button。
是通过对话框弹出的界面CommonDialog组件,由图片Button的点击事件触发
imageButton.setClickedListener(component1 -> {
dialog = new CommonDialog(getContext());
initImageData();
DirectionalLayout directionalLayout = new DirectionalLayout(getContext());
Component component2;
component2 = LayoutScatter.getInstance(this).parse(ResourceTable.Layout_image_main, null, false);
imagelistContainer= (ListContainer) component2.findComponentById(ResourceTable.Id_list_container);
closeimagebutton = (Button) component2.findComponentById(ResourceTable.Id_close_image_button);
closeimagebutton.setClickedListener(component3 -> {
dialog.destroy();
});
directionalLayout.addComponent(component2);
initImageListContainer();
dialog.setContentCustomComponent(directionalLayout);
dialog.setTitleText("图片");
dialog.setSize(MATCH_PARENT,MATCH_PARENT);
//dialog.setContentText("This is CommonDialog Content area.");
dialog.setButton(IDialog.BUTTON3, "CONFIRM", (iDialog, i) -> iDialog.destroy());
dialog.show();
//addAndUpdateMessage(messageData.size(),"message","image");
});
在第二篇中我们讲到图片是通过Uri访问的图片资源,Uri的资源获取类PictureManager 在上篇已经讲过。在展示里在ListContainer的实体类中是按行存储Uri,在Provider里转换为图片。
图片资源实体类
public class ImageLineItem {
private int index;
private Uri[] uris;
public ImageLineItem(int index) {
this.index = index;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public Uri[] getUris() {
return uris;
}
public void setUris(Uri[] uris) {
this.uris = uris;
}
}
Provider里加载图片布局,对每一个Image组件都添加了点击方法调用发送并更新消息方法addAndUpdateMessag实现点击发送图片。
public class ImageLineProvider extends BaseItemProvider {
private static final String TAG = ImageLineProvider.class.getSimpleName();
private List list;
private AbilitySlice slice;
private MainAbilitySlice mainAbilitySlice;
public void setMainAbilitySlice(MainAbilitySlice mainAbilitySlice){
this.mainAbilitySlice = mainAbilitySlice;
}
public ImageLineProvider(List list, AbilitySlice slice) {
LogUtil.info(TAG,"list.size() : "+list.size());
this.list = list;
this.slice = slice;
}
@Override
public int getCount() {
return list == null ? 0 : list.size();
}
@Override
public Object getItem(int position) {
if (list != null && position >= 0 && position < list.size()){
return list.get(position);
}
return null;
}
@Override
public long getItemId(int position) {
return position;
}
private Component getItemComponent(int position) {
return getComponent(position);
}
private Component getComponent(int position) {
LogUtil.info(TAG,"list.size()"+list.size());
final Component cpt;
cpt = LayoutScatter.getInstance(slice).parse(ResourceTable.Layout_images_line, null, false);
ImageLineItem imageLineItem = list.get(position);
Image image1,image2,image3;
image1 = (Image) cpt.findComponentById(ResourceTable.Id_image1);
image2 = (Image) cpt.findComponentById(ResourceTable.Id_image2);
image3 = (Image) cpt.findComponentById(ResourceTable.Id_image3);
DataAbilityHelper helper=DataAbilityHelper.creator(slice.getContext());
//定义图片来源对象
ImageSource imageSource;
Uri[] uris = imageLineItem.getUris();
FileDescriptor fd = null;
image1.setClickedListener(component1 -> {
mainAbilitySlice.addAndUpdateMessage(mainAbilitySlice.getMessageDataSize(), String.valueOf(uris[0]),"image");
mainAbilitySlice.getDialog().destroy();
});
image2.setClickedListener(component1 -> {
mainAbilitySlice.addAndUpdateMessage(mainAbilitySlice.getMessageDataSize(), String.valueOf(uris[1]),"image");
mainAbilitySlice.getDialog().destroy();
});
image3.setClickedListener(component1 -> {
mainAbilitySlice.addAndUpdateMessage(mainAbilitySlice.getMessageDataSize(), String.valueOf(uris[2]),"image");
mainAbilitySlice.getDialog().destroy();
});
try {
fd = helper.openFile(uris[0], "r");
} catch (DataAbilityRemoteException | FileNotFoundException e) {
e.printStackTrace();
}
imageSource = ImageSource.create(fd, null);
//创建位图
PixelMap pixelMap = imageSource.createPixelmap(null);
image1.setPixelMap(pixelMap);
imageSource.release();
helper.release();
try {
fd = helper.openFile(uris[1], "r");
} catch (DataAbilityRemoteException | FileNotFoundException e) {
e.printStackTrace();
}
imageSource = ImageSource.create(fd, null);
//创建位图
pixelMap = imageSource.createPixelmap(null);
image2.setPixelMap(pixelMap);
imageSource.release();
helper.release();
try {
fd = helper.openFile(uris[2], "r");
} catch (DataAbilityRemoteException | FileNotFoundException e) {
e.printStackTrace();
}
imageSource = ImageSource.create(fd, null);
//创建位图
pixelMap = imageSource.createPixelmap(null);
image3.setPixelMap(pixelMap);
imageSource.release();
helper.release();
return cpt;
}
@Override
public Component getComponent(int position, Component convertComponent, ComponentContainer componentContainer) {
return getItemComponent(position);
}
}
图片获取与布局就讲完了,最后看一下发送效果吧
(Preview:下篇讲如何实现发送定位功能)
Gitee链接
WeChatPage: 鸿蒙版微信界面