如何用所学的鸿蒙知识做一个小应用

描述

   

今时今日,不管是大人,还是小孩,都喜欢刷视频,生活中刷视频的 APP 也多得是,如:抖音,快手,视频号,今日头条,火山…数也不数不清了。

     

 

然而华为论坛鸿蒙版块搞活动,做一个属于自己的视频应用,说真的,看到这个活动我很开心,又可以用所学的鸿蒙知识来做一个小应用了!

 

看了小提示,都是 JS 组件来实现的,当我看到分布式也可以用 JS 来写时,当时觉得 JS 也太强大了,因为之前写的 Demo 都是用 Java 来写分布式的。

 

本人工作也是从事 Java 后台开发,对于 JS 前端知识,也就是入门级水平,然后就在想是用 Java 来写这个视频应用,还是用 JS 来写呢。

 

通过看了 JS 参考 API 实例后,决定使用 JS 来写,简单易懂,同时也希望现在还在观望鸿蒙应用开发的前端开发人员,不要怕自己不会 Java 开发,而一直在观望,没有踏出第一步来写 Demo。

 

我写的这个视频应用取名为“爱视频 ,99% 是用 JS 前端知识完成的,只有 1% 的 Java 代码是复制过来的,也就是动态授权代码,所以希望还在观望的前端开发者,就从这个爱视频 APP 开始你们的第一个鸿蒙应用吧!

   

实现效果

     

创建工程

     

在这当作你已经安装好最新版本 DevEco-Studio 开发工具,点击 File→New→New Project…弹出 Create HarmonyOS Project 窗口。

 这里我选择空白 JS 模板创建,写界面还是 JS 比较方便些,对于有一定前端知识的小伙伴来说。

 

 

 

 

主界面开发

     

在展示源代码之前,先介绍一下使用到了 JS 哪些组件:

  • 滑动容器(swiper)

  • 视频播放(video)

  • 可滑动面板(panel)

  • 列表组件(list)

  • 图片组件(image)

  • 文本组件(text)

  • 交互式组件(input)

  • 按钮组件(button)

 

通过查看 JS API 参考文档,就可以做出你喜欢的视频应用了。

 

先介绍简单的 1% Java 代码,如果之前做过分布式 Demo,直接复制过来就可以使用:

 

Java 代码:
public class MainAbility extends AceAbility {
    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        // 动态判断权限
        if (verifySelfPermission("ohos.permission.DISTRIBUTED_DATASYNC") != IBundleManager.PERMISSION_GRANTED) {
            // 应用未被授予权限
            if (canRequestPermission("ohos.permission.DISTRIBUTED_DATASYNC")) {
                // 是否可以申请弹框授权(首次申请或者用户未选择禁止且不再提示)
                requestPermissionsFromUser(new String[]{"ohos.permission.DISTRIBUTED_DATASYNC"}, 0);
            }
        }
    }

    @Override
    public void onStop() {
        super.onStop();
    }
}
   

HML 代码(重要界面布局文件):

