微信小程序(看文档写实例四)微信小程序课堂宝APP实现签到子页面布局及课程视频播放页面
一、签到子页面布局
子页面主要是一个签到按钮,然后下方是签到记录列表。
1、签到按钮
布局代码:
<button class='sign-button' bindtap='sign'>签到</button> |
样式代码:
/* 签到按钮样式 */ .sign-button{ margin-top: 30rpx; margin-bottom: 30rpx; display: flex; width: 240rpx; height: 240rpx; line-height: 240rpx; color: red; background-color: greenyellow; border-radius: 50%; justify-content: center; font-size: 36px; } |
效果:
2、签到列表设计
布局代码:
<text class='sign-record-text'>签到记录</text> <view class='section'> <block wx:for="{{mSignRecord}}" wx:key="*unique">
<view wx:if="{{item.signFlag}}" class='sign-record-item'> <view class='sign-record-item-date'>{{item.date}}</view> <view class='sign-record-item-count'>第{{item.numberNo}}次课</view> <icon type='success' class='sign-record-item-icon'></icon> <text class='sign-record-item-result'>已签到</text> </view>
<view wx:else class='sign-record-item' style='color:red;'> <view class='sign-record-item-date'>{{item.date}}</view> <view class='sign-record-item-count'>第{{item.numberNo}}次课</view> <icon type='cancel' class='sign-record-item-icon' ></icon> <text class='sign-record-item-result'>未签到</text> </view> </block> </view> |
样式代码:
/* 签到记录列表item样式 */ .sign-record-item{ height: 40px; line-height: 40px; border: 1px solid #eee; white-space: nowrap; display: flex; flex-direction: row; font-size: 15px; color: green; align-items: center; justify-content: center; } /* 签到记录列表item日期样式 */ .sign-record-item-date{ padding-left: 50rpx; } /* 签到记录列表item次数样式 */ .sign-record-item-count{ padding-left: 100rpx; } /* 签到记录列表item是否签到icon样式 */ .sign-record-item-icon{ margin-top: 20px; padding-left: 100rpx; } /* 签到记录列表item签到结果样式 */ .sign-record-item-result{ padding-left: 15rpx; } |
效果:
二、课程视频播放页面
课程视频是一个page,于是新建一个page,布局思路是屏幕上方是播放组件video,接下来是课程系列名称,然后是集数列表,点击时可以播放对应的url。
1、页面布局
看源码发现video组件有如下属性:
属性名 | 类型 | 默认值 | 说明 | 最低版本 |
---|---|---|---|---|
src | String | 要播放视频的资源地址,支持云文件ID(2.2.3起) | ||
initial-time | Number | 指定视频初始播放位置 | 1.6.0 | |
duration | Number | 指定视频时长 | 1.1.0 | |
controls | Boolean | true | 是否显示默认播放控件(播放/暂停按钮、播放进度、时间) | |
danmu-list | Object Array | 弹幕列表 | ||
danmu-btn | Boolean | false | 是否显示弹幕按钮,只在初始化时有效,不能动态变更 | |
enable-danmu | Boolean | false | 是否展示弹幕,只在初始化时有效,不能动态变更 | |
autoplay | Boolean | false | 是否自动播放 | |
loop | Boolean | false | 是否循环播放 | 1.4.0 |
muted | Boolean | false | 是否静音播放 | 1.4.0 |
page-gesture | Boolean | false | 在非全屏模式下,是否开启亮度与音量调节手势 | 1.6.0 |
direction | Number | 设置全屏时视频的方向,不指定则根据宽高比自动判断。有效值为 0(正常竖向), 90(屏幕逆时针90度), -90(屏幕顺时针90度) | 1.7.0 | |
show-progress | Boolean | true | 若不设置,宽度大于240时才会显示 | 1.9.0 |
show-fullscreen-btn | Boolean | true | 是否显示全屏按钮 | 1.9.0 |
show-play-btn | Boolean | true | 是否显示视频底部控制栏的播放按钮 | 1.9.0 |
show-center-play-btn | Boolean | true | 是否显示视频中间的播放按钮 | 1.9.0 |
enable-progress-gesture | Boolean | true | 是否开启控制进度的手势 | 1.9.0 |
objectFit | String | contain | 当视频大小与 video 容器大小不一致时,视频的表现形式。contain:包含,fill:填充,cover:覆盖 | |
poster | String | 视频封面的图片网络资源地址或云文件ID(2.2.3起支持)如果 controls 属性值为 false 则设置 poster 无效 | ||
bindplay | EventHandle | 当开始/继续播放时触发play事件 | ||
bindpause | EventHandle | 当暂停播放时触发 pause 事件 | ||
bindended | EventHandle | 当播放到末尾时触发 ended 事件 | ||
bindtimeupdate | EventHandle | 播放进度变化时触发,event.detail = {currentTime, duration} 。触发频率 250ms 一次 | ||
bindfullscreenchange | EventHandle | 视频进入和退出全屏时触发,event.detail = {fullScreen, direction},direction取为 vertical 或 horizontal | 1.4.0 | |
bindwaiting | EventHandle | 视频出现缓冲时触发 | 1.7.0 | |
binderror | EventHandle | 视频播放出错时触发 | 1.7.0 |
于是得到布局代码:
<!--pages/videoPlayer.wxml--> <view class="section"> <video src="{{videoItemSrc}}" controls ></video> </view> <view class='section course-series'> <text>{{course_series}}</text> </view> <view class='bound-section'></view> <view class='section'> <block wx:for="{{videoSeries}}" wx:key="*this"> <label class='course-video-item' id="{{index}}" bindtap='videoChooseClick'> <text>第{{item.episode}}集</text> <text class='video-item-name'>{{item.name}}</text> <view class='video-item-duration'> {{item.duration}} </view> <view class='bound-line'></view> </label> </block> </view> |
样式代码:
/* pages/vedioPlayer.wxss */ .section video{ width: 100%; } .course-series{ height: 100rpx; padding-left: 20rpx; border-left-width: 5rpx; border-left-color: greenyellow; border-left-style: solid; line-height: 100rpx; color: green; } .course-video-item{ height: 60rpx; padding-left: 20rpx; border-left-width: 5rpx; border-left-color: blue; border-left-style: solid; line-height: 60rpx; color: rgb(7, 145, 199); } .video-item-name{ padding-left: 20rpx; } .video-item-duration{ padding-left: 2rpx; text-align: right; } |
效果:
2、后台代码
(1)在main页面请求服务器获得视频信息
(2)格式化数据
(3)首页轮播图加载视频缩略图url
(4)点击对应轮播图把对应url所属的视频信息传给视频播放页面
(5)视频播放页面解析传过来的数据加载课程名称和集数信息
(6)点击集数列表的item时把当前集的url传给video组件即可播放
首页代码:
var Bmob = require("../../utils/Bmob-1.6.3.min.js"); data: { // 轮播图对应视频信息 videoData: [], // 轮播图对应图片地址 videoImgUrls:[] } , //轮播图点击事件 swiperItemClick:function(e){ var vedioSeries = new Array(); var index = 0; // 判断是同一个系列课程 for(var i=0;i<this.data.videoData.length;i++){ if (this.data.videoData[i].series == this.data.videoImgUrls[e.currentTarget.id].series){ videoSeries[index++] = this.data.videoData[i]; } } // 把vedioSeries传给视频播放页面 wx.navigateTo({ url: '../videoPlayer/videoPlayer?videoSeries=' + JSON.stringify(videoSeries), }); } , //获得轮播的视频信息 getVideoInfo:function(){ wx.showToast({ title: '正在加载...', icon:'loading', duration:10000 }) let query = Bmob.Query('course_vedio'); query.find().then(res => { var imgUrls = new Array(); for (var i = 0; i < res.length; i++) { if (res[i].thumbnail != null && imgUrls.indexOf(res[i].series) == -1) imgUrls[i] = res[i]; } wx.hideToast(); that.setData({ videoData: res, videoImgUrls: imgUrls }); }); } |
注意,现在引入Bmob服务器的sdk,要在app.js中初始化:
Bmob.initialize("xxx", "xxx"); |
详情请查看bmob官方网站https://www.bmob.cn/。
vedioPlayer.js代码:
// pages/vedioPlayer.js var Bmob = require("../../utils/Bmob-1.6.3.min.js"); var that;
Page({ /** * 页面的初始数据 */ data: { videoItemSrc:null, course_series:null, videoSeries:[] }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { var series = JSON.parse(options.videoSeries); this.setData({ videoItemSrc: series[0].video.url,course_series: series[0].series,videoSeries : series}); }, videoChooseClick:function(e){ this.setData({ videoItemSrc: this.data.videoSeries[e.target.id].video.url}); } }) |
下篇将介绍签到的逻辑及代码实现。