Quando eu uso drawables da AppCompat
biblioteca para meus Toolbar
itens de menu, o tingimento funciona conforme o esperado. Como isso:
<item
android:id="@+id/action_clear"
android:icon="@drawable/abc_ic_clear_mtrl_alpha" <-- from AppCompat
android:title="@string/clear" />
Mas se eu usar meus próprios drawables ou mesmo copiar os drawables da AppCompat
biblioteca para meu próprio projeto, ele não tingirá de forma alguma.
<item
android:id="@+id/action_clear"
android:icon="@drawable/abc_ic_clear_mtrl_alpha_copy" <-- copy from AppCompat
android:title="@string/clear" />
Existe alguma magia especial em AppCompat
Toolbar
que apenas tingem os drawables dessa biblioteca? Alguma maneira de fazer isso funcionar com meus próprios drawables?
Executando isso no dispositivo API de nível 19 com compileSdkVersion = 21
e targetSdkVersion = 21
, e também usando tudo, desdeAppCompat
abc_ic_clear_mtrl_alpha_copy
é uma cópia exata do abc_ic_clear_mtrl_alpha
png deAppCompat
Editar:
O tingimento é baseado no valor que eu defini para o android:textColorPrimary
meu tema.
Por exemplo <item name="android:textColorPrimary">#00FF00</item>
, me daria uma cor de tonalidade verde.
Capturas de tela
Tingimento funcionando como esperado com drawable do AppCompat
O tingimento não funciona com drawable copiado do AppCompat
fonte
Respostas:
Porque se você der uma olhada no código-fonte do TintManager no AppCompat, você verá:
O que significa que eles têm resourceIds específicos na lista de permissões para serem coloridos.
Mas acho que você sempre pode ver como eles estão tingindo essas imagens e fazer o mesmo. É tão fácil quanto definir o ColorFilter em um drawable.
fonte
Após a nova Biblioteca de suporte v22.1, você pode usar algo semelhante a este:
fonte
setColorFilter()
é preferível.Definir a
ColorFilter
(matiz) em aMenuItem
é simples. Aqui está um exemplo:O código acima é muito útil se você deseja oferecer suporte a temas diferentes e não deseja ter cópias extras apenas para a cor ou transparência.
Clique aqui para uma classe auxiliar para definir um
ColorFilter
em todos os drawables em um menu, incluindo o ícone de estouro.Em
onCreateOptionsMenu(Menu menu)
apenas chamadaMenuColorizer.colorMenu(this, menu, color);
depois de inflar seu menu e pronto; seus ícones são coloridos.fonte
app:iconTint
atributo é implementado naSupportMenuInflater
biblioteca de suporte (pelo menos em 28.0.0).Testado com sucesso com API 15 e superior.
Arquivo de recurso de menu:
(Neste caso,
?attr/appIconColorEnabled
era um atributo de cor personalizada nos temas do aplicativo, e os recursos de ícone eram drawables vetoriais.)fonte
android:iconTint
eandroid:iconTintMode
não funcione, mas prefixar com emapp:
vez deandroid:
funciona como um encanto (em meus próprios drawables vetoriais, API> = 21)SupportMenuInflater
não vai aplicar qualquer lógica personalizada se o menu não é umSupportMenu
comoMenuBuilder
, ele só cai de volta ao normalMenuInflater
.AppCompatActivity.startSupportActionMode(callback)
e as implementações de suporte apropriadas deandroidx.appcompat
serão passados para o retorno de chamada.Eu pessoalmente preferi essa abordagem a partir deste link
Crie um layout XML com o seguinte:
e referencie este drawable em seu menu:
fonte
bitmap
. Existem outras maneiras de colorir vetores. Talvez alguém possa adicionar coloração vetorial aqui também ...A maioria das soluções neste segmento usa uma API mais recente, ou usa reflexão, ou usa pesquisa de visualização intensiva para chegar ao
MenuItem
.No entanto, há uma abordagem mais elegante para fazer isso. Você precisa de uma barra de ferramentas personalizada, já que seu caso de uso de "aplicar tonalidade personalizada" não funciona bem com a API de estilo / tema público.
Apenas certifique-se de chamar seu código de atividade / fragmento:
Sem reflexo, sem visualização de visualização e sem tanto código, hein?
E agora você pode ignorar o ridículo
onCreateOptionsMenu/onOptionsItemSelected
.fonte
Menu#getItem()
complexidade é O (1) na barra de ferramentas, porque os itens são armazenados em ArrayList. O que é diferente deView#findViewById
travessia (a que me referi como pesquisa de visualização na minha resposta), cuja complexidade está longe de ser constante :-)Aqui está a solução que utilizo; você pode chamá-lo após onPrepareOptionsMenu () ou em um local equivalente. O motivo para mutate () é se você usar os ícones em mais de um local; sem a mutação, todos eles assumirão a mesma tonalidade.
Isso não vai cuidar do estouro, mas para isso, você pode fazer o seguinte:
Layout:
Estilos:
Isso funciona a partir de appcompat v23.1.0.
fonte