android 9.0 launcher3 去掉抽屉式显示所有 app(代码详解)
效果图
修改思路
1、增加全局控制变量sys.launcher3.is_full_app,用来动态切换
2、增加两套布局,对应有抽屉和无抽屉
3、去除allAppsButton
4、将AllAppsContainerView中的图标加载到Workspace
5、新安装的app自动添加图标到Workspace
6、替换Workspace图标长按删除选项为取消
7、屏蔽上拉显示抽屉页面手势
8、修改页面指示线为圆点
上代码
1、增加全局控制变量sys.launcher3.is_full_app
1)在LauncherAppState中增加静态方法isDisableAllApps(),通过修改Settings中自定义的值sys.launcher3.is_full_app
vendor\mediatek\proprietary\packages\apps\Launcher3\src\com\android\launcher3\LauncherAppState.java
privatestaticContextmContext;
publicstaticbooleanisDisableAllApps(){
if(mContext!=null){
returnSettings.System.getInt(mContext.getContentResolver(),
"sys.launcher3.is_full_app",0)==1;
}
returntrue;
}
vendor\mediatek\proprietary\packages\apps\Launcher3\AndroidManifest-common.xml
2)AndroidManifest-common.xml中增加权限
3)在SettingsActivity中增加SwitchPreference用以动态修改sys.launcher3.is_full_app
vendor\mediatek\proprietary\packages\apps\Launcher3\src\com\android\launcher3\SettingsActivity.java
在内部类LauncherSettingsFragment中重写onPreferenceTreeClick()用以监听SwitchPreference点击
/**
*Thisfragmentshowsthelauncherpreferences.
*/
publicstaticclassLauncherSettingsFragmentextendsPreferenceFragment{
.....
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
....
//读取保存的值,初始化SwitchPreference的初始状态,是否选中
intisFull=Settings.System.getInt(getActivity().getContentResolver(),
"sys.launcher3.is_full_app",0);
Log.d("Launcher3","sys.launcher3.is_full_app="+isFull);
SwitchPreferencefullSwitch=(SwitchPreference)findPreference("pref_is_full_app");
fullSwitch.setChecked(isFull==1);
}
//addforchangeis_full_appvalue
@Override
publicbooleanonPreferenceTreeClick(PreferenceScreenpreferenceScreen,Preferencepreference){
booleanresult=true;
finalStringkey=preference.getKey();
if("pref_is_full_app".equals(key)){
booleanchecked=((SwitchPreference)preference).isChecked();
Settings.System.putInt(getActivity().getContentResolver(),"sys.launcher3.is_full_app",
checked?1:0);
Log.e("Launcher3","SwitchPreferencechecked="+checked);
//Valuehaschanged
ProgressDialog.show(getActivity(),
null/*title*/,
getActivity().getString(R.string.full_app_override_progress),
true/*indeterminate*/,
false/*cancelable*/);
newLooperExecutor(LauncherModel.getWorkerLooper()).execute(
newOverrideApplyHandler(getActivity()));
}
returnresult;
}
}
点击SwitchPreference后需要保存sys.launcher3.is_full_app新值,同时清除Launcher3的缓存,延时启动并结束当前进程
清除缓存方法clearApplicationUserData在Launcher3中编译报错,所以通过发送广播到Setting中进行真正的清缓存操作
//addforchangeis_full_appvalue
privatestaticclassOverrideApplyHandlerimplementsRunnable{
privatefinalContextmContext;
privateOverrideApplyHandler(Contextcontext){
mContext=context;
}
@Override
publicvoidrun(){
//Cleartheiconcache.
LauncherAppState.getInstance(mContext).getIconCache().clear();
//Waitforit
try{
Thread.sleep(1000);
}catch(Exceptione){
Log.e("Launcher3","Errorwaiting",e);
}
//Scheduleanalarmbeforewekillourself.
IntenthomeIntent=newIntent(Intent.ACTION_MAIN)
.addCategory(Intent.CATEGORY_HOME)
.setPackage(mContext.getPackageName())
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntentpi=PendingIntent.getActivity(mContext,42,
homeIntent,PendingIntent.FLAG_CANCEL_CURRENT|PendingIntent.FLAG_ONE_SHOT);
mContext.getSystemService(AlarmManager.class).setExact(
AlarmManager.ELAPSED_REALTIME,SystemClock.elapsedRealtime()+50,pi);
//cleardatawillkillprocess
Intentintent=newIntent("com.android.action.CLEAR_APP_DATA");
intent.putExtra("pkgName","com.android.launcher3");
intent.addFlags(0x01000000);
mContext.sendBroadcast(intent);
Log.i("Launcher3","Clearinguserdatacom.android.launcher3");
//Killprocess
android.os.Process.killProcess(android.os.Process.myPid());
}
}
4)SettingsActivity对应的xml文件修改launcher_preferences
vendor\mediatek\proprietary\packages\apps\Launcher3\res\xml\launcher_preferences.xml
对应的string文件就不贴了,自己增加下就行
2、增加两套布局,对应有抽屉和无抽屉
加载布局文件对应的xml为vendor\mediatek\proprietary\packages\apps\Launcher3\res\xml\device_profiles.xml
Launcher3通过获取minWidthDps和minHeightDps来确定加载哪一个profile,我的平板分辨率是1280*800的,增加两个profile节点
对应的你需要在xml文件下增加4个文件,分别是default_workspace_tb_5x6.xmldw_hotseat_tb.xmldefault_workspace_tb_5x6_no_all_app.xmldw_hotseat_tb_no_all_app.xml
这样的好处是你可以自定义不同的布局文件加载内容,上面的配置含义简单说一下,分别是最小宽度、最小高度、布局的行和列、文件夹中布局行和列、图标大小、图标文字大小、HotSeat个数,加载的布局文件
在InvariantDeviceProfile()判断是否需要加载Tablet_no_all_appprofile
vendor\mediatek\proprietary\packages\apps\Launcher3\src\com\android\launcher3\InvariantDeviceProfile.java
publicInvariantDeviceProfile(Contextcontext){
WindowManagerwm=(WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
Displaydisplay=wm.getDefaultDisplay();
DisplayMetricsdm=newDisplayMetrics();
display.getMetrics(dm);
PointsmallestSize=newPoint();
PointlargestSize=newPoint();
display.getCurrentSizeRange(smallestSize,largestSize);
//Thisguaranteesthatwidth
3、去除allAppsButton
vendor\mediatek\proprietary\packages\apps\Launcher3\src\com\android\launcher3\Hotseat.java
将resetLayout()中FeatureFlags.NO_ALL_APPS_ICON替换为LauncherAppState.isDisableAllApps()
voidresetLayout(booleanhasVerticalHotseat){
mContent.removeAllViewsInLayout();
mHasVerticalHotseat=hasVerticalHotseat;
InvariantDeviceProfileidp=mLauncher.getDeviceProfile().inv;
if(hasVerticalHotseat){
mContent.setGridSize(1,idp.numHotseatIcons);
}else{
mContent.setGridSize(idp.numHotseatIcons,1);
}
//if(!FeatureFlags.NO_ALL_APPS_ICON){
///addforcheckisneedallappbutton
if(!LauncherAppState.isDisableAllApps()){
//AddtheAppsbutton
Contextcontext=getContext();
DeviceProfilegrid=mLauncher.getDeviceProfile();
...
}
4、将AllAppsContainerView中的图标加载到Workspace
vendor\mediatek\proprietary\packages\apps\Launcher3\src\com\android\launcher3\model\LoaderTask.java
run()中增加判断,添加verifyApplications(),修改InstallShortcutReceiver中PendingInstallShortcutInfo为public
publicvoidrun(){
synchronized(this){
//Skipfastifwearealreadystopped.
if(mStopped){
return;
}
}
....
//secondstep
TraceHelper.partitionSection(TAG,"step2.1:loadingallapps");
loadAllApps();
//addforloadallapponworkspace
if(LauncherAppState.isDisableAllApps()){
android.util.Log.e("Launcher3","verifyApplications()");
verifyApplications();
}
....
}
//addforloadallapponworkspace
privatevoidverifyApplications(){
finalContextcontext=mApp.getContext();
ArrayList>installQueue=newArrayList<>();
finalListprofiles=mUserManager.getUserProfiles();
for(UserHandleuser:profiles){
finalListapps=mLauncherApps.getActivityList(null,user);
ArrayListadded=newArrayList();
synchronized(this){
for(LauncherActivityInfoapp:apps){
InstallShortcutReceiver.PendingInstallShortcutInfopendingInstallShortcutInfo=newInstallShortcutReceiver.PendingInstallShortcutInfo(app,context);
added.add(pendingInstallShortcutInfo);
installQueue.add(pendingInstallShortcutInfo.getItemInfo());
}
}
if(!added.isEmpty()){
mApp.getModel().addAndBindAddedWorkspaceItems(installQueue);
}
}
}
vendor\mediatek\proprietary\packages\apps\Launcher3\src\com\android\launcher3\model\BaseModelUpdateTask.java
注释run()中的return
@Override
publicfinalvoidrun(){
if(!mModel.isModelLoaded()){
if(DEBUG_TASKS){
Log.d(TAG,"Ignoringmodeltasksinceloaderispending="+this);
}
//Loaderhasnotyetrun.
//annotaionforloadallapponworkspace
//return;
}
execute(mApp,mDataModel,mAllAppsList);
}
5、新安装的app自动添加图标到Workspace
vendor\mediatek\proprietary\packages\apps\Launcher3\src\com\android\launcher3\model\PackageUpdatedTask.java
execute()中增加判断,添加updateToWorkSpace()
publicvoidexecute(LauncherAppStateapp,BgDataModeldataModel,AllAppsListappsList){
....
finalArrayListaddedOrModified=newArrayList<>();
addedOrModified.addAll(appsList.added);
//addforloadnewinstallapponworkspace
if(LauncherAppState.isDisableAllApps()){
android.util.Log.e("cczLauncher3","updateToWorkSpace()");
updateToWorkSpace(context,app,appsList);
}
...
}
//addforloadnewinstallapponworkspace
publicvoidupdateToWorkSpace(Contextcontext,LauncherAppStateapp,AllAppsListappsList){
ArrayList>installQueue=newArrayList<>();
finalListprofiles=UserManagerCompat.getInstance(context).getUserProfiles();
ArrayListadded
=newArrayList();
for(UserHandleuser:profiles){
finalListapps=LauncherAppsCompat.getInstance(context).getActivityList(null,user);
synchronized(this){
for(LauncherActivityInfoinfo:apps){
for(AppInfoappInfo:appsList.added){
if(info.getComponentName().equals(appInfo.componentName)){
InstallShortcutReceiver.PendingInstallShortcutInfomPendingInstallShortcutInfo
=newInstallShortcutReceiver.PendingInstallShortcutInfo(info,context);
added.add(mPendingInstallShortcutInfo);
installQueue.add(mPendingInstallShortcutInfo.getItemInfo());
}
}
}
}
}
if(!added.isEmpty()){
app.getModel().addAndBindAddedWorkspaceItems(installQueue);
}
}
6、替换Workspace图标长按删除选项为取消
vendor\mediatek\proprietary\packages\apps\Launcher3\src\com\android\launcher3\DeleteDropTarget.java
在setTextBasedOnDragSource()、setControlTypeBasedOnDragSource()、onAccessibilityDrop()中分别增加判断是否需要删除图标
privatevoidsetTextBasedOnDragSource(ItemInfoitem){
if(!TextUtils.isEmpty(mText)){
mText=getResources().getString(item.id!=ItemInfo.NO_ID
?R.string.remove_drop_target_label
:android.R.string.cancel);
//addforhidedeletedroptarget
if(LauncherAppState.isDisableAllApps()){
android.util.Log.e("Launcher3","hidedeletedroptarget");
mText=getResources().getString(isCanDrop(item)
?R.string.remove_drop_target_label
:android.R.string.cancel);
}
requestLayout();
}
}
privatevoidsetControlTypeBasedOnDragSource(ItemInfoitem){
mControlType=item.id!=ItemInfo.NO_ID?ControlType.REMOVE_TARGET
:ControlType.CANCEL_TARGET;
//addforhidedeletedroptarget[S]
if(LauncherAppState.isDisableAllApps()){
mControlType=isCanDrop(item)?ControlType.REMOVE_TARGET
:ControlType.CANCEL_TARGET;
}
}
publicvoidonAccessibilityDrop(Viewview,ItemInfoitem){
//Removetheitemfromlauncherandthedb,wecanignorethecontainerInfointhiscall
//becausewealreadyremovethedragviewfromthefolder(ifthedragoriginatedfrom
//afolder)inFolder.beginDrag()
//addifjugeisneedremoveitemfromworkspace
if(!LauncherAppState.isDisableAllApps()||isCanDrop(item)){
mLauncher.removeItem(view,item,true/*deleteFromDb*/);
mLauncher.getWorkspace().stripEmptyScreens();
mLauncher.getDragLayer()
.announceForAccessibility(getContext().getString(R.string.item_removed));
}
}
privatebooleanisCanDrop(ItemInfoitem){
return!(item.itemType==LauncherSettings.Favorites.ITEM_TYPE_APPLICATION||
item.itemType==LauncherSettings.Favorites.ITEM_TYPE_FOLDER);
}
vendor\mediatek\proprietary\packages\apps\Launcher3\src\com\android\launcher3\dragndrop\DragController.java
drop()中增加判断,取消当前拖拽操作
privatevoiddrop(DropTargetdropTarget,RunnableflingAnimation){
....
booleanaccepted=false;
if(dropTarget!=null){
dropTarget.onDragExit(mDragObject);
if(dropTarget.acceptDrop(mDragObject)){
if(flingAnimation!=null){
flingAnimation.run();
}else{
dropTarget.onDrop(mDragObject,mOptions);
}
accepted=true;
//addforcancelcanceldroptargethandle
if(LauncherAppState.isDisableAllApps()&&dropTargetinstanceofDeleteDropTarget&&
isNeedCancelDrag(mDragObject.dragInfo)){
cancelDrag();
}
}
}
...
}
privatebooleanisNeedCancelDrag(ItemInfoitem){
return(item.itemType==LauncherSettings.Favorites.ITEM_TYPE_APPLICATION||
item.itemType==LauncherSettings.Favorites.ITEM_TYPE_FOLDER);
}
7、屏蔽上拉显示抽屉页面手势
vendor\mediatek\proprietary\packages\apps\Launcher3\quickstep\src\com\android\launcher3
\uioverrides\OverviewToAllAppsTouchController.java
canInterceptTouch()中增加判断是否直接拦截
@Override
protectedbooleancanInterceptTouch(MotionEventev){
//addforforbiddenworkspacedragchangeGradientViewalph
if(LauncherAppState.isDisableAllApps()){
android.util.Log.e("Launcher3","canInterceptTouch()");
returnfalse;
}
if(mCurrentAnimation!=null){
//Ifwearealreadyanimatingfromapreviousstate,wecanintercept.
returntrue;
}
if(AbstractFloatingView.getTopOpenView(mLauncher)!=null){
returnfalse;
}
if(mLauncher.isInState(ALL_APPS)){
//Inall-appsonlylistenifthecontainercannotscrollitself
returnmLauncher.getAppsView().shouldContainerScroll(ev);
}elseif(mLauncher.isInState(NORMAL)){
returntrue;
}elseif(mLauncher.isInState(OVERVIEW)){
RecentsViewrv=mLauncher.getOverviewPanel();
returnev.getY()>(rv.getBottom()-rv.getPaddingBottom());
}else{
returnfalse;
}
}
8、修改页面指示线为圆点
vendor\mediatek\proprietary\packages\apps\Launcher3\res\layout\launcher.xml
WorkspacePageIndicator改为PageIndicatorDots
vendor\mediatek\proprietary\packages\apps\Launcher3\src\com\android\launcher3
\pageindicators\PageIndicatorDots.java
增加PageIndicatorDots继承Insettable,复写setInsets(),调整圆点的位置
publicclassPageIndicatorDotsextendsViewimplementsPageIndicator,Insettable{
//addforchangeWorkspacePageIndicatorlinetodot
@Override
publicvoidsetInsets(Rectinsets){
DeviceProfilegrid=mLauncher.getDeviceProfile();
FrameLayout.LayoutParamslp=(FrameLayout.LayoutParams)getLayoutParams();
if(grid.isVerticalBarLayout()){
Rectpadding=grid.workspacePadding;
lp.leftMargin=padding.left+grid.workspaceCellPaddingXPx;
lp.rightMargin=padding.right+grid.workspaceCellPaddingXPx;
lp.bottomMargin=padding.bottom;
}else{
lp.leftMargin=lp.rightMargin=0;
lp.gravity=Gravity.CENTER_HORIZONTAL|Gravity.BOTTOM;
lp.bottomMargin=grid.hotseatBarSizePx+insets.bottom;
}
setLayoutParams(lp);
}
@Override
publicvoidsetScroll(intcurrentScroll,inttotalScroll){
if(mNumPages>1){
if(mIsRtl){
currentScroll=totalScroll-currentScroll;
}
intscrollPerPage=totalScroll/(mNumPages-1);
//addforchangeWorkspacePageIndicatorlinetodot
if(scrollPerPage==0){
return;
}
intpageToLeft=currentScroll/scrollPerPage;
intpageToLeftScroll=pageToLeft*scrollPerPage;
intpageToRightScroll=pageToLeftScroll+scrollPerPage;
...
}
vendor\mediatek\proprietary\packages\apps\Launcher3\src\com\android\launcher3
\states\SpringLoadedState.java
注释setShouldAutoHide(),避免长按workSpace时发生崩溃
@Override
publicvoidonStateEnabled(Launcherlauncher){
Workspacews=launcher.getWorkspace();
ws.showPageIndicatorAtCurrentScroll();
//annotaionforWorkspacePageIndicatorlinetodot
//ws.getPageIndicator().setShouldAutoHide(false);
//PreventanyUn/InstallShortcutReceiversfromupdatingthedbwhileweare
//inspringloadedmode
InstallShortcutReceiver.enableInstallQueue(InstallShortcutReceiver.FLAG_DRAG_AND_DROP);
launcher.getRotationHelper().setCurrentStateRequest(REQUEST_LOCK);
}
@Override
publicvoidonStateDisabled(finalLauncherlauncher){
//annotaionforWorkspacePageIndicatorlinetodot
//launcher.getWorkspace().getPageIndicator().setShouldAutoHide(true);
//Re-enableanyUn/InstallShortcutReceiverandnowprocessanyqueueditems
InstallShortcutReceiver.disableAndFlushInstallQueue(
InstallShortcutReceiver.FLAG_DRAG_AND_DROP,launcher);
}
总结
以上所述是小编给大家介绍的android9.0launcher3去掉抽屉式显示所有app代码详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。