LoadingController

本文介绍了一个游戏加载场景的具体实现过程,包括加载控制器的设计、资源异步加载方式、加载进度显示等核心功能。此外,还详细解释了如何在加载完成后进行场景切换及资源清理。
--local MainSceneConfig = require "res.scripts.configs.MainSceneConfig" -- 暂时添加一个临时配置文件
--require "res.scripts.scenes.MainScene"

-- 加载事件
OnLoadingStart         = "OnLoadingStart";
OnLoadingProcess     = "OnLoadingProcess";
OnLoadingEnd         = "OnLoadingEnd";

-- 加载类型
SOUNDTYPE = "sounds";
TEXTURETYPE = "textures";
ATLASTYPE = "atlas";
ANIMATIONTYPE = "animations";
EFFECTTYPE   = "effects";

-- 加载控制逻辑
local LoadingController = class("LoadingController", Behavior);

function LoadingController:ctor(sceneName)
    LoadingController.super.ctor(self);

    -- 定义成员变量
    self.progress = 0; -- 加载进度
    self.totalLoadingNum = 0; --加载总数数量
    self.curLoadingNum = 0;  -- 当前加载数量
    self.loadingConfig = ""; -- 资源配置文件

    self.log = nil;        -- 加载界面log    
    self.btmLabel = nil; --进度显示标签    
    self.uiLayout = nil; -- 加载界面布局
    self.uiLayer = nil; -- 加载界面层
    self.curScene = nil; -- 上一个场景
    self.nextScene = nil; -- 下一个场景
    self.config = res[sceneName];-- 配置文件
    self.curSceneName = sceneName; 

    self.isLoaded = false;

    -- 随机抽取一只怪物
    local animKeys = table.keys(res.animations);
    if #animKeys > 0 then
        local index = math.random(1, #animKeys);
        self.animName = tostring(animKeys[index]);
        self.loadingxml = res.animations[self.animName];
        self.loadingplist = string.gsub(self.loadingxml, ".xml", ".plist")
        self.loadingpng = string.gsub (self.loadingxml, ".xml", ".png")
    end
end

function LoadingController:run(  )
    self.curScene = SceneM.getRunningScene();
    self.nextScene = nil;

    -- 1.ui层
    self.uiLayer = ObjectFactory.newLayer();
    self.uiLayer:setColor(ccc3(0, 0, 0));

    -- 2.创建构成加载场景的元素
    self.btmLabel = ObjectFactory.newBMFontLabel({text = "Loading 0%", font = res.fonts.UIFont,})
    self.btmLabel:setPosition(ccp(Screen.cx, Screen.cy - 80));
    self.uiLayer:addChild(self.btmLabel);
    if self.loadingxml then
        CCArmatureDataManager:sharedArmatureDataManager():addArmatureFileInfoAsync(self.loadingpng, self.loadingplist, self.loadingxml, function (  )
            if self.isLoaded then
                return;
            end
            local lion = ObjectFactory.newArmature(self.animName);
            lion:setPosition(ccp(Screen.cx,Screen.cy));
            lion:addParent(self.uiLayer);
            lion:getComponent("Animation"):play("run", WrapMode.Loop);
        end)
    end

    -- 3. 添加到场景
    SceneM.dontDestroy(self.uiLayer);

    -- 4. 关掉触摸消息
    CCDirector:sharedDirector():getTouchDispatcher():setDispatchEvents(false);

    -- 5. 关掉动作管理
    CCDirector:sharedDirector():getActionManager():removeAllActions();

    -- 6. 退出当前场景
    if self.curScene then
        self.curScene:setVisible(false);
    end

    -- 7. 重新初始化管理类
    SceneM.uiLayers = {};

    -- 8.延迟清除当前资源,并且加载下一个场景资源 
    performWithDelay(function (  )
        self:cleanup();
        self:startLoading(self.config);
    end, 0.01)

    -- 9. 回收lua内存
    collectgarbage("collect")
end

function LoadingController:startLoading(theloadingconfig)
    if theloadingconfig == nil then
        self.isLoaded = true;
            -- 切换场景
            self.nextScene = ObjectFactory.newScene(self.curSceneName);
            SceneM.curScene = self.nextScene;
            self.nextScene:addComponent(self.curSceneName,SceneM.getSceneController(self.curSceneName));
            
            -- 关闭加载层
            SceneM.destroy(self.uiLayer);

            -- 开启触摸消息
            CCDirector:sharedDirector():getTouchDispatcher():setDispatchEvents(true);

            -- 记录配置文件路径
            SceneM.lastSceneName = self.curSceneName;

            -- 切换到新场景
            SceneM.replaceScene(self.nextScene, "crossfade", 0.2, Screen.COLOR_WHITE);
        return;
    end
    print ("start loading")
    self.loadingConfig = theloadingconfig;
    local resTypes = {"sounds","textures","atlas","animations","effects"}
    local curIndex = 1;
    -- 1.开始当前场景加载资源
    self.curLoadingNum = 0
    local totalNum  = 0
    local function loopRes( t , resType)
        if self.curLoadingNum > self.totalLoadingNum then
            return;
        end
        if t == nil then
            curIndex = curIndex + 1;
            local resType = resTypes[curIndex];
            print("加载类型:",resType);
            print("加载:",theloadingconfig[resType]);
            loopRes(theloadingconfig[resType], resType);
            return;
        end
        local keys = table.keys(t);
        totalNum = totalNum + #keys;
        local tempIndex = 1;
        local function loadRes(  )
            self.curLoadingNum = self.curLoadingNum + 1;
            if self.curLoadingNum > self.totalLoadingNum then
                return;
            end
            --print("====",self.curLoadingNum , totalNum)
            if self.curLoadingNum > totalNum then
                tempIndex = 1;
                curIndex = curIndex + 1;
                local resType = resTypes[curIndex];
                self.curLoadingNum = self.curLoadingNum - 1;
                loopRes(theloadingconfig[resType], resType);
                return;
            end
            local key = keys[tempIndex];
            local value = t[key];
            tempIndex = tempIndex + 1;
            if (tolua.type(value) == "table") then
                loopRes( value );
            elseif (tolua.type(value) == "string") then
                if resType == SOUNDTYPE then
                    -- 1.异步声音加载
                    --print("加载声音:", value);
                    Audio.preloadEffect(value);
                    performWithDelay(function (  )
                        loadRes();
                    end, CCDirector:sharedDirector():deltaTime())
                end

                if resType == TEXTURETYPE then
                    -- 2.异步纹理加载
                    --print("加载纹理:", value);
                    CCTextureCache:sharedTextureCache():addImageAsync(value, function ( )
                        self:CheckedResLoaded(); -- 检测下是否加载完毕
                        performWithDelay(function (  )
                            loadRes();
                        end, CCDirector:sharedDirector():deltaTime())
                    end);
                end

                if resType == ATLASTYPE then
                    -- 2.异步纹理加载
                    local png = string.gsub(value, ".plist", ".png")
                    --print("加载图集:",png);
                    CCTextureCache:sharedTextureCache():addImageAsync(png, function ( )
                        -- 添加plist 到 CCSpriteFrameCache
                        CCSpriteFrameCache:sharedSpriteFrameCache():addSpriteFramesWithFile(value)
                        self:CheckedResLoaded(); -- 检测下是否加载完毕
                        performWithDelay(function (  )
                            loadRes();
                        end, CCDirector:sharedDirector():deltaTime())
                    end);
                end

                if resType == ANIMATIONTYPE or resType == EFFECTTYPE then
                    --3.异步动画加载
                    local plist = string.gsub(value, ".xml", ".plist")
                    local png = string.gsub (value, ".xml", ".png")
                    --print("加载骨骼动画:",png, plist, value);
                    CCArmatureDataManager:sharedArmatureDataManager():addArmatureFileInfoAsync(png, plist, value, function (  )
                        self:CheckedResLoaded(); -- 检测下是否加载完毕
                        performWithDelay(function (  )
                            loadRes();
                        end, CCDirector:sharedDirector():deltaTime())
                    end)
                end
            end
        end

        loadRes();
    end
    -- 计算加载的资源总数
    local function size( config )
        return #table.keys(config.textures) 
        + #table.keys(config.sounds) 
        + #table.keys(config.fonts) 
        + #table.keys(config.animations)
        + #table.keys(config.atlas)
        + #table.keys(config.effects);
    end
    self.totalLoadingNum = size(theloadingconfig);

    -- 加载场景资源
    local resType = resTypes[curIndex];
    print("加载类型:",resType);
    print("加载:",theloadingconfig[resType]);
    loopRes(theloadingconfig[resType], resType);
end

-- 检测是否加载完毕
function LoadingController:CheckedResLoaded(  )
    if self.curLoadingNum <= self.totalLoadingNum then
        -- 1.更新当前进度
        local percent = math.modf(self.curLoadingNum * 100 / self.totalLoadingNum)
        self.btmLabel:setString(string.format("Loading %s%%", percent));
    end

    -- 2.检测下是否加载完毕
    if (self.curLoadingNum == self.totalLoadingNum) then
        local function onComplete(event)
            print ("loading res finished!")
            self.isLoaded = true;
            -- 切换场景
            self.nextScene = ObjectFactory.newScene(self.curSceneName);
            SceneM.curScene = self.nextScene;
            self.nextScene:addComponent(self.curSceneName,SceneM.getSceneController(self.curSceneName));
            
            -- 关闭加载层
            SceneM.destroy(self.uiLayer);

            -- 开启触摸消息
            CCDirector:sharedDirector():getTouchDispatcher():setDispatchEvents(true);

            -- 记录配置文件路径
            SceneM.lastSceneName = self.curSceneName;

            -- 切换到新场景
            SceneM.replaceScene(self.nextScene, "crossfade", 0.2, Screen.COLOR_WHITE);
        end
        -- 等待一帧 不然最后一次无法绘制
        performWithDelay(onComplete, CCDirector:sharedDirector():deltaTime() * 2);
    end
end

-- 清理资源
function LoadingController:cleanup(  )
    CCDirector:sharedDirector():getActionManager():removeAllActions();
    -- 获得上一个场景配置,根据配置删除
    if SceneM.lastSceneName then
        local lastConfig = res[SceneM.lastSceneName];
        local function removeRes( t , resType)
            if t == nil or type(t) ~= "table" then
                return;
            end
            for key, value in pairs(t) do    
                 if (tolua.type(value) == "table") then
                    loopRes( value );
                elseif (tolua.type(value) == "string") then
                    if resType == SOUNDTYPE then
                        -- 1.删除声音
                        Audio.unloadSound(value);
                    end

                    if resType == TEXTURETYPE then
                        -- 2.删除纹理
                        CCTextureCache:sharedTextureCache():removeTextureForKey(value);
                    end

                    if resType == ATLASTYPE then
                        -- 3.删除plist纹理
                        CCSpriteFrameCache:sharedSpriteFrameCache():removeSpriteFramesFromFile(value);
                        value = string.gsub(value, ".plist", ".png");
                        CCTextureCache:sharedTextureCache():removeTextureForKey(value);
                    end

                    if resType == ANIMATIONTYPE then
                        -- 4.删除动画
                        print("删除骨骼动画资源:",value);
                        value = string.gsub(value, ".xml", ".png");
                        CCTextureCache:sharedTextureCache():removeTextureForKey(value); 
                        value = string.gsub(value, ".png", ".plist");
                        CCSpriteFrameCache:sharedSpriteFrameCache():removeSpriteFramesFromFile(value); 
                        --CCArmatureDataManager:purge();
                    end
                end
            end 
        end
        removeRes(lastConfig.sounds, SOUNDTYPE);          --删除声音资源
        removeRes(lastConfig.textures, TEXTURETYPE);       --删除纹理资源
        removeRes(lastConfig.atlas, ATLASTYPE);           --删除图集资源
        removeRes(lastConfig.animations, ANIMATIONTYPE);    --删除动画资源
        removeRes(lastConfig.effects, ANIMATIONTYPE);    --删除动画资源

        -- 移除临时动态公共资源
        if ResM.tempPathCache then
            removeRes(ResM.tempPathCache.sounds, SOUNDTYPE);          --删除声音资源
            removeRes(ResM.tempPathCache.textures, TEXTURETYPE);       --删除纹理资源
            removeRes(ResM.tempPathCache.atlas, ATLASTYPE);           --删除图集资源
            removeRes(ResM.tempPathCache.animations, ANIMATIONTYPE);    --删除动画资源
        end
        ResM.init();
        
        CCTextureCache:sharedTextureCache():dumpCachedTextureInfo();
    end
    
    -- CCSpriteFrameCache:purgeSharedSpriteFrameCache();
    -- CCTextureCache:sharedTextureCache():removeAllTextures();
    -- CCArmatureDataManager:purge();
end

return LoadingController;

 

转载于:https://www.cnblogs.com/newlist/p/3647660.html

/********************************************************************* * * Copyright (C), 2010-2022 Oplus. All rights reserved.. * * VENDOR_EDIT * * File : AddFilePanelFragment.kt * * Description : AddFilePanelFragment * * Version : 1.0 * * Date : 2025/02/08 * * Author : W9085798 * * * * ---------------------Revision History: ---------------------------- * * <author> <data> <version> <desc> ***********************************************************************/ package com.oplus.filemanager.addfilepanel.ui import android.annotation.SuppressLint import android.app.Activity import android.os.SystemClock import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.RelativeLayout import android.widget.TextView import androidx.annotation.VisibleForTesting import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity import androidx.lifecycle.Lifecycle import androidx.lifecycle.ViewModelProvider import com.coui.appcompat.button.COUIButton import com.coui.appcompat.button.SingleButtonWrap import com.coui.appcompat.contextutil.COUIContextUtil import com.coui.appcompat.panel.COUIBottomSheetDialog import com.coui.appcompat.panel.COUIBottomSheetDialogFragment import com.coui.appcompat.panel.COUIPanelFragment import com.coui.appcompat.panel.COUIPanelMultiWindowUtils import com.coui.appcompat.tablayout.COUITab import com.coui.appcompat.tablayout.COUITabLayout import com.coui.appcompat.toolbar.COUIToolbar import com.filemanager.common.MyApplication.appContext import com.filemanager.common.base.BaseFileBean import com.filemanager.common.base.BaseFragmentAdapter import com.filemanager.common.constants.Constants import com.filemanager.common.controller.LoadingController import com.filemanager.common.controller.PrivacyPolicyController import com.filemanager.common.helper.MimeTypeHelper import com.filemanager.common.helper.uiconfig.UIConfigMonitor import com.filemanager.common.utils.Injector import com.filemanager.common.utils.KtViewUtils import com.filemanager.common.utils.Log import com.filemanager.common.utils.ModelUtils import com.filemanager.common.utils.SdkUtils import com.filemanager.common.utils.StatusBarUtil import com.filemanager.common.utils.Utils import com.filemanager.common.utils.dp2px import com.filemanager.common.view.ViewPagerWrapperForPC import com.filemanager.common.view.viewpager.RTLViewPager import com.oplus.filemanager.addfilepanel.R import com.oplus.filemanager.addfilepanel.bean.AddFileBean import com.oplus.filemanager.addfilepanel.viewmodel.AddFilePanelViewModel import com.oplus.filemanager.interfaze.categorydoc.IDocumentExtensionType import com.oplus.filemanager.interfaze.main.IMain import kotlin.properties.Delegates class AddFilePanelFragment : COUIPanelFragment(), COUITabLayout.OnTabSelectedListener, PrivacyPolicyController.OnPrivacyPolicyListener { companion object { private const val TAG = "ShortcutFolderAddFilePanelFragment" private const val NUM = 1024 private const val DECIMAL_NUM = 1024f private const val DISMISS_TIME_GAP = 1000L private const val DELAY_TIME = 50L private const val PANEL_MAX_HEIGHT = "panel_max_height" } var lifeCycle: Lifecycle by Delegates.notNull() var title: String? = null var mCurrentPath: String = "" private var disMissTime: Long = 0L private var toolBar: COUIToolbar? = null private var mTabTitle = arrayListOf( appContext.resources.getString(com.filemanager.common.R.string.total), appContext.resources.getString(com.filemanager.common.R.string.string_photos), appContext.resources.getString(com.filemanager.common.R.string.string_videos), appContext.resources.getString(com.filemanager.common.R.string.string_audio), appContext.resources.getString(com.filemanager.common.R.string.string_documents), appContext.resources.getString(com.filemanager.common.R.string.string_other) ) private val mTabTitles = intArrayOf( Constants.TAB_ALL, Constants.TAB_IMAGE, Constants.TAB_VIDEO, Constants.TAB_AUDIO, Constants.TAB_DOCUMENT, Constants.TAB_OTHER ) private var mAddFileDialogInterface: AddFileDialogInterface? = null private var mPages: ArrayList<AddFileListFragment> = ArrayList() private var mViewPager: RTLViewPager? = null private var mTabView: COUITabLayout? = null private var mViewPagerWrapper: ViewPagerWrapperForPC? = null private var addFileBtn: COUIButton? = null private var verticalButtonWrap: SingleButtonWrap? = null private var rootView: ViewGroup? = null private var addFilePanelViewModel: AddFilePanelViewModel? = null private var statisticsSelectTitleView: TextView? = null private var statisticsSelectBodyView: TextView? = null private var contentLayout: RelativeLayout? = null private var buttonDivider: View? = null private var statisticsArrowUpView: ImageView? = null private var statisticsRootView: ViewGroup? = null private var loadingController: LoadingController? = null private var mPosition: Int = 0 var limitCount: Int = 0 private val allFiles: MutableList<BaseFileBean> = mutableListOf() private val imageFiles: MutableList<BaseFileBean> = mutableListOf() private val videoFiles: MutableList<BaseFileBean> = mutableListOf() private val audioFiles: MutableList<BaseFileBean> = mutableListOf() private val docFiles: MutableList<BaseFileBean> = mutableListOf() private val otherFiles: MutableList<BaseFileBean> = mutableListOf() private val mSelectArrayByID: MutableSet<Long> = mutableSetOf() var addFileClickCallback: (selectData: List<AddFileBean>) -> Unit = {} var isExternalReference: Boolean = false private fun setPanelMaxHeight() { if (activity == null) return rootView?.layoutParams?.apply { if (UIConfigMonitor.isCurrentZoomWindowShow() && SdkUtils.isAtLeastR() && !isExternalReference) { val savedHeight: Int = arguments?.getInt(PANEL_MAX_HEIGHT) ?: 0 Log.d(TAG, "setPanelMaxHeight savedHeight = $savedHeight") if (savedHeight == 0) { // 处理浮窗 height = handleZoomWindowHeight(requireActivity(), height) arguments?.putInt(PANEL_MAX_HEIGHT, height) } else { height = savedHeight } Log.d(TAG, "setPanelMaxHeight height = $height") } else { val screenHeight = dp2px(requireActivity(), requireActivity().resources.configuration.screenHeightDp) val panelMaxHeight = COUIPanelMultiWindowUtils.getPanelMaxHeight(requireActivity(), requireActivity().resources.configuration) Log.d(TAG, "setPanelMaxHeight screenHeight:$screenHeight panelH:$panelMaxHeight height:$height") //当是分屏 if (requireActivity().isInMultiWindowMode) { if (StatusBarUtil.checkIsGestureNavMode(requireActivity())) { //全面屏手势导航 height = handleGestureNavModeHeight(requireActivity(), height) } else { // 底部导航栏 height = Math.min(screenHeight, panelMaxHeight) - requireActivity().resources.getDimensionPixelOffset( com.filemanager.common.R.dimen.dimen_40dp ) height = handleNavModeHeight(requireActivity(), height) } } rootView?.layoutParams = this } } } /** * 处理浮窗模式下的高度 */ private fun handleZoomWindowHeight(activity: Activity, height: Int): Int { var result = height val statusBarH = COUIPanelMultiWindowUtils.getStatusBarHeight(activity) val configuration = activity.resources.configuration val paddingBottom = COUIPanelMultiWindowUtils.getPanelMarginBottom(context, configuration) val rect = COUIPanelMultiWindowUtils.getCurrentWindowVisibleRect(activity) if (rect != null) { if (rect.top == 0) { Log.d(TAG, "handleZoomWindowHeight: rect $rect top is invalid, reset") rect.top = activity.resources.getDimensionPixelOffset(com.filemanager.common.R.dimen.panel_min_top_margin) } if (rect.bottom == 0) { val windowH = KtViewUtils.getWindowSize(activity).y rect.bottom = windowH Log.d(TAG, "handleZoomWindowHeight: rect $rect bottom is invalid, reset $windowH") } result = (rect.bottom - rect.top) - paddingBottom - statusBarH Log.d(TAG, "handleZoomWindowHeight: height $result = ${rect.bottom}-${rect.top}-$paddingBottom-$statusBarH") } return result } /** * 处理底部导航栏导航时的高度 */ private fun handleNavModeHeight(it: Activity, height: Int): Int { val navBarHeight = KtViewUtils.getSoftNavigationBarSize(it) var result = height when { ModelUtils.isTablet() -> { //平板竖屏分屏时 if (UIConfigMonitor.instance.isDevicePortrait(it)) { result = height - navBarHeight Log.d(TAG, "handleNavMode pad portrait height:$result") } } UIConfigMonitor.instance.isFoldable(it) -> { // 折叠屏 result = height - navBarHeight Log.d(TAG, "handleNavMode fold height:$result") } else -> { //手机且分屏处于下屏 if (!COUIPanelMultiWindowUtils.isDisplayInUpperWindow(it)) { result = height - navBarHeight Log.d(TAG, "handleNavMode phone lower split screen height:$result") } } } return result } /** * 处理全面屏手势导航时的高度 */ @VisibleForTesting fun handleGestureNavModeHeight(activity: Activity, height: Int): Int { if (COUIPanelMultiWindowUtils.isDisplayInUpperWindow(activity)) { // 上分屏,不用处理 return height } // 处于下分屏,并且显示了手势指示条 if (StatusBarUtil.checkShowGestureNavBar(activity)) { val result = height - activity.resources.getDimensionPixelOffset(com.filemanager.common.R.dimen.dimen_16dp) Log.d(TAG, "handleGestureNavMode lower split screen with show gesture nvaBar height:$result") return result } return height } override fun onDestroy() { Log.d(TAG, "onDestroy") super.onDestroy() verticalButtonWrap?.release() clearDataList() addFilePanelViewModel?.onDestroy() } override fun initView(panelView: View?) { activity?.let { activity -> LayoutInflater.from(activity).inflate(getLayoutResId(), null, false)?.let { (contentView as? ViewGroup)?.addView(it) initContentView(it) initViewModel(activity) startObserver() initData() } } } private fun getLayoutResId(): Int { return R.layout.add_file_panel_dialog } private fun initViewModel(act: FragmentActivity) { addFilePanelViewModel = ViewModelProvider(act)[AddFilePanelViewModel::class.java] } private fun startObserver() { addFilePanelViewModel?.mAllFiles?.observe(this) { it ?: return@observe showLoadingView(false) setViewPagerData(it) } addFilePanelViewModel?.mAllSelectFiles?.observe(this) { it ?: return@observe updateStatisticsSelectView(it) } } fun notifyUpdate() { mSelectArrayByID.clear() addFilePanelViewModel?.mAllSelectFiles?.value?.forEach { bean -> if (bean.isSelected) { bean.mFileID?.let { mSelectArrayByID.add(it) } } } getCurrentFragment()?.apply { setSelectedData(mSelectArrayByID) notifyUpdate() } } private fun initContentView(view: View) { Log.d(TAG, "initContentView") hideDragView() rootView = view.findViewById(R.id.dialog_layout) toolBar = view.findViewById(R.id.toolbar) mTabView = view.findViewById<COUITabLayout?>(R.id.tab_layout) mViewPager = view.findViewById(R.id.viewPager) mViewPagerWrapper = view.findViewById<ViewPagerWrapperForPC?>(R.id.view_pager_wrapper).apply { notifyMainViewPager = object : ((Boolean) -> Unit) { override fun invoke(enable: Boolean) { activity?.let { val mainAction = Injector.injectFactory<IMain>() mainAction?.setViewPagerScrollEnabled(it, enable) } } } } addFileBtn = view.findViewById<COUIButton?>(R.id.btn_add_file).apply { verticalButtonWrap = SingleButtonWrap(this, SingleButtonWrap.Type.Small) setOnClickListener { Log.d(TAG, "addFileBtn click. select:${addFilePanelViewModel?.mAllSelectFiles?.value?.size}") val selectList = addFilePanelViewModel?.mAllSelectFiles?.value selectList?.let { addFileClickCallback.invoke(it) } } } contentLayout = view.findViewById(R.id.content_layout) buttonDivider = view.findViewById(R.id.button_divider) statisticsSelectTitleView = view.findViewById<TextView?>(R.id.select_title_content) statisticsSelectBodyView = view.findViewById<TextView?>(R.id.select_body_content) statisticsArrowUpView = view.findViewById(R.id.select_arraw_up) statisticsRootView = view.findViewById<ViewGroup?>(R.id.select_root_view).apply { setOnClickListener { if (Utils.isQuickClick()) { Log.w(TAG, "click too fast, try later") return@setOnClickListener } addFilePanelViewModel?.mAllSelectFiles?.value?.let { mAddFileDialogInterface?.replaceSelectedPanelFragment(it) } } } setPanelMaxHeight() } private fun initData() { initToolBar() resetStatisticsView() val fragments = childFragmentManager.fragments for (i in mTabTitles.indices) { initFragment(i, fragments) } initViewPager() if (PrivacyPolicyController.hasAgreePrivacy()) { loadData() } else { PrivacyPolicyController.bindPrivacyPolicyListener(this) } } private fun loadData() { Log.d(TAG, "loadData") showLoadingView(true) // 加载数据 activity?.let { addFilePanelViewModel?.loadAllFiles(it) } } private fun resetStatisticsView() { addFileBtn?.isEnabled = false statisticsSelectTitleView?.apply { visibility = View.VISIBLE text = appContext.resources.getString(com.filemanager.common.R.string.not_selected_file) } statisticsSelectBodyView?.apply { visibility = View.GONE text = "" } statisticsArrowUpView?.apply { visibility = View.GONE } statisticsRootView?.apply { isClickable = false } } private fun initToolBar() { toolBar?.apply { visibility = View.VISIBLE title = appContext.resources.getString(com.filemanager.common.R.string.encryption_file_select_title) isTitleCenterStyle = true inflateMenu(R.menu.add_file_panel_dialog_menu_bar) menu.findItem(R.id.cancel).setOnMenuItemClickListener { mAddFileDialogInterface?.dismissAddFileDialog() true } } if ((mTabView != null) && (mViewPager != null)) { mTabView?.let { it.setupWithViewPager(mViewPager, false) it.addOnTabSelectedListener(this) it.isUpdateindicatorposition = true } } } fun setAddFileDialogInterface(addFileDialog: AddFileDialogInterface) { mAddFileDialogInterface = addFileDialog } private fun initViewPager() { mViewPager?.let { it.offscreenPageLimit = mTabTitles.size it.adapter = ViewPagerFragmentStateAdapter(this) it.currentItem = 0 it.overScrollMode = View.OVER_SCROLL_NEVER } } private fun initFragment(position: Int, fragments: List<Fragment>): Fragment { Log.d(TAG, "initFragment") var fragment = if (fragments.isEmpty()) null else fragments[position] if (fragment == null) { fragment = AddFileListFragment() fragment.isExternalReference = isExternalReference fragment.lifeCycle = lifeCycle fragment.mOnItemSelectCallback = { _, fileID -> mSelectArrayByID.add(fileID) addFilePanelViewModel?.updateAllSelectFiles(mSelectArrayByID) } fragment.mOnItemUnSelectCallback = { _, fileID -> mSelectArrayByID.remove(fileID) addFilePanelViewModel?.updateAllSelectFiles(mSelectArrayByID) } fragment.mFileEmptyCallback = { isShowEmpty -> handleFileEmptyView(isShowEmpty) } fragment.mCurrentPath = mCurrentPath fragment.limitCount = limitCount } if (fragment is AddFileListFragment) { mPages.add(fragment) } return fragment } private fun handleFileEmptyView(isShowEmptyView: Boolean) { if (isShowEmptyView) { showLoadingView(false) buttonDivider?.alpha = 0F } else { buttonDivider?.alpha = 1F } } private fun showLoadingView(isShow: Boolean) { if (isShow) { Log.d(TAG, "showLoadingView disMissTime $disMissTime") activity?.let { loadingController = LoadingController(it, this) //如果异常loadingView刚刚调用,就不调用显示loadingView,防止loadingView一直显示 Log.d(TAG, "showLoadingView getLoadingShowStartTime ${loadingController?.getLoadingShowStartTime()}") if (SystemClock.elapsedRealtime() - disMissTime >= DISMISS_TIME_GAP || loadingController?.getLoadingShowStartTime() == 0L) { loadingController?.showLoading(contentLayout) } } } else { Log.d(TAG, "showLoadingView dismissLoading") loadingController?.dismissLoading() disMissTime = SystemClock.elapsedRealtime() } } override fun onShow(isShowOnFirstPanel: Boolean?) { super.onShow(isShowOnFirstPanel) ((parentFragment as? COUIBottomSheetDialogFragment)?.dialog as? COUIBottomSheetDialog) ?.setPanelBackgroundTintColor(COUIContextUtil.getAttrColor(context, com.support.appcompat.R.attr.couiColorBackgroundElevatedWithCard)) } private fun clearDataList() { allFiles.clear() imageFiles.clear() videoFiles.clear() audioFiles.clear() docFiles.clear() otherFiles.clear() mSelectArrayByID.clear() } private fun setViewPagerData(data: MutableList<AddFileBean>) { Log.d(TAG, "setViewPagerData") clearDataList() allFiles.addAll(data) val documentExtensionType = Injector.injectFactory<IDocumentExtensionType>() data.forEach { file -> val localType = file.mLocalType if (MimeTypeHelper.isImageType(localType)) { imageFiles.add(file) } else if (MimeTypeHelper.isVideoType(localType)) { videoFiles.add(file) } else if (MimeTypeHelper.isAudioType(localType)) { audioFiles.add(file) } else if ((MimeTypeHelper.isDocType(localType) || MimeTypeHelper.isOtherDocType(localType)) && documentExtensionType?.isCategoryDocSupportType(file) == true ) { //isCategoryDocSupportType确保面板上文档分类显示的内容和文管文档分类一致(部分未知格式后缀会识解析TXT类型) docFiles.add(file) } else { otherFiles.add(file) } } updateData(mTabTitles[mPosition]) } private fun updateStatisticsSelectView(data: MutableList<AddFileBean>) { if (data.size <= 0) { Log.d(TAG, "unselect file") resetStatisticsView() return } addFileBtn?.isEnabled = true statisticsSelectTitleView?.apply { visibility = View.VISIBLE text = appContext.resources.getQuantityString( com.filemanager.common.R.plurals.mark_selected_items_new, data.size, data.size ) } statisticsSelectBodyView?.apply { visibility = View.VISIBLE val size: Long = data.sumOf { it.mSize } val totalSize: String = updateSizeFormat(size) text = appContext.resources.getString(com.filemanager.common.R.string.selected_size, totalSize) } statisticsArrowUpView?.apply { visibility = View.VISIBLE } statisticsRootView?.apply { isClickable = true } } @SuppressLint("DefaultLocale") fun updateSizeFormat(size: Long): String { return if (size < NUM) { size.toString() + "B" } else if (size < NUM * NUM) { String.format("%.1f", (size / DECIMAL_NUM)) + " KB" } else if (size < NUM * NUM * NUM) { String.format("%.1f", (size / NUM / DECIMAL_NUM)) + " MB" } else { String.format("%.1f", (size / NUM / NUM / DECIMAL_NUM)) + " GB" } } private fun updateData(fragmentType: Int) { val fragment = getCurrentFragment() fragment?.mFragmentType = fragmentType when (fragmentType) { Constants.TAB_ALL -> fragment?.setData(allFiles) Constants.TAB_IMAGE -> fragment?.setData(imageFiles) Constants.TAB_VIDEO -> fragment?.setData(videoFiles) Constants.TAB_AUDIO -> fragment?.setData(audioFiles) Constants.TAB_DOCUMENT -> fragment?.setData(docFiles) Constants.TAB_OTHER -> fragment?.setData(otherFiles) } fragment?.setSelectedData(mSelectArrayByID) Log.d( TAG, "allFiles=${allFiles.size}, imageFiles=${imageFiles.size}, videoFiles=${videoFiles.size}, " + "audioFiles=${audioFiles.size}, docFiles=${docFiles.size}, otherFiles=${otherFiles.size}" ) } override fun onTabSelected(tab: COUITab?) { Log.d(TAG, "onTabSelected tab.postion=${tab?.position}") tab?.let { mPosition = it.position if (loadingController?.isShowing() != true) { updateData(mTabTitles[mPosition]) } } } override fun onTabUnselected(p0: COUITab?) {} override fun onTabReselected(p0: COUITab?) {} private fun getCurrentFragment(): AddFileListFragment? { return if (mPosition < mPages.size) { mPages[mPosition] } else { null } } inner class ViewPagerFragmentStateAdapter(fragment: Fragment) : BaseFragmentAdapter(fragment) { override fun getItemCount(): Int { return mTabTitle.size } override fun createFragment(position: Int): Fragment { return mPages[position] } override fun getPageTitle(position: Int): CharSequence { return mTabTitle[position] } } override fun onAgreeResult(agree: Boolean, noLongerRemind: Boolean) { loadData() } } interface AddFileDialogInterface { fun dismissAddFileDialog() fun replaceSelectedPanelFragment(selectData: MutableList<AddFileBean>) }这是对应的kotlin代码,怎么处理
最新发布
07-29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值