hadss_adaptive_video 1.0.0-rc.0 copy "hadss_adaptive_video: ^1.0.0-rc.0" to clipboard
hadss_adaptive_video: ^1.0.0-rc.0 copied to clipboard

A adaptive short video immersion and rotation rule plugin project.

example/lib/main.dart

/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import 'package:example/video_page.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:hadss_adaptive_video/hadss_adaptive_video.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(ChangeNotifierProvider(
      create: (context) => AppState(), child: const MyApp()));
}

class AppState with ChangeNotifier {
  double _topBlankHeight = 0.0;

  double get topBlankHeight => _topBlankHeight;

  set topBlankHeight(double height) {
    _topBlankHeight = height;
    notifyListeners();
  }

  double _bottomBlankHeight = 0.0;

  set bottomBlankHeight(double height) {
    _bottomBlankHeight = height;
    notifyListeners();
  }

  double get bottomBlankHeight => _bottomBlankHeight;

  Color _bottomNavColor = Colors.transparent;

  Color get bottomNavColor => _bottomNavColor;

  set bottomNavColor(Color color) {
    _bottomNavColor = color;
    notifyListeners();
  }

  double _currentVideoWidth = 0.0;

  double get currentVideoWidth => _currentVideoWidth;

  set currentVideoWidth(double width) {
    _currentVideoWidth = width;
    notifyListeners();
  }

  double _currentVideoHeight = 0.0;

  double get currentVideoHeight => _currentVideoHeight;

  set currentVideoHeight(double height) {
    _currentVideoHeight = height;
    notifyListeners();
  }

  double defaultBottomNavHeight = 0.0;
  double defaultTopHeight = 0.0;
}

final RouteObserver<ModalRoute<dynamic>> routeObserver =
    RouteObserver<ModalRoute<dynamic>>();

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    // 应用默认支持自由旋转
    WidgetsFlutterBinding.ensureInitialized();
    SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      navigatorObservers: [routeObserver],
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final List<IconData> _icons = [
    Icons.video_library,
    Icons.search,
    Icons.person
  ];
  final List<String> _labels = ['首页', '搜索', '个人'];
  late List<String> _videoDataList = [
    'assets/videos/4_3.mp4',
    'assets/videos/1_1.mp4',
    'assets/videos/9_16_1.mp4',
    'assets/videos/9_16_2.mp4',
    'assets/videos/16_9.mp4',
    'assets/videos/3_4.mp4'
  ];

  @override
  void initState() {
    super.initState();
    AdaptiveRotation().registerEvent();
    SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
    SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
      statusBarColor: Colors.transparent,
      statusBarIconBrightness: Brightness.light,
    ));
    // 进入页面先设置状态栏和底部导航的高度
    WidgetsBinding.instance.addPostFrameCallback((_) {
      Provider.of<AppState>(context, listen: false).defaultBottomNavHeight =
          56.0 + MediaQuery.of(context).padding.bottom;
      Provider.of<AppState>(context, listen: false).defaultTopHeight =
          MediaQuery.of(context).padding.top;
      // 设置顶部部空白占位高度
      Provider.of<AppState>(context, listen: false).topBlankHeight =
          MediaQuery.of(context).padding.top;
      // 设置底部空白占位高度
      Provider.of<AppState>(context, listen: false).bottomBlankHeight =
          56.0 + MediaQuery.of(context).padding.bottom;
      // 设置底部导航栏颜色
      Provider.of<AppState>(context, listen: false).bottomNavColor =
          Colors.black;
    });
    if (kIsWeb) {
      _videoDataList = [
        'videos/4_3.mp4',
        'videos/1_1.mp4',
        'videos/9_16_1.mp4',
        'videos/9_16_2.mp4',
        'videos/16_9.mp4',
        'videos/21_9.mp4'
      ];
    }
  }

  @override
  void dispose() {
    super.dispose();
    AdaptiveRotation().unregisterEvent();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Stack(
      children: [
        Align(
            alignment: Alignment.topCenter,
            child: Consumer(builder: (context, AppState state, Widget? child) {
              return Container(
                width: double.infinity,
                height: double.infinity,
                color: Colors.black,
                child: Column(
                  children: [
                    SizedBox(
                      width: double.infinity,
                      height: state.topBlankHeight,
                    ),
                    Expanded(
                      child: PageView.builder(
                          scrollDirection: Axis.vertical,
                          itemCount: _videoDataList.length,
                          pageSnapping: true,
                          itemBuilder: (context, index) {
                            return VideoPlayerPage(
                              videoUrl: _videoDataList[index],
                            );
                          }),
                    ),
                    SizedBox(
                      width: double.infinity,
                      height: state.bottomBlankHeight,
                    )
                  ],
                ),
              );
            })),
        Align(alignment: Alignment.bottomCenter, child: _bottomNav())
      ],
    ));
  }

  Widget _bottomNav() {
    return Consumer(builder: (context, AppState state, Widget? child) {
      return Container(
        decoration: const BoxDecoration(
          border: Border(
              top: BorderSide(
            color: Colors.green,
            width: 2,
          )),
        ),
        child: Container(
          width: double.infinity,
          height: state.defaultBottomNavHeight,
          color: state.bottomNavColor,
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: List.generate(_icons.length, (index) {
              return _buildNavItem(_icons[index], _labels[index]);
            }),
          ),
        ),
      );
    });
  }

  Widget _buildNavItem(IconData icon, String label) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 6.0),
      child: Column(children: [
        Icon(
          icon,
          color: Colors.white,
          size: 20,
        ),
        Text(
          label,
          style: const TextStyle(color: Colors.white, fontSize: 16),
        )
      ]),
    );
  }
}
1
likes
140
points
20
downloads

Publisher

unverified uploader

Weekly Downloads

A adaptive short video immersion and rotation rule plugin project.

Homepage
Repository

Topics

#adaptive #immersion #rotation #video

Documentation

Documentation
API reference

License

Apache-2.0 (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on hadss_adaptive_video

Packages that implement hadss_adaptive_video