文章目录
- 需求
- 实现需求说明
- 参考资料
- 修改文件
- 实现思路
- 首页显示的搜索框去除
- 应用列表中的搜索框去除
- 解决方案
- 代码跟踪
- 代码扩展
需求
Launcher3 去掉搜桌面索框
实现需求说明
- 每个平台平台源码有区别,比如:MTK、高通、展讯、RK、谷歌…
- 单个平台下 不同Android版本对应的模块源码也不一样
当前针对的是MTK Android12 来实现去掉搜索框功能,其它平台可借鉴部分实现思路。网上部分资料也因为不同平台不同版本,可能只能解决部分问题。实际还是需要自己针对性看源码,分析源码实现。
搜索框 有两部分: 主界面和所有应用的谷歌搜索框
参考资料
为了方便了解Launcher3,建议还是熟悉下相关Launcher3 知识点
菜鸟成长之路-源码分析专栏
Android Launcher3 简介
Launcher3 高端定制
Launcher3 开发
Launcher3 Android Code Search在线源码查看
Launcher3 xref 在线源码查看
Launcher3 RK 源码查看
Launcher3 解析
Launcher3 AndroidP AS版本
谷歌Launcher3 Android13源码修改
Launcher3 和 Launcher3QuickStep 区别
Android14 不分Launcher3修改
Launcher3 LoaderTask 的数据加载
Android14 浅析Launcher
Android O Launcher3-Workspace加载
修改文件
packages/apps/Launcher3/res/layout/search_container_workspace.xml
packages/apps/Launcher3/src/com/android/launcher3/Workspace.java
packages/apps/Launcher3/res/layout/secondary_launcher.xml
实现思路
首页显示的搜索框去除
去除首页的搜索框思路方法基本一致,search_container_workspace.xml 修改:屏蔽Fragment 配置
<com.android.launcher3.qsb.QsbContainerViewxmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="0dp"android:id="@id/search_container_workspace"android:padding="0dp" ><!--
注释这一段<fragmentandroid:name="com.android.launcher3.qsb.QsbContainerView$QsbFragment"android:layout_width="match_parent"android:tag="qsb_view"android:layout_height="match_parent"/>-->
</com.android.launcher3.qsb.QsbContainerView>
Workspace.java 文件修改
bindAndInitFirstWorkspaceScreen 方法中,屏蔽// Add the first pageCellLayout firstPage = insertNewWorkspaceScreen(Workspace.FIRST_SCREEN_ID, getChildCount());// Always add a QSB on the first screen.if (mQsb == null) {// In transposed layout, we add the QSB in the Grid. As workspace does not touch the// edges, we do not need a full width QSB.mQsb = LayoutInflater.from(getContext()).inflate(R.layout.search_container_workspace, firstPage, false);}int cellVSpan = FeatureFlags.EXPANDED_SMARTSPACE.get()? EXPANDED_SMARTSPACE_HEIGHT : DEFAULT_SMARTSPACE_HEIGHT;CellLayout.LayoutParams lp = new CellLayout.LayoutParams(0, twoQsb?1:0, firstPage.getCountX(),cellVSpan);lp.canReorder = false;if (!firstPage.addViewToCellLayout(mQsb, 0, R.id.search_container_workspace, lp, true)) {Log.e(TAG, "Failed to add to item at (0, 0) to CellLayout");mQsb = null;}
应用列表中的搜索框去除
实际这个需求实现, 在不同的平台和版本区别很大,借鉴解决思路。
解决方案
解决方案:找到对应表的布局,将布局中的View
com.android.launcher3.allapps.search.AppsSearchContainerLayout 设置为GONE 状态
代码跟踪
首先看Launcher 目录有一个allapps: 自己猜是所有app 的意思吧
看着像的就去看一下源码 ![(https://i-blog.csdnimg.cn/direct/6e65499862dc4d60a68dc2f1d2878f46.png)
在AllAppsContainerView.java 文件中有这样一段代码,初始化View
这个search 相关的 search_container_all_apps,看着像mSearchContainer = findViewById(R.id.search_container_all_apps);mSearchUiManager = (SearchUiManager) mSearchContainer;mSearchUiManager.initializeSearch(this);mSearchContainer.setVisibility(View.GONE);
那就找 search_container_all_apps ,grep -rn search_container_all_apps 一次
fise4@ubuntu-PowerEdge-R730:~/Android/mt6769-alps-release-s0.mp1.rc/alps-release-s0.mp1.rc$ grep -rn "search_container_all_apps"
packages/apps/Launcher3/res/values/config.xml:108: <item type="id" name="search_container_all_apps" />
packages/apps/Launcher3/res/layout/all_apps_tabs.xml:23: android:layout_below="@id/search_container_all_apps"
packages/apps/Launcher3/res/layout/secondary_launcher.xml:65: android:layout_below="@id/search_container_all_apps"
packages/apps/Launcher3/res/layout/secondary_launcher.xml:102: android:id="@id/search_container_all_apps"
packages/apps/Launcher3/res/layout/all_apps_content_layout.xml:21: android:layout_below="@id/search_container_all_apps"
packages/apps/Launcher3/res/layout/all_apps_rv_layout.xml:22: android:layout_below="@id/search_container_all_apps"
packages/apps/Launcher3/res/layout/all_apps_fast_scroller.xml:24: android:layout_below="@+id/search_container_all_apps"
packages/apps/Launcher3/res/layout/all_apps_fast_scroller.xml:33: android:layout_below="@+id/search_container_all_apps"
packages/apps/Launcher3/res/layout/search_container_all_apps.xml:18: android:id="@id/search_container_all_apps"
packages/apps/Launcher3/res/layout/all_apps.xml:36: android:layout_below="@id/search_container_all_apps"
packages/apps/Launcher3/res/layout/all_apps.xml:48: layout="@layout/search_container_all_apps"/>
packages/apps/Launcher3/src/com/android/launcher3/allapps/AllAppsContainerView.java:378: mSearchContainer = findViewById(R.id.search_container_all_apps);
packages/apps/Launcher3/src/com/android/launcher3/allapps/AllAppsContainerView.java:382: Log.d(TAG," findViewById search_container_all_apps GONE");
packages/apps/Launcher3/tests/tapl/com/android/launcher3/tapl/AllAppsFromOverview.java:51: allAppsContainer, "search_container_all_apps");
packages/apps/Launcher3/tests/tapl/com/android/launcher3/tapl/AllApps.java:203: return mLauncher.waitForObjectInContainer(allAppsContainer, "search_container_all_apps");
整理出有用的信息如下
packages/apps/Launcher3/res/values/config.xml:108: <item type="id" name="search_container_all_apps" />
packages/apps/Launcher3/res/layout/secondary_launcher.xml:102: android:id="@id/search_container_all_apps"
packages/apps/Launcher3/res/layout/search_container_all_apps.xml:18: android:id="@id/search_container_all_apps"
packages/apps/Launcher3/res/layout/all_apps.xml:48: layout="@layout/search_container_all_apps"/>
再次搜索对应的文件
- secondary_launcher.xml 找到 SecondaryDisplayLauncher.java 对应
- search_container_all_apps.xml -> 无
- all_apps.xml -> 无
我们看看secondary_launcher.xml 发现有一个搜索的View, AppsSearchContainerLayout 设置为GONE 状态,就是 search_container_all_apps 对应的View
<?xml version="1.0" encoding="utf-8"?>
<com.android.launcher3.secondarydisplay.SecondaryDragLayerxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:id="@+id/drag_layer"android:padding="@dimen/dynamic_grid_edge_margin"><GridViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:layout_marginBottom="100dp"android:theme="@style/HomeScreenElementTheme"android:layout_gravity="center_horizontal|top"android:layout_margin="@dimen/dynamic_grid_edge_margin"android:id="@+id/workspace_grid" /><ImageButtonandroid:id="@+id/all_apps_button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="bottom|end"android:layout_margin="40dp"android:padding="16dp"android:src="@drawable/ic_apps"android:background="@drawable/bg_all_apps_button"android:contentDescription="@string/all_apps_button_label"android:onClick="onAppsButtonClicked" /><com.android.launcher3.allapps.AllAppsContainerViewandroid:id="@+id/apps_view"android:layout_width="match_parent"android:layout_height="match_parent"android:clipChildren="true"android:clipToPadding="false"android:focusable="false"android:saveEnabled="false"android:layout_gravity="bottom|end"android:background="@drawable/round_rect_primary"android:elevation="2dp"android:visibility="invisible" ><includelayout="@layout/all_apps_rv_layout"android:visibility="gone" /><com.android.launcher3.allapps.FloatingHeaderViewandroid:id="@+id/all_apps_header"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_below="@id/search_container_all_apps"android:clipToPadding="false"android:paddingTop="@dimen/all_apps_header_top_padding"android:orientation="vertical" ><com.android.launcher3.workprofile.PersonalWorkSlidingTabStripandroid:id="@+id/tabs"android:layout_width="match_parent"android:layout_height="@dimen/all_apps_header_pill_height"android:orientation="horizontal"style="@style/TextHeadline"><Buttonandroid:id="@+id/tab_personal"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:background="?android:attr/selectableItemBackground"android:text="@string/all_apps_personal_tab"android:textAllCaps="true"android:textColor="@color/all_apps_tab_text"android:textSize="14sp" /><Buttonandroid:id="@+id/tab_work"android:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="1"android:background="?android:attr/selectableItemBackground"android:text="@string/all_apps_work_tab"android:textAllCaps="true"android:textColor="@color/all_apps_tab_text"android:textSize="14sp" /></com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip></com.android.launcher3.allapps.FloatingHeaderView><com.android.launcher3.allapps.search.AppsSearchContainerLayoutandroid:id="@id/search_container_all_apps"android:layout_width="match_parent"android:layout_height="@dimen/all_apps_search_bar_field_height"android:layout_centerHorizontal="true"android:layout_gravity="top|center_horizontal"android:background="@drawable/bg_all_apps_searchbox"android:elevation="1dp"android:focusableInTouchMode="true"android:gravity="center"android:hint="@string/all_apps_search_bar_hint"android:imeOptions="actionSearch|flagNoExtractUi"android:inputType="text|textNoSuggestions|textCapWords"android:maxLines="1"android:padding="8dp"android:saveEnabled="false"android:scrollHorizontally="true"android:singleLine="true"android:textColor="?android:attr/textColorSecondary"android:textColorHint="@drawable/all_apps_search_hint"android:textSize="16sp"android:visibility="gone"/><include layout="@layout/all_apps_fast_scroller" /></com.android.launcher3.allapps.AllAppsContainerView>
</com.android.launcher3.secondarydisplay.SecondaryDragLayer>
代码扩展
上面的更改已经实现了需求,我们接着看 secondary_launcher.xml 对应的Java 文件
AllAppsContainerView.java onFinishInflate() 方法@Overrideprotected void onFinishInflate() {super.onFinishInflate();Log.d(TAG,"onFinishInflate");// This is a focus listener that proxies focus from a view into the list view. This is to// work around the search box from getting first focus and showing the cursor.setOnFocusChangeListener((v, hasFocus) -> {if (hasFocus && getActiveRecyclerView() != null) {getActiveRecyclerView().requestFocus();}});mHeader = findViewById(R.id.all_apps_header);rebindAdapters(mUsingTabs, true /* force */);mSearchContainer = findViewById(R.id.search_container_all_apps); //搜索框,找的就是这个搜索框mSearchUiManager = (SearchUiManager) mSearchContainer;mSearchUiManager.initializeSearch(this);//下面代码自己添加的mSearchContainer.setVisibility(View.GONE);Log.d(TAG," findViewById search_container_all_apps GONE");}
实际验证在不修改布局情况下,这里设置GONE 没有用
跟踪:mSearchContainer, 对外提供的方法public View getSearchView() {return mSearchContainer;}搜索 getSearchView() 方法fise4@ubuntu-PowerEdge-R730:~/Android/mt6769-alps-release-s0.mp1.rc/alps-release-s0.mp1.rc/packages/apps/Launcher3$ grep -rn getSearchView
src/com/android/launcher3/allapps/AllAppsContainerView.java:586: public View getSearchView() {
src/com/android/launcher3/allapps/AllAppsContainerView.java:806: (int) (getSearchView().getAlpha() * 255));
src/com/android/launcher3/allapps/AllAppsContainerView.java:809: getSearchView().setBackgroundColor(viewBG);
src/com/android/launcher3/allapps/AllAppsContainerView.java:816: getSearchView().setVisibility(View.GONE);这些都是 AllAppsContainerView.java 里面获取View; 回头看 secondary_launcher.xml 对应的类是SecondaryDisplayLauncher.java 找到 SecondaryDisplayLauncher.java showAppDrawer 方法,在这个方法里去通过getSearchView 获取到搜索框,然后对搜索框设置GONE 不显示也可以的。/*** Show/hide app drawer card with animation.*/public void showAppDrawer(boolean show) {Log.d(TAG," showAppDrawer show");if (show == mAppDrawerShown) {return;}float openR = (float) Math.hypot(mAppsView.getWidth(), mAppsView.getHeight());float closeR = Themes.getDialogCornerRadius(this);float startR = mAppsButton.getWidth() / 2f;float[] buttonPos = new float[] { startR, startR};mDragLayer.getDescendantCoordRelativeToSelf(mAppsButton, buttonPos);mDragLayer.mapCoordInSelfToDescendant(mAppsView, buttonPos);final Animator animator = ViewAnimationUtils.createCircularReveal(mAppsView,(int) buttonPos[0], (int) buttonPos[1],show ? closeR : openR, show ? openR : closeR);if (show) {mAppDrawerShown = true;mAppsView.setVisibility(View.VISIBLE);mAppsButton.setVisibility(View.INVISIBLE);} else {mAppDrawerShown = false;animator.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationEnd(Animator animation) {mAppsView.setVisibility(View.INVISIBLE);mAppsButton.setVisibility(View.VISIBLE);mAppsView.getSearchUiManager().resetSearch();}});}Log.d(TAG," showAppDrawer set searchView Gone");//设置为 GONE mAppsView.getSearchView().setVisibility(View.GONE);animator.start();}
showAppDrawer 方法,只是在特定的情况下执行,所以在这个方法里面执行设置GONE逻辑并不是完全之策,最简单直接就是更改布局GONE 状态了。