先放 Launcher3 地址:https://github.com/yuchuangu85/Launcher3_mx/

在这感谢 @yuchuangu85


Launcher3 是 Google AOSP 项目中默认的桌面应用程序。它差不多长这样:

应用页

下面看看基本的桌面结构:

在最外层,是一个叫 LauncherRootView 的控件(图中并未标出)。由外往内以此 LauncherRootView -> DragLayer -> Workspace,Hotseat 和 WorkspacePageIndicator 并不是在 Workspace 中。可以理解为悬浮于 Workspace 上。

具体布局请参考 res/layout/launcher.xml


我发现一些讲 Launcher3 的文章都没有很好的写清楚 UI,这样会导致我们在分析源码的时候,根本无法找到源码操作了什么 View。所以请看下图:

Launcher3 Layout

Launcher3 视图、布局。

下面来具体介绍一下 Launcher (src/Launcher.java) 中的 View (res/layout/launcher.xml)。

LauncherRootView:主要做一些整体上布局的调整,非重点。

DragLayer:协调整个app之间的拖动

Workspace:应用图标、文件夹、小部件都放于其中。

include/overview_panel_container:已废弃,无用。

WorkspacePageIndicator:工作区页面指示器,如图(白色横线)。

WorkspacePageIndicator

include/drop_target_bar:拖拽APP后在顶部显示的view。顶部栏包含各种放置目标:删除/应用信息/卸载。

include/drop_target_bar

include/scrim_view:用于过度处理的单色view,参考 CollapsingToolbarLayout#contentScrim,如图白框内。

include/scrim_view

include/apps_view:放置所有app图标。如图。

include/apps_view

include/hotseat:放置“常用”app图标,如图(淡黄色区)。

include/hotseat

以上就是 Launcher3 中的视图介绍。


首先我们找到入口Activity:com.android.launcher3.Launcher

com.android.launcher3.Launcher
点击查看代码
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        if (DEBUG_STRICT_MODE) {
            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                    .detectDiskReads()
                    .detectDiskWrites()
                    .detectNetwork()   // or .detectAll() for all detectable problems
                    .penaltyLog()
                    .build());
            StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                    .detectLeakedSqlLiteObjects()
                    .detectLeakedClosableObjects()
                    .penaltyLog()
                    .penaltyDeath()
                    .build());
        }
        TraceHelper.beginSection("Launcher-onCreate");

        super.onCreate(savedInstanceState);
        TraceHelper.partitionSection("Launcher-onCreate", "super call");

        // 初始化 LauncherAppState
        LauncherAppState app = LauncherAppState.getInstance(this);

        // 获取配置文件
        mOldConfig = new Configuration(getResources().getConfiguration());

        // 设置回调
        mModel = app.setLauncher(this);

        // 初始化设备配置文件
        initDeviceProfile(app.getInvariantDeviceProfile());

        // 获取 k-v sharedprefs
        mSharedPrefs = Utilities.getPrefs(this);
        mIconCache = app.getIconCache();
        mAccessibilityDelegate = new LauncherAccessibilityDelegate(this);

        // 初始化拖拽管理器
        mDragController = new DragController(this);

        // 视图过渡处理
        mAllAppsController = new AllAppsTransitionController(this);

        mStateManager = new LauncherStateManager(this);
        UiFactory.onCreate(this);

        // 初始化小部件管理器
        mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);

        mAppWidgetHost = new LauncherAppWidgetHost(this);
        mAppWidgetHost.startListening();

        // 加载主视图
        mLauncherView = LayoutInflater.from(this).inflate(R.layout.launcher, null);

        // 配置视图
        setupViews();

        mPopupDataProvider = new PopupDataProvider(this);

        // 旋转帮助类
        mRotationHelper = new RotationHelper(this);

        // app 过度
        mAppTransitionManager = LauncherAppTransitionManager.newInstance(this);

        boolean internalStateHandled = InternalStateHandler.handleCreate(this, getIntent());
        if (internalStateHandled) {
            if (savedInstanceState != null) {
                // InternalStateHandler has already set the appropriate state.
                // We dont need to do anything.
                savedInstanceState.remove(RUNTIME_STATE);
            }
        }
        restoreState(savedInstanceState);

        // We only load the page synchronously if the user rotates (or triggers a
        // configuration change) while launcher is in the foreground
        // 只有在启动器处于前台时用户旋转(或触发配置更改)时,我们才会同步加载页面
        int currentScreen = PagedView.INVALID_RESTORE_PAGE;
        if (savedInstanceState != null) {
            currentScreen = savedInstanceState.getInt(RUNTIME_STATE_CURRENT_SCREEN, currentScreen);
        }

        if (!mModel.startLoader(currentScreen)) {
            if (!internalStateHandled) {
                // If we are not binding synchronously, show a fade in animation when
                // the first page bind completes.
                // 如果我们不同步绑定,请在第一页绑定完成时显示淡入淡出的动画。
                mDragLayer.getAlphaProperty(ALPHA_INDEX_LAUNCHER_LOAD).setValue(0);
            }
        } else {
            // Pages bound synchronously.
            mWorkspace.setCurrentPage(currentScreen);

            setWorkspaceLoading(true);
        }

        // For handling default keys
        // 用于处理默认 key
        setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);

        setContentView(mLauncherView);
        getRootView().dispatchInsets();

        // Listen for broadcasts
        // 监听广播
        registerReceiver(mScreenOffReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));

        getSystemUiController().updateUiState(SystemUiController.UI_STATE_BASE_WINDOW,
                Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText));

        if (mLauncherCallbacks != null) {
            mLauncherCallbacks.onCreate(savedInstanceState);
        }
        mRotationHelper.initialize();

        TraceHelper.endSection("Launcher-onCreate");
    }

  


August

Android 开发者、影视后期内容(包装)制作者、Unity 2D游戏开发者

0 条评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注

%d 博主赞过: