MTK-Android12-系统设置一级菜单-适配遥控器
提示MTK-Android12-系统设置一级菜单-适配遥控器文章目录前言-需求-存在的问题前言-场景存在问题遥控器问题系统源码问题一、参考资料二、实现方案1、修改源码文件2、具体实践修改方案修改原理三、实际效果四、思路扩展-源码分析1、实现方案和Android13 版本对比分析2、新方案畅享方案难点新方案思路总结前言-需求-存在的问题前言-场景Android12 MTK 平台6769方案 的大屏产品接遥控器 发现遥控器在系统设置一集菜单最下方的菜单可以获取的遥控器焦点但是对用户不可见。 6769 本身是手机方案拿来直接用作大屏商显产品可能就本身存在一定问题需要修复。 接入遥控器后系统设置一级菜单可以实现遥控器下拉到最下方的一级菜单用户可见。存在问题遥控器问题如下如果是白色遥控器 本身还可以点触效果滑动页面 但是使用的是黑色遥控器就没有这个功能了。 那么就一定要通过 上下左右切换焦点的功能达到每个功能性UI 焦点可达系统源码问题如下实际问题密码和账号、快霸 下面还有子菜单遥控器焦点可达但是UI不可见。 一定要用手上拉才能看见实际菜单。一、参考资料MTK-Android13-设置模块一级菜单添加遥控器功能 偏系统应用层适配但是和当前版本不一致可借鉴Android软件适配遥控器需求-案例经验分享:偏应用层相关适配MTK-Android12-适配蓝牙遥控器按键 偏系统层适配遥控器按键值、功能性适配。二、实现方案1、修改源码文件文件路径/vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/homepage/SettingsHomepageActivity.java2、具体实践修改方案具体修改如下屏蔽//initHomepageContainer();privatevoidinitHomepageContainer(){finalViewviewfindViewById(R.id.homepage_container);// Prevent inner RecyclerView gets focus and invokes scrolling.view.setFocusableInTouchMode(true);view.requestFocus();}在onCreate方法中添加代码如下给列表底部加留白最后几项完全显示importandroid.view.View;importandroid.view.ViewTreeObserver;importandroidx.core.widget.NestedScrollView;importandroid.widget.FrameLayout;importandroid.util.Log;importandroid.view.ViewGroup;importandroidx.recyclerview.widget.RecyclerView;importandroid.view.ViewParent;importandroid.graphics.Rect;finalViewGroupmainContentfindViewById(R.id.main_content);mainContent.getViewTreeObserver().addOnGlobalLayoutListener(newViewTreeObserver.OnGlobalLayoutListener(){OverridepublicvoidonGlobalLayout(){mainContent.getViewTreeObserver().removeOnGlobalLayoutListener(this);// 找到列表RecyclerViewrecyclerViewfindRecyclerView(mainContent);if(recyclerViewnull)return;// 关键给列表底部设置 400dp 留白让最后几项可以完全滚动显示intbottomPadding(int)(getResources().getDisplayMetrics().density*400);recyclerView.setPadding(recyclerView.getPaddingLeft(),recyclerView.getPaddingTop(),recyclerView.getPaddingRight(),bottomPadding// 底部加大量空白);recyclerView.setClipToPadding(false);}});修改原理屏蔽掉焦点占用直接给 RecyclerView 加足够的底部留白让最后几项能完全滚上来。三、实际效果四、思路扩展-源码分析1、实现方案和Android13 版本对比分析之前Mtk 平台Android13版本解决方案屏蔽//initHomepageContainer();就可以了的但是在Android12版本中无效。2、新方案畅享方案难点我们解决方案其实没有从UI滑动上面考虑来解决只是兜底、保底 方案 拼凑一个View 出来。 实际上 我们保证列表上划。难点是NestedScrollView里面嵌套了FrameLayoutFrameLayout中最终嵌套的是TopLevelSettings下面的各种PreferenceFragmentCompat可以这么理解吧 很难捕获到真正的焦点、焦点冲突了。NestedScrollView←**这个才能继续往上滑**↳LinearLayout↳FrameLayout↳RecyclerView←**这个已经滑到底了滑不动了**androidx.core.widget.NestedScrollViewandroid:idid/main_content_scrollable_containerandroid:layout_widthmatch_parentandroid:layout_heightmatch_parentapp:layout_behaviorcom.android.settings.widget.HomepageAppBarScrollingViewBehaviorLinearLayoutandroid:idid/homepage_containerandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:orientationverticalFrameLayoutandroid:idid/contextual_cards_contentandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:layout_marginStartdimen/contextual_card_side_marginandroid:layout_marginEnddimen/contextual_card_side_margin/FrameLayoutandroid:idid/main_contentandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:animateLayoutChangestrueandroid:background?android:attr/windowBackground//LinearLayout/androidx.core.widget.NestedScrollView新方案思路基于焦点冲突问题那么就是解决焦点冲突所以可以尝试监听然后找到对应的焦点然后滑动对应的View. 这个方案可以自行研究这里暂不讨论 我自己尝试解决没有解决出来。如下代码是调试代码可以借鉴、找方向、定位问题/* NestedScrollView scrollView findViewById(R.id.main_content_scrollable_container); scrollView.setNestedScrollingEnabled(false); getWindow().getDecorView().setOnFocusChangeListener((v, hasFocus) - { View focusView getCurrentFocus(); if (focusView ! null focusView ! scrollView) { scrollView.post(() - { Log.d(TAG,setOnFocusChangeListener smoothScrollBy); int[] pos new int[2]; focusView.getLocationInWindow(pos); scrollView.smoothScrollBy(0, pos[1] - 100); }); } });*/Log.d(TAG,onCreate1111);/*final NestedScrollView scrollView findViewById(R.id.main_content_scrollable_container); scrollView.setSmoothScrollingEnabled(true); getWindow().getDecorView().getViewTreeObserver().addOnGlobalFocusChangeListener((oldFocus, newFocus) - { if (newFocus null) return; int[] location new int[2]; newFocus.getLocationInWindow(location); int focusBottom location[1] newFocus.getHeight(); int screenHeight getResources().getDisplayMetrics().heightPixels; Log.d(TAG,addOnGlobalFocusChangeListener focusBottom:focusBottom screenHeight:screenHeight); //addOnGlobalFocusChangeListener focusBottom:1179 screenHeight:1008 //addOnGlobalFocusChangeListener focusBottom:1297 screenHeight:1008 if (focusBottom screenHeight - 100) { scrollView.post(() - { scrollView.smoothScrollBy(0, 300); }); } }); *//* final NestedScrollView scrollView findViewById(R.id.main_content_scrollable_container); scrollView.setSmoothScrollingEnabled(true); getWindow().getDecorView().getViewTreeObserver().addOnGlobalFocusChangeListener((oldFocus, newFocus) - { if (newFocus null || scrollView null) return; int[] location new int[2]; newFocus.getLocationOnScreen(location); int focusBottom location[1] newFocus.getHeight(); int screenHeight getResources().getDisplayMetrics().heightPixels; Log.d(TAG, addOnGlobalFocusChangeListener focusBottom: focusBottom screenHeight: screenHeight); if (focusBottom screenHeight - 100) { scrollView.post(() - { int scrollY newFocus.getTop() - scrollView.getTop(); Log.d(TAG, addOnGlobalFocusChangeListener scrollY: scrollY newFocus.getTop():newFocus.getTop() scrollView.getTop():scrollView.getTop()); scrollView.scrollTo(0, scrollY); }); } }); *//* final NestedScrollView scrollView findViewById(R.id.main_content_scrollable_container); final ViewGroup mainContent findViewById(R.id.main_content); mainContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { Override public void onGlobalLayout() { mainContent.getViewTreeObserver().removeOnGlobalLayoutListener(this); RecyclerView recyclerView findRecyclerView(mainContent); if (recyclerView null){ Log.d(TAG, wfc addOnGlobalLayoutListener recyclerView null return ); return; } getWindow().getDecorView().getViewTreeObserver().addOnGlobalFocusChangeListener((oldFocus, newFocus) - { if (newFocus null || recyclerView null){ Log.d(TAG, wfc addOnGlobalFocusChangeListener newFocus null || recyclerView null ); return; } int[] loc new int[2]; newFocus.getLocationInWindow(loc); int bottom loc[1] newFocus.getHeight(); int screenHeight getResources().getDisplayMetrics().heightPixels; Log.d(TAG, wfc addOnGlobalFocusChangeListener bottom: bottom screenHeight: screenHeight); if (bottom screenHeight - 150) { recyclerView.post(() - { int position recyclerView.getChildAdapterPosition(newFocus); Log.d(TAG,wfc smoothScrollToPosition position:position); recyclerView.scrollBy(0, 350); }); } }); } });*//* final NestedScrollView scrollView findViewById(R.id.main_content_scrollable_container); getWindow().getDecorView().getViewTreeObserver().addOnGlobalFocusChangeListener((oldFocus, newFocus) - { if (newFocus null) return; newFocus.post(() - { newFocus.getWindowVisibleDisplayFrame(new Rect()); }); }); */finalViewGroupmainContentfindViewById(R.id.main_content);mainContent.getViewTreeObserver().addOnGlobalLayoutListener(newViewTreeObserver.OnGlobalLayoutListener(){OverridepublicvoidonGlobalLayout(){mainContent.getViewTreeObserver().removeOnGlobalLayoutListener(this);RecyclerViewrecyclerViewfindRecyclerView(mainContent);if(recyclerViewnull)return;intbottomPadding(int)(getResources().getDisplayMetrics().density*400);recyclerView.setPadding(recyclerView.getPaddingLeft(),recyclerView.getPaddingTop(),recyclerView.getPaddingRight(),bottomPadding);recyclerView.setClipToPadding(false);}});// }// modify by fangchen startprivateRecyclerViewfindRecyclerView(ViewGroupparent){for(inti0;iparent.getChildCount();i){Viewchildparent.getChildAt(i);if(childinstanceofRecyclerView){return(RecyclerView)child;}if(childinstanceofViewGroup){RecyclerViewrvfindRecyclerView((ViewGroup)child);if(rv!null)returnrv;}}returnnull;}// modify by fangchen end总结这里解决了Mtk平台 Android12 版本系统设置不适配遥控器问题针对性讨论了解决方案对比不同版本、不同的解决方案、找到实际解决方案并解决问题焦点问题才是核心不太好调试可以自行调试并解决。