Prefácio
Recentemente recebi uma solicitação de certificação EDLA do Google. Sou responsável pela modificação do layout nativo da área de trabalho do Google. Ao estudar o código-fonte, postarei algumas idéias de modificação envolvidas. Você pode consultá-lo para ver se há alguma informação útil para você. As principais modificações incluem:
1. A barra de pesquisa e a barra de navegação inferior não estão centralizadas.
2. Os aplicativos no meio não estão organizados conforme necessário. Consulte o Mocke para obter detalhes.
3. S-write neutro, Kshare de espelhamento de tela e aplicativos de página de boas-vindas não são adicionado ao desktop nativo do Google.
Situação da FIG:
Imagem de referência:
1. Modificações na caixa de pesquisa do Google
As áreas envolvidas nas modificações são:
1、Launcher3\res\xml\device_profiles.xml
2、com/android/launcher3/Workspace.java
1. Primeiro observe o código device_profiles.xml. Geralmente, dispositivos de tela grande (tablets) carregam o layout 6*5 e dispositivos móveis carregam o layout do telefone celular. Existem quatro tipos de layout diferentes definidos neste arquivo. Como determinar qual layout é carregado pelo dispositivo?Pano de lã? Você pode manter pressionado o ícone do aplicativo na área de trabalho, observar quantas grades podem ser movidas e encontrar a posição do layout a ser modificada com base no número de linhas e colunas. Por exemplo, meu dispositivo carrega um layout 6 * 5. Eu modifico aqui **launcher:numSearchContainerColumns="5"** para modificar a caixa de pesquisa do Google para ocupar 5 grades (um total de 7 grades na tela horizontal)
<--这个行数可以根据自己想要的效果修改,比如我就改了7*6布局,6行7列--/>
<grid-option
launcher:name="6_by_5"
launcher:numRows="6"
launcher:numColumns="7"
launcher:numSearchContainerColumns="5"
launcher:numFolderRows="3"
launcher:numFolderColumns="4"
launcher:numHotseatIcons="0"
launcher:hotseatColumnSpanLandscape="2"
launcher:numAllAppsColumns="6"
launcher:isScalable="true"
launcher:inlineNavButtonsEndSpacing="@dimen/taskbar_button_margin_6_5"
launcher:devicePaddingId="@xml/paddings_6x5"
launcher:dbFile="launcher_6_by_5.db"
launcher:defaultLayoutId="@xml/default_workspace_6x5"
launcher:deviceCategory="tablet" >
<display-option
launcher:name="Tablet"
launcher:minWidthDps="900"
launcher:minHeightDps="820"
launcher:minCellHeight="120"
launcher:minCellWidth="102"
launcher:minCellHeightLandscape="104"
launcher:minCellWidthLandscape="120"
launcher:iconImageSize="60"
launcher:iconTextSize="14"
launcher:borderSpaceHorizontal="16"
launcher:borderSpaceVertical="64"
launcher:borderSpaceLandscapeHorizontal="64"
launcher:borderSpaceLandscapeVertical="16"
launcher:horizontalMargin="54"
launcher:horizontalMarginLandscape="120"
launcher:allAppsCellWidth="96"
launcher:allAppsCellHeight="142"
launcher:allAppsCellWidthLandscape="126"
launcher:allAppsCellHeightLandscape="126"
launcher:allAppsIconSize="60"
launcher:allAppsIconTextSize="14"
launcher:allAppsBorderSpaceHorizontal="8"
launcher:allAppsBorderSpaceVertical="16"
launcher:allAppsBorderSpaceLandscape="16"
launcher:hotseatBarBottomSpace="30"
launcher:hotseatBarBottomSpaceLandscape="40"
launcher:canBeDefault="true" />
</grid-option>
</profiles>
2. Modifique a posição da caixa de pesquisa do Google em workspace.java. Encontre este método na classe: bindAndInitFirstWorkspaceScreen e localize-o aqui.
public void bindAndInitFirstWorkspaceScreen() {
if (!FeatureFlags.QSB_ON_FIRST_SCREEN) {
return;
}
// Add the first page
CellLayout firstPage = insertNewWorkspaceScreen(Workspace.FIRST_SCREEN_ID, getChildCount());
// Always add a first page pinned widget on the first screen.
if (mFirstPagePinnedItem == null) {
// In transposed layout, we add the first page pinned widget in the Grid.
// As workspace does not touch the edges, we do not need a full
// width first page pinned widget.
mFirstPagePinnedItem = LayoutInflater.from(getContext())
.inflate(R.layout.search_container_workspace, firstPage, false);
}
int cellHSpan = mLauncher.getDeviceProfile().inv.numSearchContainerColumns;
//格子数从0开始算,这里表示搜索框位置从X轴第2格子,y轴第3个格子算起,x轴占据5(cellHSpan)个格子,y轴占据1个格子
CellLayoutLayoutParams lp = new CellLayoutLayoutParams(1, 2, cellHSpan, 1, FIRST_SCREEN_ID);
lp.canReorder = false;
if (!firstPage.addViewToCellLayout(
mFirstPagePinnedItem, 0, R.id.search_container_workspace, lp, true)) {
Log.e(TAG, "Failed to add to item at (0, 0) to CellLayout");
mFirstPagePinnedItem = null;
}
}
Dica: Se não houver uma caixa de pesquisa do Google na área de trabalho no início, você poderá adicioná-la na forma de um widget. Existem duas situações ao adicionar um widget. O método específico a ser usado depende se o sistema leu a configuração arquivo. Caso contrário, use-o. A primeira é adicioná-lo diretamente ao arquivo de layout, como res/xml/default_workspace_6x5.xml:
<appwidget
container="-100"
screen="0"
x="1"
y="2"
spanX="5"
spanY="1"
packageName="com.google.android.googlequicksearchbox"
className="com.google.android.googlequicksearchbox.SearchWidgetProvider"/>
Outra maneira é adicionar: release\vendor\partner_gms\apps\GmsSampleIntegration\res_dhs_full\xml\partner_default_layout.xml ao arquivo de configuração no pacote google_gms, por exemplo
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2017 Google Inc. All Rights Reserved. -->
<favorites>
<!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
<!-- Dialer Messaging Calendar Contacts Camera -->
<!--<favorite container="-101" screen="0" x="0" y="0" packageName="com.google.android.dialer" className="com.google.android.dialer.extensions.GoogleDialtactsActivity"/>-->
<!--<favorite container="-101" screen="1" x="1" y="0" packageName="com.google.android.apps.messaging" className="com.google.android.apps.messaging.ui.ConversationListActivity"/>-->
<!-- <favorite container="-101" screen="0" x="0" y="0" packageName="com.android.settings" className="com.android.settings.Settings"/> -->
<!-- <favorite container="-101" screen="1" x="1" y="0" packageName="com.android.deskclock" className="com.android.deskclock.DeskClock"/> -->
<!-- <favorite container="-101" screen="2" x="2" y="0" packageName="com.google.android.calendar" className="com.android.calendar.event.LaunchInfoActivity"/> -->
<!-- <favorite container="-101" screen="3" x="3" y="0" packageName="com.google.android.contacts" className="com.android.contacts.activities.PeopleActivity"/> -->
<!-- <favorite container="-101" screen="4" x="4" y="0" packageName="com.android.camera2" className="com.android.camera.CameraLauncher"/> -->
<!-- In Launcher3, workspaces extend infinitely to the right, incrementing from zero -->
<!-- Google folder -->
<!-- Google, Chrome, Gmail, Maps, YouTube, (Drive), (Music), (Movies), Duo, Photos -->
<folder title="@string/google_folder_title" screen="0" x="1" y="3">
<favorite packageName="com.google.android.googlequicksearchbox" className="com.google.android.googlequicksearchbox.SearchActivity"/>
<favorite packageName="com.android.chrome" className="com.google.android.apps.chrome.Main"/>
<favorite packageName="com.google.android.gm" className="com.google.android.gm.ConversationListActivityGmail"/>
<favorite packageName="com.google.android.apps.maps" className="com.google.android.maps.MapsActivity"/>
<favorite packageName="com.google.android.youtube" className="com.google.android.youtube.app.honeycomb.Shell$HomeActivity"/>
<favorite packageName="com.google.android.apps.docs" className="com.google.android.apps.docs.app.NewMainProxyActivity"/>
<favorite packageName="com.google.android.apps.youtube.music" className="com.google.android.apps.youtube.music.activities.MusicActivity"/>
<favorite packageName="com.google.android.videos" className="com.google.android.videos.GoogleTvEntryPoint"/>
<favorite packageName="com.google.android.apps.tachyon" className="com.google.android.apps.tachyon.MainActivity"/>
<favorite packageName="com.google.android.apps.photos" className="com.google.android.apps.photos.home.HomeActivity"/>
</folder>
<favorite screen="0" x="5" y="3" packageName="com.android.vending" className="com.android.vending.AssetBrowserActivity"/>
<appwidget screen="0" x="2" y="0" packageName="com.android.deskclock" className="com.android.alarmclock.DigitalAppWidgetProvider" spanX="3" spanY="2" />
<appwidget screen="0" x="1" y="2" packageName="com.google.android.googlequicksearchbox" className="com.google.android.googlequicksearchbox.SearchWidgetProvider" spanX="5" spanY="1" />
</favorites>
O conteúdo comentado é o aplicativo que define a exibição do hotSeat na área de trabalho. A tag appwidget é usada para adicionar widgets. O relógio da área de trabalho pode ser adicionado assim. A tag folder define uma pasta da área de trabalho, que pode definir os aplicativos a serem armazenados na pasta. .
2. Modifique a posição do aplicativo na primeira tela
Assim como a caixa de pesquisa do Google, o número de linhas e colunas da área de trabalho é definido no arquivo device_profiles.xml e, em seguida, o local modificado é determinado com base na leitura do arquivo de layout do parceiro_default_layout.xml pelo sistema; (1) Se for leia, está em parceiro_default_layout.xml Defina o nome do pacote, tipo e informações de localização do aplicativo. Por exemplo, <favorite screen="0" x="5" y="3" packageName="com.android.vending" className="com.android.vending.AssetBrowserActivity"/>
adicione o aplicativo Google Store na 6ª coluna da tela = "0" (primeira tela) e na 4ª linha da grade . (2) Se o arquivo de layout partner_default_layout.xml não for lido, modifique o local do aplicativo no X×X.xml correspondente.
3. Modificação da barra de tarefas inferior e barra de navegação
1. Se a aplicação hotSeat estiver configurada para ficar na parte inferior, ou seja, a tag container="-101" definida em parceiro_default_layout.xml (parte do código comentado no arquivo), então a aplicação fixada na parte inferior irá será exibido na área de trabalho. Exibe a barra de tarefas recente. Se os aplicativos fixados do hotSeat forem bloqueados, a barra de tarefas recente será exibida por padrão para substituir os aplicativos fixados. O número de ícones exibidos na barra de tarefas recente está relacionado ao iniciador:numHotseatIcons=" 0" no arquivo device_profiles.xml. o isTablet atributo para false , o que significa configurar o dispositivo para Na tela do celular, a barra de tarefas recente não é exibida na tela do celular e a barra de navegação será centralizada por padrão. Tentei esse método, mas não funciona em grandes -dispositivos de tela grande e não conseguem obter o efeito desejado. Você pode ler o que ele escreveu: Dispositivos de tela grande Barra de navegação à direita
2. Se você usar meu método, defina o número de ícones exibidos pelo hotSeat como 0: launcher:numHotseatIcons="0"
Se você compilá-lo diretamente, ocorrerá uma exceção de tempo de execução durante o tempo de execução. Ao capturar o log, você descobrirá que há muitos lugares no código-fonte que será removido ao calcular o layout. Pegue numHotseatIcons e sabemos que o divisor não pode ser 0, então a área de trabalho trava com um erro. Neste momento, precisamos modificar o local onde a exceção é causada ( observe que definir numHotseatIcons como 1 e 0 causará uma exceção , porque há uma operação -1 em numHotseatIcons). O local modificado é o seguinte:
com/android /launcher3/DeviceProfile.java
Nesta categoria, pressione ctrl+F para pesquisar numShownHotseatIcons. Todos os cálculos relacionados a numShownHotseatIcons serão julgados. Se for 0, você pode alterar o algoritmo para outro. Você
também pode pesquisar e rastrear a variável numHotseatIcons globalmente em device_profiles.xml primeiro e acompanhe-o passo a passo. Vá para a classe DeviceProfile.java, que tornará todo o processo mais claro.
Aqui está o local específico de minhas modificações. As capturas de tela têm números de linha para sua referência:
Aviso este método, que também é usado nele.
Modifique esses dois métodos de cálculo
e modifique-os aqui. Removemos a barra de tarefas recente! !
4. O próximo passo é centralizar a barra de navegação
Primeiro, observamos o arquivo device_profiles.xml e percebemos que existe essa variável.
Procurando por essa variável, rastreamos o código e descobrimos que essa variável controla o valor dp da barra de navegação inferior a partir da borda direita. Quanto maior o valor, quanto mais próximo estiver do meio. Com essa ideia, não será difícil centralizar a barra de navegação. Em primeiro lugar, sabemos que a barra de navegação está centralizada à direita porque o sistema determina que se trata de um dispositivo de tela grande tablet. Como queremos manter o atributo tablet, não podemos controlar a centralização da barra de navegação alterando o dispositivo para o modo móvel. Portanto, você pode controlar a margem direita!
Alterar esse valor é muito simples. Você só precisa alterar o valor do recurso referenciado.
Entramos no arquivo e alteramos a margem direita.
Você pode depurar esse valor lentamente. Estou centralizado aqui.
5. Resumo
Escreva um resumo: primeiro, determine se o sistema carrega o arquivo de layout em parceiro_gms e, em seguida, modifique o código do layout. Estudei esse código-fonte por mais de uma semana. Não há informações suficientes sobre o launcher3 do Android 13 na Internet. No final, eu mesmo tenho que estudar o código de rastreamento do código-fonte e compilar e depurar durante o período. Dezenas de vezes! !
efeito final