#星光计划1.0# HarmonyOS 分布式之仿抖音应用 原创 精华
中软HOS小鸿
发布于 2021-10-20 09:43
浏览
7收藏
作者:梁青松
项目介绍
使用Java UI开发分布式仿抖音应用,上下滑动切换视频,评论功能,设备迁移功能:记录播放的视频页和进度、评论数据。
效果演示
1.上下滑动切换视频、点击迁移图标,弹框选择在线的设备,完成视频数据的迁移。
2.点击评论图标查看评论,编辑评论内容并发送。点击迁移图标,弹框选择在线的设备,完成评论数据的迁移。
项目结构
主要代码
1、上下滑动页面
页面切换用到系统组件PageSlider,默认左右切换,设置为上下方向:setOrientation(Component.VERTICAL);
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.*;
import java.util.ArrayList;
import java.util.List;
public class MainAbilitySlice extends AbilitySlice {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
// 查找滑动页面组件
PageSlider pageSlider = (PageSlider) findComponentById(ResourceTable.Id_pageSlider);
// 设置滑动方向为上下滑动
pageSlider.setOrientation(Component.VERTICAL);
// 集合测试数据
List<String> listData=new ArrayList<>();
listData.add("第一页");
listData.add("第二页");
listData.add("第三页");
// 设置页面适配器
pageSlider.setProvider(new PageSliderProvider() {
/**
* 获取当前适配器中可用视图的数量
*/
@Override
public int getCount() {
return listData.size();
}
/**
* 创建页面
*/
@Override
public Object createPageInContainer(ComponentContainer container, int position) {
// 查找布局
Component component = LayoutScatter.getInstance(getContext()).parse(ResourceTable.Layout_item_page, null, false);
Text textContent = (Text) component.findComponentById(ResourceTable.Id_text_item_page_content);
// 设置数据
textContent.setText(listData.get(position));
// 添加到容器中
container.addComponent(component);
return component;
}
/**
* 销毁页面
*/
@Override
public void destroyPageFromContainer(ComponentContainer container, int position, Object object) {
// 从容器中移除
container.removeComponent((Component) object);
}
/**
* 检查页面是否与对象匹配
*/
@Override
public boolean isPageMatchToObject(Component page, Object object) {
return true;
}
});
// 添加页面改变监听器
pageSlider.addPageChangedListener(new PageSlider.PageChangedListener() {
/**
* 页面滑动时调用
*/
@Override
public void onPageSliding(int itemPos, float itemPosOffset, int itemPosOffsetPixels) {}
/**
* 当页面滑动状态改变时调用
*/
@Override
public void onPageSlideStateChanged(int state) {}
/**
* 选择新页面时回调
*/
@Override
public void onPageChosen(int itemPos) {
// 在此方法下,切换页面获取当前页面的视频源,进行播放
String data = listData.get(itemPos);
}
});
}
}
2、播放视频
视频播放使用Player,视频画面窗口显示使用SurfaceProvider
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.surfaceprovider.SurfaceProvider;
import ohos.agp.graphics.SurfaceOps;
import ohos.global.resource.RawFileDescriptor;
import ohos.media.common.Source;
import ohos.media.player.Player;
import java.io.IOException;
public class MainAbilitySlice extends AbilitySlice {
// 视频路径
private final String videoPath = "resources/rawfile/HarmonyOS.mp4";
// 播放器
private Player mPlayer;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
// 初始化播放器
mPlayer = new Player(getContext());
// 查找视频窗口组件
SurfaceProvider surfaceProvider = (SurfaceProvider) findComponentById(ResourceTable.Id_surfaceProvider);
// 设置视频窗口在顶层
surfaceProvider.pinToZTop(true);
// 设置视频窗口操作监听
if (surfaceProvider.getSurfaceOps().isPresent()) {
surfaceProvider.getSurfaceOps().get().addCallback(new SurfaceOps.Callback() {
/**
* 创建视频窗口
*/
@Override
public void surfaceCreated(SurfaceOps holder) {
try {
RawFileDescriptor fileDescriptor = getResourceManager().getRawFileEntry(videoPath).openRawFileDescriptor();
Source source = new Source(fileDescriptor.getFileDescriptor(),
fileDescriptor.getStartPosition(),
fileDescriptor.getFileSize()
);
// 设置媒体文件
mPlayer.setSource(source);
// 设置播放窗口
mPlayer.setVideoSurface(holder.getSurface());
// 循环播放
mPlayer.enableSingleLooping(true);
// 准备播放环境并缓冲媒体数据
mPlayer.prepare();
// 开始播放
mPlayer.play();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 视频窗口改变
*/
@Override
public void surfaceChanged(SurfaceOps holder, int format, int width, int height) {}
/**
* 视频窗口销毁
*/
@Override
public void surfaceDestroyed(SurfaceOps holder) {}
});
}
}
@Override
protected void onStop() {
super.onStop();
// 页面销毁,释放播放器
if (mPlayer != null) {
mPlayer.stop();
mPlayer.release();
}
}
}
3、跨设备迁移示例
跨设备迁移使用IAbilityContinuation接口
1、在entry下的config.json配置权限
"reqPermissions": [
{
"name": "ohos.permission.DISTRIBUTED_DATASYNC"
},
{
"name": "ohos.permission.GET_DISTRIBUTED_DEVICE_INFO"
},
{
"name": "ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE"
}
]
2、实现IAbilityContinuation接口,说明:一个应用可能包含多个Page,仅需要在支持迁移的Page中通过以下方法实现IAbilityContinuation接口。同时,此Page所包含的所有AbilitySlice也需要实现此接口。
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.ability.IAbilityContinuation;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.IntentParams;
import ohos.agp.components.Button;
import ohos.agp.components.Text;
import ohos.bundle.IBundleManager;
import ohos.distributedschedule.interwork.DeviceInfo;
import ohos.distributedschedule.interwork.DeviceManager;
import java.util.List;
public class MainAbilitySlice extends AbilitySlice implements IAbilityContinuation {
private String data = "";
String PERMISSION = "ohos.permission.DISTRIBUTED_DATASYNC";
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
// 申请权限
if (verifySelfPermission(PERMISSION) != IBundleManager.PERMISSION_GRANTED) {
requestPermissionsFromUser(new String[]{PERMISSION}, 0);
}
Button button = (Button)findComponentById(ResourceTable.Id_button);
Text text = (Text)findComponentById(ResourceTable.Id_text);
// 点击迁移
button.setClickedListener(component -> {
// 查询分布式网络中所有在线设备(不包括本地设备)的信息。
List<DeviceInfo> deviceList = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE);
if (deviceList.size()>0) {
// 启动迁移,指定的设备ID
continueAbility(deviceList.get(0).getDeviceId());
}
});
// 显示迁移的数据
text.setText("迁移的数据:"+data);
}
/**
* 启动迁移时首次调用此方法
* @return 是否进行迁移
*/
@Override
public boolean onStartContinuation() {
return true;
}
/**
* 迁移时存入数据
*/
@Override
public boolean onSaveData(IntentParams intentParams) {
intentParams.setParam("data","测试数据");
return true;
}
/**
* 获取迁移存入的数据,在生命周期的onStart之前执行
*/
@Override
public boolean onRestoreData(IntentParams intentParams) {
data= (String) intentParams.getParam("data");
return true;
}
/**
* 迁移完成
*/
@Override
public void onCompleteContinuation(int i) {}
}
根据上面的核心代码示例,了解实现原理,接下来便可以结合实际需求完善功能了。
项目地址
https://gitee.com/liangdidi/DistributedDemo
更多原创内容请关注:开鸿 HarmonyOS 学院
入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。
©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
赞
12
收藏 7
回复
相关推荐
确实很像抖音,完善后肯定会是一款优秀的产品。
楼主666,这个是不是也可以参加华为的活动呀?
很赞(抱大腿
是呀,作者参加了华为活动呢