<div class="container">
    <swiper class="swiper" id="swiper" index="{{ continueAbilityData.currentIndex }}" indicator="false" loop="true" digital="false" vertical="true" onchange="changeSwiper">
        <div class = "swiperContent" >
            <video id='videoOne' src='{{ continueAbilityData.videoList[0] }}' muted='false' autoplay='true'ontimeupdate='timeupdateCallback' style="object-fit:fill; width:100%; height: 100%;" controls="false" onclick="change_start_pause_one" loop='true' starttime = '{{ ontinueAbilityData.timeupdatetime }}'>video>
        div>
        <div class = "swiperContent">
            <video id='videoTwo' src='{{ continueAbilityData.videoList[1] }}' muted='false' autoplay='false' ontimeupdate='timeupdateCallback' style="object-fit:fill; width:100%; height: 100%;" controls="false" onclick="change_start_pause_two" loop='true' starttime = '{{ ontinueAbilityData.timeupdatetime }}'>video>
        div>
        <div class = "swiperContent">
            <video id='videoThree' src='{{ continueAbilityData.videoList[2] }}' muted='false' autoplay='false' ontimeupdate='timeupdateCallback' style="object-fit:fill; width:100%; height: 100%;" controls="false" onclick="change_start_pause_three" loop='true' starttime = '{{ continueAbilityData.timeupdatetime }}'>video>
        div>
    swiper>
    <div class="btn-footer">
        <image class="comment-icon icon" src="/common/army_icon.jpg">image>
        <text class="footer-label">#HarmonyOS挑战赛第二期#text>
        <image class="comment-icon" src="/common/share.png" onclick="tryContinueAbility">image>
        <image class="comment-icon" src="/common/bxs-message.png" onclick="showPanel">image>
    div>
    <panel id="simplepanel" type="foldable" mode="half" miniheight="400px">
        <div class="panel-div">
            <list class="todo-wrapper">
                <list-item for="{{continueAbilityData.todolist}}" class="todo-item">
                    <image class="todo-icon" src="/common/avatar04.png">image>
                    <text class="todo-title">{{$item.title}}text>
                list-item>
            list>
            <div class="inner-btn">
                <input id="input" class="input" type="text" value="{{continueAbilityData.comment}}" maxlength="20" enterkeytype="send" placeholder="请输入评论内容" onchange="changeValue" onenterkeyclick="enterkeyClick" style="margin-right: 10px;">input>
                <button type="capsule" value="关闭" onclick="closePanel">button>
            div>
        div>
    panel>
div>

 

 

JS 代码(重要逻辑代码,各组件事件):

// @ts-nocheck
import app from '@system.app';
export default {
    data: {
        img: "resources/media/pic_tv.png",
        continueAbilityData: {
            currentIndex: 0,
            videoList: [
                "/common/000001.mp4",
                "/common/000002.mp4",
                "/common/000003.mp4"
            ],
            timeupdatetime: 2,
            isStart: true,
            todolist: [
                {title: 'HDC2021活动门票进行中'},
                {title: '我期待HarmonyOS生态越来越完善'},
                {title: 'HarmonyOS你值得拥有'}],
            comment: ''
        }
    },
    onInit() {
    },
    changeSwiper(e) {
        console.info("onRestoreData:changeSwiper");
        this.switchPlay(e.index);
    },
    switchPlay(index) {
        console.info("onRestoreData:onShow <> " + index);
        this.continueAbilityData.currentIndex = index;
        if(index == 0) {
            this.$element('videoOne').start();
            this.$element('videoTwo').pause();
            this.$element('videoThree').pause();
            console.info("onRestoreData:videoOne <> start " + this.$element('videoOne').starttime);
        }else if(index == 1) {
            this.$element('videoOne').pause();
            this.$element('videoTwo').start();
            this.$element('videoThree').pause();
            console.info("onRestoreData:videoTwo <> start " + this.$element('videoTwo').starttime);
        }else if(index == 2) {
            this.$element('videoOne').pause();
            this.$element('videoTwo').pause();
            this.$element('videoThree').start();
            console.info("onRestoreData:videoThree <> start " + this.$element('videoThree').starttime);
        }
    },

    //流转事件
    tryContinueAbility: async function() {
        // 应用进行迁移
        let result = await FeatureAbility.continueAbility();
        console.info("result:" + JSON.stringify(result));
    },
    onStartContinuation() {
        // 判断当前的状态是不是适合迁移
        console.info("onStartContinuation");
        return true;
    },
    onCompleteContinuation(code) {
        // 迁移操作完成,code返回结果
        console.info("CompleteContinuation: code = " + code);
        app.terminate();

    },
    onSaveData(saveData) {
        // 数据保存到savedData中进行迁移。
        var data = this.continueAbilityData;
        console.info("onSaveData:" + JSON.stringify(data));
        Object.assign(saveData, data)
    },
    onRestoreData(restoreData) {
        console.info("onRestoreData:" + JSON.stringify(restoreData));
        // 收到迁移数据,恢复。
        this.continueAbilityData = restoreData;

        var currentIndex = this.continueAbilityData.currentIndex;
        var currentTime = this.continueAbilityData.timeupdatetime;

        this.$element('videoOne').pause();
        this.$element('videoTwo').pause();
        this.$element('videoThree').pause();

        this.$element('videoOne').starttime = currentTime;
        this.$element('videoTwo').starttime = currentTime;
        this.$element('videoThree').starttime = currentTime;

        this.switchPlay(currentIndex);
    },

    //评论事件
    showPanel() {
        this.$element('simplepanel').show()
    },
    closePanel() {
        this.$element('simplepanel').close()
    },
    changeValue(e) {
        this.continueAbilityData.comment = e.value;
    },
    enterkeyClick(e) {
        this.continueAbilityData.todolist.push({title: this.continueAbilityData.comment});
        this.continueAbilityData.comment = "";
    },
    timeupdateCallback:function(e){ this.continueAbilityData.timeupdatetime = e.currenttime;},
    change_start_pause_one: function() {
        if(this.continueAbilityData.isStart) {
            this.$element('videoOne').pause();
            this.continueAbilityData.isStart = false;
        } else {
            this.$element('videoOne').start();
            this.continueAbilityData.isStart = true;
        }
    },
    change_start_pause_two: function() {
        if(this.continueAbilityData.isStart) {
            this.$element('videoTwo').pause();
            this.continueAbilityData.isStart = false;
        } else {
            this.$element('videoTwo').start();
            this.continueAbilityData.isStart = true;
        }
    },
    change_start_pause_three: function() {
        if(this.continueAbilityData.isStart) {
            this.$element('videoThree').pause();
            this.continueAbilityData.isStart = false;
        } else {
            this.$element('videoThree').start();
            this.continueAbilityData.isStart = true;
        }
    }
}

 

 

