zhenghy

沉浸式视频代码提交

... ... @@ -15,15 +15,17 @@ export class Size {
export class WindowModel {
private windowStage?: window.WindowStage;
static shared: WindowModel = new WindowModel()
static TAG = "WindowModel";
setWindowStage(windowStage: window.WindowStage) {
this.windowStage = windowStage;
}
getWindowStage(): window.WindowStage {
return this.windowStage as window.WindowStage
}
setMainWindowFullScreen(fullScreen: boolean) {
if (deviceInfo.deviceType != "phone") {
return
... ... @@ -65,10 +67,10 @@ export class WindowModel {
windowClass.setWindowKeepScreenOn(isKeepScreenOn, (err: BusinessError) => {
const errCode: number = err.code;
if (errCode) {
console.error(WindowModel.TAG +'设置屏幕常亮:' + isKeepScreenOn + ',失败: ' + JSON.stringify(err));
console.error(WindowModel.TAG + '设置屏幕常亮:' + isKeepScreenOn + ',失败: ' + JSON.stringify(err));
return;
}
console.info(WindowModel.TAG +'设置屏幕常亮:' + isKeepScreenOn + ",成功");
console.info(WindowModel.TAG + '设置屏幕常亮:' + isKeepScreenOn + ",成功");
})
})
}
... ...
... ... @@ -14,6 +14,7 @@
"wdKit": "file:../../commons/wdKit",
"wdWebComponent": "file:../../commons/wdWebComponent",
"wdBean": "file:../../features/wdBean",
"wdDetailPlayShortVideo": "file:../../features/wdDetailPlayShortVideo",
"wdRouter": "file:../../commons/wdRouter",
"wdNetwork": "file:../../commons/wdNetwork"
}
... ...
... ... @@ -7,16 +7,24 @@ import { CompUtils } from '../../utils/CompUtils';
import PageViewModel from '../../viewmodel/PageViewModel';
const TAG = 'BottomNavigationComponent';
let storage = LocalStorage.getShared();
/**
* 底部页签导航栏/底导
*/
@Entry(storage)
@Component
export struct BottomNavigationComponent {
@Provide bottomRectHeight: number = 0
@Provide topRectHeight: number = 0
@Provide isLayoutFullScreen: boolean = false
@State bottomSafeHeight: number = AppStorage.get<number>('bottomSafeHeight') || 0
@State topSafeHeight: number = AppStorage.get<number>('topSafeHeight') || 0
// 底导/顶导全部数据
@State @Watch('onBottomNavigationDataUpdated') bottomNavList: BottomNavDTO[] = []
// 底导当前选中/焦点下标
@State currentNavIndex: number = BottomNavi.NEWS;
@State barBackgroundColor: Color = Color.Transparent
// 底导TabsController
private navController: TabsController = new TabsController();
readonly ASPECT_RATIO_1_1: number = 1 / 1; // 底导图片宽高比
... ... @@ -51,20 +59,44 @@ export struct BottomNavigationComponent {
// 我的页面组件数据列表
MinePageComponent()
} else {
TopNavigationComponent({ topNavList: navItem.topNavChannelList, _currentNavIndex: this.currentNavIndex })
TopNavigationComponent({
topNavList: navItem.topNavChannelList,
_currentNavIndex: this.currentNavIndex,
changeBarBackgroundColor: (color: Color) => {
this.barBackgroundColor = color
}
})
}
}
}
.tabBar(this.tabBarBuilder(navItem, index))
});
}
.barHeight($r('app.float.bottom_navigation_barHeight'))
.barMode(BarMode.Fixed)
// TODO:更详细的判断是视频频道
.barBackgroundColor(this.barBackgroundColor)
.onChange((index: number) => {
Logger.info(TAG, `onChange, index: ${index}`);
this.currentNavIndex = index;
// this.onBottomNavigationIndexChange()
})
.backgroundColor(this.barBackgroundColor)
.padding({ bottom: this.bottomRectHeight + 'px', top: this.topRectHeight + 'px' }) // 此处margin具体数值在实际中应与导航条区域高度保持一致
}
/**
* TODO:更详细的判断视频频道
*/
getFontColor(index: number): Color {
if (this.currentNavIndex === 2 && this.barBackgroundColor === Color.Black) {
return Color.White
} else {
return this.currentNavIndex === index ? Color.Red : Color.Gray
}
}
@Builder
... ... @@ -79,8 +111,8 @@ export struct BottomNavigationComponent {
.margin({ bottom: $r('app.float.bottom_navigation_margin_bottom') })
.fontWeight(this.currentNavIndex === index ? FontWeight.Bold : FontWeight.Normal)
.textAlign(TextAlign.Center)
.fontSize($r('app.float.font_size_10'))
.fontColor(this.currentNavIndex === index ? Color.Red : Color.Gray)
.fontSize($r('app.float.font_size_10'))// .fontColor(this.currentNavIndex === index ? Color.Red : Color.Gray)
.fontColor(this.getFontColor(index))
.opacity(this.currentNavIndex === index ? this.FULL_OPACITY : this.SIXTY_OPACITY)
}
.height($r('app.float.bottom_navigation_barHeight'))
... ...
... ... @@ -12,6 +12,7 @@ import LoadMoreLayout from './LoadMoreLayout';
import CustomRefreshLoadLayout from './CustomRefreshLoadLayout';
import { CompParser } from '../CompParser';
import { CompDTO } from 'wdBean';
import { VideoChannelDetail } from 'wdDetailPlayShortVideo/Index';
const TAG = 'PageComponent';
... ... @@ -21,6 +22,7 @@ export struct PageComponent {
navIndex: number = 0;
pageId: string = "";
channelId: string = "";
name: string = "";
@Link @Watch('onChange') currentTopNavSelectedIndex: number
build() {
... ... @@ -62,7 +64,12 @@ export struct PageComponent {
LazyForEach(this.pageModel.compList, (compDTO: CompDTO, compIndex: number) => {
ListItem() {
Column() {
CompParser({ compDTO: compDTO, compIndex: compIndex });
if (this.name == '视频') {
VideoChannelDetail()
} else {
CompParser({ compDTO: compDTO, compIndex: compIndex });
}
}
}
},
... ... @@ -94,8 +101,10 @@ export struct PageComponent {
@Builder
LoadingLayout() {
CustomRefreshLoadLayout({ refreshBean: new RefreshLayoutBean(true,
$r('app.media.ic_pull_up_load'), $r('app.string.pull_up_load_text'), this.pageModel.pullDownRefreshHeight) })
CustomRefreshLoadLayout({
refreshBean: new RefreshLayoutBean(true,
$r('app.media.ic_pull_up_load'), $r('app.string.pull_up_load_text'), this.pageModel.pullDownRefreshHeight)
})
}
async aboutToAppear() {
... ...
... ... @@ -4,21 +4,34 @@ import { WDRouterRule } from 'wdRouter';
import { PageComponent } from './PageComponent';
import { ChannelSubscriptionLayout } from './ChannelSubscriptionLayout';
import { FirstTabTopSearchComponent } from '../search/FirstTabTopSearchComponent';
import window from '@ohos.window';
import { WindowModel } from 'wdKit';
const TAG = 'TopNavigationComponent';
PersistentStorage.persistProp('channelIds', '');
PersistentStorage.persistProp('indexSettingChannelId', 0);
const storage = LocalStorage.getShared();
/**
* 顶部页签导航栏/顶导
*/
@Entry(storage)
@Component
export struct TopNavigationComponent {
private tabsController: TabsController = new TabsController()
@Prop _currentNavIndex?: number;
private changeBarBackgroundColor: (color: Color) => void = () => {
}
@Consume isLayoutFullScreen: boolean
@Consume bottomRectHeight: number
@Consume topRectHeight: number
@State bottomSafeHeight: number = AppStorage.get<number>('bottomSafeHeight') || 0
@State topSafeHeight: number = AppStorage.get<number>('topSafeHeight') || 0
@State barBackgroundColor: Color = Color.Transparent
@Prop @Watch('indexChange') _currentNavIndex?: number;
// 顶导当前选中/焦点下标
@State currentTopNavSelectedIndex: number = 0;
@State @Watch('indexChange') currentTopNavSelectedIndex: number = 0;
// 顶导数据
@State @Watch('onTopNavigationDataUpdated') topNavList: TopNavDTO[] = []
@State compList: LazyDataSource<CompDTO> = new LazyDataSource();
... ... @@ -135,6 +148,40 @@ export struct TopNavigationComponent {
WDRouterRule.jumpWithAction(taskAction)
}
indexChange() {
if (this._currentNavIndex === 2 && this.currentTopNavSelectedIndex === 0 && this.changeBarBackgroundColor) {
this.barBackgroundColor = Color.Black
this.changeBarBackgroundColor(this.barBackgroundColor)
} else {
this.barBackgroundColor = Color.Transparent
this.changeBarBackgroundColor(this.barBackgroundColor)
}
if (this._currentNavIndex === 2 && this.currentTopNavSelectedIndex == 0) {
if (!this.isLayoutFullScreen) {
const windowStage = WindowModel.shared.getWindowStage() as window.WindowStage
const windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口
windowClass.setWindowLayoutFullScreen(true).then(() => {
this.isLayoutFullScreen = true
this.bottomRectHeight = this.bottomSafeHeight
this.topRectHeight = this.topSafeHeight
})
}
} else {
if (this.isLayoutFullScreen) {
const windowStage = WindowModel.shared.getWindowStage() as window.WindowStage
const windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口
windowClass.setWindowLayoutFullScreen(false).then(() => {
this.isLayoutFullScreen = false
this.bottomRectHeight = 0
this.topRectHeight = 0
console.error(' this.isLayoutFullScreen ', this.isLayoutFullScreen)
})
}
}
}
build() {
Column() {
// 顶部搜索、日报logo、早晚报
... ... @@ -145,7 +192,7 @@ export struct TopNavigationComponent {
Image($r('app.media.icon_ren_min_ri_bao'))
.width(72)
.height(29)
.onClick(()=>{
.onClick(() => {
this.jumpToENewPaper()
})
Stack({ alignContent: Alignment.Center }) {
... ... @@ -194,16 +241,20 @@ export struct TopNavigationComponent {
currentTopNavSelectedIndex: $currentTopNavSelectedIndex,
navIndex: index,
pageId: navItem.pageId + '',
channelId: navItem.channelId + ''
channelId: navItem.channelId + '',
name: navItem.name
})
}
}
.tabBar(this.tabBarBuilder(navItem, index))
}, (navItem: TopNavDTO) => JSON.stringify(navItem));
}
.barHeight($r('app.float.top_tab_bar_height'))
.barMode(BarMode.Scrollable)
.vertical(false)
// item.name === '视频' && this.currentTopNavSelectedIndex === 0 ?
.barBackgroundColor(this.barBackgroundColor)
.onChange((index: number) => {
Logger.info(TAG, `onChange index : ${index}`);
if (!this.isBroadcast(this._currentNavIndex === 0 ? this.myChannelList[index] : this.topNavList[index]) &&
... ... @@ -245,7 +296,21 @@ export struct TopNavigationComponent {
})
}
}
}
}
/**
* TODO:更详细的判断视频频道
*/
getFontColor(item: TopNavDTO, index: number): Color | string {
if (this._currentNavIndex === 2) {
if (this.currentTopNavSelectedIndex == 0) {
return item.name === '视频' ? Color.White : '#e5e0e0'
} else {
return this.currentTopNavSelectedIndex === index ? Color.Black : Color.Gray
}
} else {
return this.currentTopNavSelectedIndex === index ? Color.Black : Color.Gray
}
}
... ... @@ -255,7 +320,7 @@ export struct TopNavigationComponent {
Text(item.name)
.fontSize(this.currentTopNavSelectedIndex === index ? $r('app.float.selected_text_size') : $r('app.float.normal_text_size'))
.fontWeight(this.currentTopNavSelectedIndex === index ? FontWeight.Bold : FontWeight.Normal)
.fontColor(Color.Black)
.fontColor(this.getFontColor(item, index))
.padding({ top: $r('app.float.top_tab_item_padding_top') })
.maxLines(this.MAX_LINE)
Divider()
... ... @@ -271,7 +336,7 @@ export struct TopNavigationComponent {
maxWidth: $r('app.float.top_tab_item_max_width')
})
// .margin({ right: 36 })
// .backgroundColor(Color.Black)
.backgroundColor(Color.Transparent)
.padding({
left: $r('app.float.top_tab_item_padding_horizontal'),
right: $r('app.float.top_tab_item_padding_horizontal'),
... ...
export { DetailPlayShortVideoPage } from './src/main/ets/pages/DetailPlayShortVideoPage'
\ No newline at end of file
export { DetailPlayShortVideoPage } from './src/main/ets/pages/DetailPlayShortVideoPage'
export { DetailVideoListPage } from './src/main/ets/pages/DetailVideoListPage'
export { VideoChannelDetail } from './src/main/ets/pages/VideoChannelDetail'
export { LottieViewDemo } from './src/main/ets/pages/LottieViewDemo'
\ No newline at end of file
... ...
... ... @@ -14,6 +14,6 @@
"wdRouter": "file:../../commons/wdRouter",
"wdNetwork": "file:../../commons/wdNetwork",
"wdDetailPlayApi": "file:../../features/wdDetailPlayApi",
"wdComponent": "file:../../features/wdComponent"
// "wdComponent": "file:../../features/wdComponent"
}
}
... ...
... ... @@ -140,6 +140,7 @@ export struct DetailPlayShortVideoPage {
aboutToDisappear(): void {
console.log('aboutToDisappear', this.index)
this.playerController?.pause()
this.playerController?.release();
// this.playerController.onCanplay = ()={}
}
... ... @@ -160,7 +161,7 @@ export struct DetailPlayShortVideoPage {
// console.log('onload==', this.index)
// if (this.index === 0) {
if(this.contentDetailData!=null && this.contentDetailData?.videoInfo[0]!=null){
if (this.contentDetailData != null && this.contentDetailData?.videoInfo[0] != null) {
this.playerController.firstPlay(this.contentDetailData.videoInfo[0].videoUrl);
}
// }
... ... @@ -211,5 +212,7 @@ export struct DetailPlayShortVideoPage {
.height('100%')
.width('100%')
.backgroundColor(Color.Black)
// 扩展至所有非安全区域
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
}
}
\ No newline at end of file
... ...
... ... @@ -2,15 +2,18 @@ import { Action, ContentDetailDTO, InteractDataDTO } from 'wdBean/Index';
import { ContentDetailRequest } from 'wdDetailPlayApi/Index'
import { ResponseDTO } from 'wdNetwork/Index';
import { DetailPlayShortVideoPage } from './DetailPlayShortVideoPage'
import { Test } from './Test'
import router from '@ohos.router';
import window from '@ohos.window';
import { contentListParams } from 'wdDetailPlayApi/src/main/ets/request/ContentDetailRequest';
import window from '@ohos.window';
import { WindowModel } from 'wdKit';
const storage = LocalStorage.getShared();
@Entry
@Entry(storage)
@Component
export struct DetailVideoListPage {
@State bottomSafeHeight: number = AppStorage.get<number>('bottomSafeHeight') || 0
@State topSafeHeight: number = AppStorage.get<number>('topSafeHeight') || 0
private contentId: string = ''
private relId: string = ''
private relType: string = ''
... ... @@ -21,6 +24,14 @@ export struct DetailVideoListPage {
@State interactDataList: InteractDataDTO[] = []
async aboutToAppear(): Promise<void> {
const windowStage = WindowModel.shared.getWindowStage() as window.WindowStage
const windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口
windowClass.setWindowLayoutFullScreen(true)
windowClass.setWindowSystemBarProperties({ statusBarColor: '#fff' })
let data: ContentDetailDTO[] = []
let action: Action = router.getParams() as Action
if (action) {
... ... @@ -83,6 +94,15 @@ export struct DetailVideoListPage {
}
aboutToDisappear(): void {
const windowStage = WindowModel.shared.getWindowStage() as window.WindowStage
const windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口
windowClass.setWindowLayoutFullScreen(false)
windowClass.setWindowSystemBarProperties({ statusBarColor: '#000' })
}
/**
* 查询视频列表用于翻页
*/
... ... @@ -112,16 +132,17 @@ export struct DetailVideoListPage {
})
}.width('100%')
.height('100%')
// 扩展至所有非安全区域
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
}, (item: ContentDetailDTO) => item.newsId + '')
}
.clip(false)
.cachedCount(-1)
.indicator(false)
.vertical(true)
.loop(false)
.width('100%')
.height('100%')
// 扩展至所有非安全区域
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
.onChange((index: number) => {
this.currentIndex = index
console.info('onChange==', index.toString())
... ... @@ -130,7 +151,6 @@ export struct DetailVideoListPage {
this.queryVideoList()
}
})
}.width('100%').height('100%')
}.width('100%').height('100%').backgroundColor(Color.Black).padding({ bottom: this.bottomSafeHeight + 'px' })
}
}
\ No newline at end of file
... ...
import { AnimationItem } from '@ohos/lottie'
import { LottieView } from 'wdComponent/Index'
// import { LottieView } from 'wdComponent/Index'
@Component
... ... @@ -16,16 +17,16 @@ export struct LottieViewDemo {
.fontColor(Color.White)
.borderRadius(10)
.fontWeight(500)
LottieView({
name: 'lottieDemo',
path: 'common/lottie/politeChicky.json',
onReady: (animateItem: AnimationItem | null) => {
this.animateItem = animateItem
},
onComplete: () => {
console.log('onComplete===')
}
})
// LottieView({
// name: 'lottieDemo',
// path: 'common/lottie/politeChicky.json',
// onReady: (animateItem: AnimationItem | null) => {
// this.animateItem = animateItem
// },
// onComplete: () => {
// console.log('onComplete===')
// }
// })
}
.width(200)
.height(200)
... ...
... ... @@ -20,26 +20,26 @@ export struct VideoChannelDetail {
@State interactDataList: InteractDataDTO[] = []
async aboutToAppear(): Promise<void> {
let data: ContentDetailDTO[] = []
let action: Action = router.getParams() as Action
if (action) {
this.contentId = action.params?.contentID || ''
if (action.params && action.params.extra) {
this.relId = action.params.extra.relId || ''
this.relType = action.params.extra.relType || ''
}
await ContentDetailRequest.getContentDetail({
contentId: this.contentId,
relId: this.relId,
relType: this.relType
}).then((resDTO: ResponseDTO<ContentDetailDTO[]>) => {
console.error('resDTO==', JSON.stringify(resDTO.data))
if (resDTO.data) {
this.data.push(resDTO.data[0])
}
})
}
// let data: ContentDetailDTO[] = []
// let action: Action = router.getParams() as Action
// if (action) {
// this.contentId = action.params?.contentID || ''
// if (action.params && action.params.extra) {
// this.relId = action.params.extra.relId || ''
// this.relType = action.params.extra.relType || ''
// }
// await ContentDetailRequest.getContentDetail({
// contentId: this.contentId,
// relId: this.relId,
// relType: this.relType
// }).then((resDTO: ResponseDTO<ContentDetailDTO[]>) => {
// console.error('resDTO==', JSON.stringify(resDTO.data))
// if (resDTO.data) {
// this.data.push(resDTO.data[0])
// }
//
// })
// }
await this.queryVideoList()
... ... @@ -97,10 +97,17 @@ export struct VideoChannelDetail {
})
}
aboutToDisappear(): void {
}
onPageHide(): void {
}
build() {
Column() {
Swiper(this.swiperController) {
ForEach(this.data, (item: ContentDetailDTO, index: number) => {
Column() {
DetailPlayShortVideoPage({
... ...
... ... @@ -12,6 +12,7 @@
"wdKit": "file:../../commons/wdKit",
"wdWebComponent": "file:../../commons/wdWebComponent",
"wdBean": "file:../../features/wdBean",
"wdDetailPlayShortVideo": "file:../../features/wdDetailPlayShortVideo",
"wdRouter": "file:../../commons/wdRouter",
"wdNetwork": "file:../../commons/wdNetwork"
}
... ...
... ... @@ -23,6 +23,18 @@ export default class EntryAbility extends UIAbility {
// Main window is created, set main page for this ability
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
WindowModel.shared.setWindowStage(windowStage);
// 2. 获取布局避让遮挡的区域
const windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口
const TYPE_NAVIGATION_INDICATOR = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR; // 以导航条避让为例
const TYPE_SYSTEM = window.AvoidAreaType.TYPE_SYSTEM; // 以导航条避让为例
const NAV_AREA = windowClass.getWindowAvoidArea(TYPE_NAVIGATION_INDICATOR);
const SYSTEM_AREA = windowClass.getWindowAvoidArea(TYPE_SYSTEM);
const bottomSafeHeight = NAV_AREA.bottomRect.height; // 获取到导航条区域的高度
const topSafeHeight = SYSTEM_AREA.topRect.height; // 获取到状态栏区域的高度
AppStorage.setOrCreate('bottomSafeHeight', bottomSafeHeight);
AppStorage.setOrCreate('topSafeHeight', topSafeHeight);
// let a = new WindowModel();
// 设置窗口的显示方向属性
WindowModel.shared.setPreferredOrientation(window.Orientation.PORTRAIT)
... ...