Settings首页Suggestion菜单加载流程

目录

一、概述

二、Suggestion常见问题

1、如何打开原生Suggestion菜单

2、原生默认有哪些Suggestion菜单

3、如何配置Suggestion菜单显示时机

三、Suggestion菜单加载流程分析

1、设置首页SettingsHomepageActivity.java

2、ContextualCardsFragment.java

3、ContextualCardManager.java

4、ContextualCardsAdapter.java

5、ControllerRendererPool.java

6、LegacySuggestionContextualCardController.java

7、SuggestionController.java

8、SettingsIntelligence-SuggestionService.java

9、SuggestionFeatureProvider.java

10、SuggestionParser.java


一、概述

什么是建议(Suggestion)菜单,如下图。在设置首页的,第一个菜单上方,搜索框下方会弹出一些快捷菜单。提醒用户进行一些个性化设置,用户设置后或者关闭后则不再显示

二、Suggestion常见问题

1、如何打开原生Suggestion菜单

出现时机需要满足三个条件,1、设备不是 LowRam 设备 2、启用 settings_contextual_home 特性 3、在开机一定时间后(一般是几天,具体看 AndroidManifest.xml 中的有配置),为什么是这几个,后面的分析流程会详细解释。代码逻辑可以查看SettingsHomePageActivity-OnCreate

2、原生默认有哪些Suggestion菜单

在Settings AndroidManifest.xml中搜索以下cagegory

"com.android.settings.suggested.category.FIRST_IMPRESSION"

所有Suggestion都需要配置此category,其实其他应用配置该category应该也可以显示

原生默认共有七个:

ZenSuggestionActivity
WallpaperSuggestionActivity
StyleSuggestionActivity
Settings$NightDisplaySuggestionActivity
ScreenLockSuggestionActivity
FingerprintEnrollSuggestionActivity
WifiCallingSuggestionActivity

3、如何配置Suggestion菜单显示时机

所有Suggestion都有配置"com.android.settings.dismiss",如果第一个值为0,则显示直接显示。

非0时,则会根据取一个值,判断多少天后显示。逻辑在

DismissedChecker.java-parseAppearDay()中
<meta-data android:name="com.android.settings.dismiss"
    android:value="10,14,30" />

三、Suggestion菜单加载流程分析

整个加载过程涉及Settings、SettingsLib、SettingsIntelligence、framework。为何设计这么复杂,还是涉及到framework,我猜测google工程师初衷是为了在其他应用中也可以增加Suggestion菜单

1、设置首页SettingsHomepageActivity.java

判定显示Suggestion条件,条件满足时加载ContextualCardsFragment

SettingsHomepageActivity.java
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
....
if (!getSystemService(ActivityManager.class).isLowRamDevice()) { //非LowRamDevice才会加载
            initAvatarView();
            final boolean scrollNeeded = mIsEmbeddingActivityEnabled
                    && !TextUtils.equals(getString(DEFAULT_HIGHLIGHT_MENU_KEY), highlightMenuKey);
            showSuggestionFragment(scrollNeeded);

//FeatureFlags.CONTEXTUAL_HOME = "settings_contextual_home" 该功能为true时才会显示Suggestion
            if (FeatureFlagUtils.isEnabled(this, FeatureFlags.CONTEXTUAL_HOME)) {
//加载ContextualCardsFragment
                showFragment(() -> new ContextualCardsFragment(), R.id.contextual_cards_content);
                ((FrameLayout) findViewById(R.id.main_content))
                        .getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
            }
        }
...

}

2、ContextualCardsFragment.java

Suggestion菜单显示在Fragment中,所有的Suggestion最终是用ContextualCardsFragment来加载和展示

ContextualCardsFragment.java

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        final Context context = getContext();
        if (savedInstanceState == null) {
            FeatureFactory.getFactory(context).getSlicesFeatureProvider().newUiSession();
            BluetoothUpdateWorker.initLocalBtManager(getContext());
        }
//该Manager会管理Suggestion相关的Controller、Render
        mContextualCardManager = new ContextualCardManager(context, getSettingsLifecycle(), //pri suggestion 2
                savedInstanceState);
        mKeyEventReceiver = new KeyEventReceiver();
    }

 @Override
    public void onStart() {
        super.onStart();
        registerScreenOffReceiver();
        registerKeyEventReceiver();
//loadCards,默认配置这里是不执行的
        mContextualCardManager.loadContextualCards(LoaderManager.getInstance(this),  //pri suggestion 加载
                sRestartLoaderNeeded);
        sRestartLoaderNeeded = false;
    }

  @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,   //pri suggestion 2
            Bundle savedInstanceState) {
        final Context context = getContext();
        final View rootView = inflater.inflate(R.layout.settings_homepage, container, false);
        mCardsContainer = rootView.findViewById(R.id.card_container);
        mLayoutManager = new GridLayoutManager(getActivity(), SPAN_COUNT,
                GridLayoutManager.VERTICAL, false /* reverseLayout */);  //设为网格布局
        mCardsContainer.setLayoutManager(mLayoutManager);
//Suggestion显示的布局未FocusRecyclerView,这个是对应的Adapter
        mContextualCardsAdapter = new ContextualCardsAdapter(context, this /* lifecycleOwner */,
                mContextualCardManager);
        mCardsContainer.setItemAnimator(null);
        mCardsContainer.setAdapter(mContextualCardsAdapter);
        mContextualCardManager.setListener(mContextualCardsAdapter); //数据会通过回调从这里返回
        mCardsContainer.setListener(this);
        mItemTouchHelper = new ItemTouchHelper(new SwipeDismissalDelegate(mC
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值