CSS 代码(重要化妆技术):

.container {
    width100%;
    height100%;
    flex-direction: column;
}

.img {
    object-fit: cover;
    background-color#808080;
}

.swiper {
    flex-direction: column;
    align-content: center;
    align-items: center;
    width100%;
    height100%;
    background-color: black;
}
.swiperContent {
    height100%;
    justify-content: center;
    background-color: black;
}

.btn-footer {
    height60px;
    line-height60px;
    width100%;
    background-color: black;
    flex-direction: row;
}
.footer-label {
    font-size16px;
    color: white;
    padding-top0px;
    flex-weight1;
    line-height20px;
}
.comment-icon {
    width32px;
    height32px;
    margin8px;
}
.icon {
    border-radius16px;
}

.panel-div {
    flex-direction: column;
    align-content: center;
    align-items: center;
    width100%;
    height100%;
}
.inner-btn {
    height70px;
    padding10px;
}
.todo-wrapper {
    width100%;
    height100%;
}
.todo-item {
    width100%;
    height30px;
    padding-left10px;
    padding-right10px;
}
.todo-icon {
    width16px;
    height16px;
    margin-top10px;
    margin-right10px;
}
.todo-title {
    width100%;
    height100%;
    text-align: left;
    font-size14fp;
}

 

代码就写到此了,不要忘记了 config.json 文件的权限配置哦,在 module 下添加:

"reqPermissions": [
   {
      "name""ohos.permission.DISTRIBUTED_DATASYNC"
   }
]
   

总结

     

 

说实存的,当看到这个活动时间才几天时,感觉时间不太够用,要滑动视频,要评论功能,要分布式的,加上都是用空闲时间来做的,然而当深入去理解相关组件用法后,发现应该一天时间就可以了。

 

有兴趣的小伙伴可以下载源码查看,项目代码写得还不算靓仔,很多为了实现效果,都是 Hardcode 的。

 

有空可以把重复代码抽出来,视频源也可以放到服务器上,然后就可以更愉快的刷更多视频了,源码同步到 gitee 码云,项目素材没有上传,自行添加。  

源码在这:

https://gitee.com/army16/qin-hong-jun-video

 

责任编辑:haq
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分