Android launcher3 -- launcher3源码2

xiaoxiao2021-02-27  207

Android launcher3 – launcher3源码2

去除首次进入提示框

布局

longpress_cling.xml “欢迎使用”界面的背景和容器 longpress_cling_welcome_content.xml “欢迎使用”界面的描述,首次启动调用 longpress_cling_content.xml 数据迁移时提醒

相关字符串:

<string name="first_run_cling_title" msgid="2459738000155917941">"欢迎使用"</string> <string name="migration_cling_title" msgid="9181776667882933767">"复制应用图标"</string> <string name="migration_cling_description" msgid="2752413805582227644">"要导入旧的主屏幕中的图标和文件夹吗?"</string> <string name="migration_cling_copy_apps" msgid="946331230090919440">"复制图标"</string> <string name="migration_cling_use_default" msgid="2626475813981258626">"使用全新配置"</string> <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"壁纸、小部件和设置"</string> <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"触摸并按住背景,即可进行个性化设置"</string> <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"知道了"</string>

调用“欢迎使用”界面

Launcher.java:protected void onCreate(Bundle savedInstanceState) Launcher.java:void showFirstRunClings() LauncherClings.java:public void showLongPressCling(boolean showWelcome)

public void showLongPressCling(boolean showWelcome) { mIsVisible = true; ViewGroup root = (ViewGroup) mLauncher.findViewById(R.id.launcher); View cling = mInflater.inflate(R.layout.longpress_cling, root, false); cling.setOnLongClickListener(new OnLongClickListener() { @Override public boolean onLongClick(View v) { mLauncher.showOverviewMode(true); dismissLongPressCling(); return true; } }); final ViewGroup content = (ViewGroup) cling.findViewById(R.id.cling_content); mInflater.inflate(showWelcome ? R.layout.longpress_cling_welcome_content : R.layout.longpress_cling_content, content); content.findViewById(R.id.cling_dismiss_longpress_info).setOnClickListener(this); if (TAG_CROP_TOP_AND_SIDES.equals(content.getTag())) { Drawable bg = new BorderCropDrawable(mLauncher.getResources().getDrawable(R.drawable.cling_bg), true, true, true, false); content.setBackground(bg); } root.addView(cling); if (showWelcome) { // This is the first cling being shown. No need to animate. return; } // Animate content.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { content.getViewTreeObserver().removeOnGlobalLayoutListener(this); ObjectAnimator anim; if (TAG_CROP_TOP_AND_SIDES.equals(content.getTag())) { content.setTranslationY(-content.getMeasuredHeight()); anim = LauncherAnimUtils.ofFloat(content, "translationY", 0); } else { content.setScaleX(0); content.setScaleY(0); PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1); PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1); anim = LauncherAnimUtils.ofPropertyValuesHolder(content, scaleX, scaleY); } anim.setDuration(SHOW_CLING_DURATION); anim.setInterpolator(new LogDecelerateInterpolator(100, 0)); anim.start(); } }); }

状态栏和导航栏透明

透明设置

Android 4.4 沉浸式透明状态栏与导航栏。 Android 系统自4.2 开始 UI 上就没多大改变,4.4 也只是增加了透明状态栏与导航栏的功能;而Material Design的普及,很多开发人员都会面临App的Material适配。如果你的App不只是针对5.0以上设备的话,多数情况也必须做兼容

代码设置:

if(VERSION.SDK_INT >= VERSION_CODES.KITKAT) { getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); }

在values、values-v19、values-v21的style.xml设置: values/style.xml

<style name="BaseWallpaperTheme" parent="@android:style/Theme.DeviceDefault.Light.NoActionBar"> <item name="android:windowBackground">@android:color/transparent</item> <item name="android:colorBackgroundCacheHint">@null</item> <item name="android:windowShowWallpaper">true</item> <item name="android:windowNoTitle">true</item> </style> <style name="Theme" parent="@style/BaseWallpaperTheme"></style>

values-v19/style.xml

<style name="Theme" parent="@style/BaseWallpaperTheme"> <item name="android:windowTranslucentStatus">true</item> <item name="android:windowTranslucentNavigation">true</item> </style>

values-v21/style.xml

<style name="Theme" parent="@style/BaseWallpaperTheme"> <item name="android:windowTranslucentStatus">true</item> <item name="android:windowTranslucentNavigation">true</item> <item name="android:colorControlActivated">@color/launcher_accent_color</item> <item name="android:colorAccent">@color/launcher_accent_color</item> <item name="android:colorPrimary">@color/launcher_accent_color</item> </style>

values-sw720dp\styles.xml

<style name="Theme" parent="@android:style/Theme.DeviceDefault.Wallpaper.NoTitleBar"> <item name="android:windowActionModeOverlay">true</item> </style>

values-sw720dp-v19\styles.xml

<style name="Theme" parent="@android:style/Theme.DeviceDefault.Wallpaper.NoTitleBar"> <item name="android:windowActionModeOverlay">true</item> <item name="android:windowTranslucentStatus">true</item> <item name="android:windowTranslucentNavigation">true</item> </style>

Launcher3设置全屏显示

mLauncherView.setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);

Launcher3为什么还要设置全屏显示?状态栏和导航栏透明存在各种问题。

导航栏UI重叠问题
android:fitsSystemWindows="true"

通过前面的两种方式所实现 Translucent System Bar 效果的Activity,都需要在根布局里设置 android:fitsSystemWindows=”true” 。设置了该属性的作用在于,不会让系统导航栏和我们app的UI重叠,导致交互问题。

ActionBar上菜单显示三个方块

保持Activity调起,使用android:windowActionModeOverlay属性。 看似让ActionMode浮在了ActionBar上,但其实存在很大问题。 这种方式在4.4以下会使用Holo风格(overflow图标可以看出来,不是三个原点,是三个方块),且ActionMode比ActionBar小一些(可以看到蓝色底边是ActionBar)

详细内容请参考:Material适配详解

布局空出状态栏和导航栏区域

上面设置状态栏和导航栏透明后,在Launcher3源码处理:

public class LauncherRootView extends InsettableFrameLayout { public LauncherRootView(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected boolean fitSystemWindows(Rect insets) { setInsets(insets); return true; // I'll take it from here } }

父类InsettableFrameLayout.java回调:

public void setInsets(Rect insets) { final int n = getChildCount(); for (int i = 0; i < n; i++) { final View child = getChildAt(i); setFrameLayoutChildInsets(child, insets, mInsets); } mInsets.set(insets); }

最终处理布局Margin:

public void setFrameLayoutChildInsets(View child, Rect newInsets, Rect oldInsets) { final LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (child instanceof Insettable) { ((Insettable) child).setInsets(newInsets); } else if (!lp.ignoreInsets) { lp.topMargin += (newInsets.top - oldInsets.top); lp.leftMargin += (newInsets.left - oldInsets.left); lp.rightMargin += (newInsets.right - oldInsets.right); lp.bottomMargin += (newInsets.bottom - oldInsets.bottom); } child.setLayoutParams(lp); }

还可使用Google提供CoordinatorLayout布局对fitsSystemWindows处理。参考:令人困惑的fitsSystemWindows属性

测试屏蔽:

lp.topMargin += (newInsets.top - oldInsets.top); lp.leftMargin += (newInsets.left - oldInsets.left); lp.rightMargin += (newInsets.right - oldInsets.right); lp.bottomMargin += (newInsets.bottom - oldInsets.bottom);

转载请注明原文地址: https://www.6miu.com/read-9473.html

最新回复(0)