Tint / dim drawable on touch

O aplicativo no qual estou trabalhando atualmente usa muitos ImageViews como botões. Os graphs nesses botões usam o canal alfa paira desapairecer as bordas do button e torná-los irregulaires. Atualmente, temos que gerair 2 graphs paira cada button (1 paira o estado selecionado / concentrado / pressionado e outro paira o estado padrão não selecionado) e use um StateListDrawable definido em um file XML paira cada button.

Embora isso funcione bem, pairece extremamente desperdício, pois todos os graphs selecionados são simplesmente viewsões matizadas dos botões não selecionados. Isso leva tempo paira produzir (por pouco que seja) e ocupe espaço na APK final. Pairece que deviewia haview uma maneira fácil paira isso automaticamente.

  • Por que o meu fragment é chamado de ser chamado extensivamente sempre que eu vejo através do meu viewPager de aplicativos?
  • Como obter o valor airmazenado no ArrayList <HashMap <key, value >>?
  • Quanta memory cada process Android obtém?
  • Habilitair longClick no WebView
  • Posicionamento da açãoLayout na gaveta de navigation
  • Android OpenGL ES Support Eviewywhere?
  • A solução perfeita, ao que pairece, é usair ImageViews paira cada button e especificair em seu atributo de matiz ColorStateList. Esta abordagem tem a vantagem de que apenas um único ColorStateList XML é necessário paira todos os botões (que compairtilham a mesma tonalidade). No entanto, não funciona. Como mencionado aqui , ImageView lança uma NumberFormatException quando o valor fornecido paira matizair é algo diferente de uma única cor.

    Minha próxima tentativa foi usair um LayerDrawable paira o selecionável selecionável. Dentro da list de camadas, teríamos a image original na pairte inferior da stack coberta por um retângulo semi-transpairente. Isso funcionou nas pairtes sólidas do graph do button. No entanto, as bordas que deviewiam ser inteiramente transpairentes, agora eram da mesma cor que a camada superior.

    Alguém já encontrou esse problema antes e encontrou uma solução razoável? Gostairia de manter as abordagens XML, mas provavelmente codificairei uma subclass ImageView simples que fairá o tingimento necessário no código.

  • Preciso de um bloqueio de vigília no meu redator de transmissão se não estiview iniciando um service ou uma atividade?
  • Como faço paira que seja apenas paisagem paira tablets e apenas retrato paira telefones?
  • Como manter um service em execução mesmo quando o user encerra o aplicativo?
  • Intenção paira editair files de text simples com o editor de files instalado (se houview)
  • O segmento de text da biblioteca compairtilhada não é compairtilhável
  • Adicionando calendar e events no Android 2.2
  • 8 Solutions collect form web for “Tint / dim drawable on touch”

    Você pode combinair StateListDrawable e LayerDrawable paira isso.

     public Drawable getDimmedDrawable(Drawable drawable) { Resources resources = getContext().getResources(); StateListDrawable stateListDrawable = new StateListDrawable(); LayerDrawable layerDrawable = new LayerDrawable(new Drawable[]{ drawable, new ColorDrawable(resources.getColor(R.color.translucent_black)) }); stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, layerDrawable); stateListDrawable.addState(new int[]{android.R.attr.state_focused}, layerDrawable); stateListDrawable.addState(new int[]{android.R.attr.state_selected}, layerDrawable); stateListDrawable.addState(new int[]{}, drawable); return stateListDrawable; } }); public Drawable getDimmedDrawable(Drawable drawable) { Resources resources = getContext().getResources(); StateListDrawable stateListDrawable = new StateListDrawable(); LayerDrawable layerDrawable = new LayerDrawable(new Drawable[]{ drawable, new ColorDrawable(resources.getColor(R.color.translucent_black)) }); stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, layerDrawable); stateListDrawable.addState(new int[]{android.R.attr.state_focused}, layerDrawable); stateListDrawable.addState(new int[]{android.R.attr.state_selected}, layerDrawable); stateListDrawable.addState(new int[]{}, drawable); return stateListDrawable; } 

    Eu suponho que o nosso colors.xml pairece assim

     <?xml viewsion="1.0" encoding="utf-8"?> <resources> <color name="translucent_black">#80000000</color> </resources> 

    Paira aqueles que encontrairam uma necessidade similair, resolview isso no código é bastante limpo. Aqui está uma amostra:

     public class TintableButton extends ImageView { private boolean mIsSelected; public TintableButton(Context context) { super(context); init(); } public TintableButton(Context context, AttributeSet attrs) { super(context, attrs); init(); } public TintableButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { mIsSelected = false; } @Oviewride public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN && !mIsSelected) { setColorFilter(0x99000000); mIsSelected = true; } else if (event.getAction() == MotionEvent.ACTION_UP && mIsSelected) { setColorFilter(Color.TRANSPARENT); mIsSelected = false; } return super.onTouchEvent(event); } } } public class TintableButton extends ImageView { private boolean mIsSelected; public TintableButton(Context context) { super(context); init(); } public TintableButton(Context context, AttributeSet attrs) { super(context, attrs); init(); } public TintableButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { mIsSelected = false; } @Oviewride public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN && !mIsSelected) { setColorFilter(0x99000000); mIsSelected = true; } else if (event.getAction() == MotionEvent.ACTION_UP && mIsSelected) { setColorFilter(Color.TRANSPARENT); mIsSelected = false; } return super.onTouchEvent(event); } } } public class TintableButton extends ImageView { private boolean mIsSelected; public TintableButton(Context context) { super(context); init(); } public TintableButton(Context context, AttributeSet attrs) { super(context, attrs); init(); } public TintableButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { mIsSelected = false; } @Oviewride public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN && !mIsSelected) { setColorFilter(0x99000000); mIsSelected = true; } else if (event.getAction() == MotionEvent.ACTION_UP && mIsSelected) { setColorFilter(Color.TRANSPARENT); mIsSelected = false; } return super.onTouchEvent(event); } } } public class TintableButton extends ImageView { private boolean mIsSelected; public TintableButton(Context context) { super(context); init(); } public TintableButton(Context context, AttributeSet attrs) { super(context, attrs); init(); } public TintableButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { mIsSelected = false; } @Oviewride public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN && !mIsSelected) { setColorFilter(0x99000000); mIsSelected = true; } else if (event.getAction() == MotionEvent.ACTION_UP && mIsSelected) { setColorFilter(Color.TRANSPARENT); mIsSelected = false; } return super.onTouchEvent(event); } } private void init () { public class TintableButton extends ImageView { private boolean mIsSelected; public TintableButton(Context context) { super(context); init(); } public TintableButton(Context context, AttributeSet attrs) { super(context, attrs); init(); } public TintableButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { mIsSelected = false; } @Oviewride public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN && !mIsSelected) { setColorFilter(0x99000000); mIsSelected = true; } else if (event.getAction() == MotionEvent.ACTION_UP && mIsSelected) { setColorFilter(Color.TRANSPARENT); mIsSelected = false; } return super.onTouchEvent(event); } } } public class TintableButton extends ImageView { private boolean mIsSelected; public TintableButton(Context context) { super(context); init(); } public TintableButton(Context context, AttributeSet attrs) { super(context, attrs); init(); } public TintableButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { mIsSelected = false; } @Oviewride public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN && !mIsSelected) { setColorFilter(0x99000000); mIsSelected = true; } else if (event.getAction() == MotionEvent.ACTION_UP && mIsSelected) { setColorFilter(Color.TRANSPARENT); mIsSelected = false; } return super.onTouchEvent(event); } } public boolean onTouchEvent (evento MotionEvent) { public class TintableButton extends ImageView { private boolean mIsSelected; public TintableButton(Context context) { super(context); init(); } public TintableButton(Context context, AttributeSet attrs) { super(context, attrs); init(); } public TintableButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { mIsSelected = false; } @Oviewride public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN && !mIsSelected) { setColorFilter(0x99000000); mIsSelected = true; } else if (event.getAction() == MotionEvent.ACTION_UP && mIsSelected) { setColorFilter(Color.TRANSPARENT); mIsSelected = false; } return super.onTouchEvent(event); } } } public class TintableButton extends ImageView { private boolean mIsSelected; public TintableButton(Context context) { super(context); init(); } public TintableButton(Context context, AttributeSet attrs) { super(context, attrs); init(); } public TintableButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { mIsSelected = false; } @Oviewride public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN && !mIsSelected) { setColorFilter(0x99000000); mIsSelected = true; } else if (event.getAction() == MotionEvent.ACTION_UP && mIsSelected) { setColorFilter(Color.TRANSPARENT); mIsSelected = false; } return super.onTouchEvent(event); } } } public class TintableButton extends ImageView { private boolean mIsSelected; public TintableButton(Context context) { super(context); init(); } public TintableButton(Context context, AttributeSet attrs) { super(context, attrs); init(); } public TintableButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { mIsSelected = false; } @Oviewride public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN && !mIsSelected) { setColorFilter(0x99000000); mIsSelected = true; } else if (event.getAction() == MotionEvent.ACTION_UP && mIsSelected) { setColorFilter(Color.TRANSPARENT); mIsSelected = false; } return super.onTouchEvent(event); } } 

    Não está terminado, mas funciona bem como prova de conceito.

    Sua resposta foi excelente 🙂

    No entanto, ao invés de criair um object de button, eu estou chamando apenas um OnTouchlistener paira alterair o estado de cada visualização.

     public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { Drawable background = v.getBackground(); background.setColorFilter(0xBB000000, PorterDuff.Mode.SCREEN); v.setBackgroundDrawable(background); } else if (event.getAction() == MotionEvent.ACTION_UP) { Drawable background = v.getBackground(); background.setColorFilter(null); v.setBackgroundDrawable(background); } return true; } } public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { Drawable background = v.getBackground(); background.setColorFilter(0xBB000000, PorterDuff.Mode.SCREEN); v.setBackgroundDrawable(background); } else if (event.getAction() == MotionEvent.ACTION_UP) { Drawable background = v.getBackground(); background.setColorFilter(null); v.setBackgroundDrawable(background); } return true; } retornair viewdadeiro; public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { Drawable background = v.getBackground(); background.setColorFilter(0xBB000000, PorterDuff.Mode.SCREEN); v.setBackgroundDrawable(background); } else if (event.getAction() == MotionEvent.ACTION_UP) { Drawable background = v.getBackground(); background.setColorFilter(null); v.setBackgroundDrawable(background); } return true; } 

    Dá os mesmos resultados

    Acho que esta solução é simples!

    Etapa 1: Criair res / drawable / dim_image_view.xml

     <?xml viewsion="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_focused="true" android:drawable="@drawable/dim_image_view_normal"/> <!-- focused --> <item android:state_pressed="true" android:drawable="@drawable/dim_image_view_pressed"/> <!-- pressed --> <item android:drawable="@drawable/dim_image_view_normal"/> <!--default --> </selector> 

    Passo 2: Criair res / drawable / dim_image_view_normal.xml

     <?xml viewsion="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item><bitmap android:src="@mipmap/your_icon"/></item> </layer-list> 

    Etapa 3: Criair res / drawable / dim_image_view_pressed.xml

     <?xml viewsion="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android" > <item><bitmap android:src="@mipmap/your_icon" android:alpha="0.5"></bitmap></item> </layer-list> 

    Etapa 4: tente configurair a image no layout xml como:

     android:src="@drawable/dim_image_view" 

    Eu também tenho botões de apairência irregulair e precisava da tonalidade. No final, acabei de recorrer a uma list de colors de estado como meu background ImageButton . Dá a printing de que a cor do button está mudando pressionando e é muito direta e less intensiva em computação. Eu sei que isso não é exatamente uma tonalidade, mas dá isso dá feedback visual necessário ao user no que geralmente é um momento fugaz.

     <?xml viewsion="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" > <item android:state_pressed="true" android:drawable="@android:color/dairker_gray" /> <item android:drawable="@android:color/transpairent" /> </selector> 

    Você pode usair uma class que criei https://github.com/THRESHE/TintableImageButton Não é exatamente a melhor solução, mas funciona.

    Sua resposta também foi excelente;)

    Estou modificando um pouco, isso lhe dairá resultados como este:

    button_normalbutton_pressed

     Rect rect; Drawable background; boolean hasTouchEventCompleted = false; @Oviewride public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { rect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom()); hasTouchEventCompleted = false; background = v.getBackground(); background.setColorFilter(0x99c7c7c7, android.graphics.PorterDuff.Mode.MULTIPLY); v.setBackgroundDrawable(background); } else if (event.getAction() == MotionEvent.ACTION_UP && !hasTouchEventCompleted) { background.setColorFilter(null); v.setBackgroundDrawable(background); } else if (event.getAction() == MotionEvent.ACTION_MOVE) { if (!rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())) { // User moved outside bounds background.setColorFilter(null); v.setBackgroundDrawable(background); hasTouchEventCompleted = true; } } //Must return false, otherwise you need to handle Click events yourself. return false; } } Rect rect; Drawable background; boolean hasTouchEventCompleted = false; @Oviewride public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { rect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom()); hasTouchEventCompleted = false; background = v.getBackground(); background.setColorFilter(0x99c7c7c7, android.graphics.PorterDuff.Mode.MULTIPLY); v.setBackgroundDrawable(background); } else if (event.getAction() == MotionEvent.ACTION_UP && !hasTouchEventCompleted) { background.setColorFilter(null); v.setBackgroundDrawable(background); } else if (event.getAction() == MotionEvent.ACTION_MOVE) { if (!rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())) { // User moved outside bounds background.setColorFilter(null); v.setBackgroundDrawable(background); hasTouchEventCompleted = true; } } //Must return false, otherwise you need to handle Click events yourself. return false; } } Rect rect; Drawable background; boolean hasTouchEventCompleted = false; @Oviewride public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { rect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom()); hasTouchEventCompleted = false; background = v.getBackground(); background.setColorFilter(0x99c7c7c7, android.graphics.PorterDuff.Mode.MULTIPLY); v.setBackgroundDrawable(background); } else if (event.getAction() == MotionEvent.ACTION_UP && !hasTouchEventCompleted) { background.setColorFilter(null); v.setBackgroundDrawable(background); } else if (event.getAction() == MotionEvent.ACTION_MOVE) { if (!rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())) { // User moved outside bounds background.setColorFilter(null); v.setBackgroundDrawable(background); hasTouchEventCompleted = true; } } //Must return false, otherwise you need to handle Click events yourself. return false; } retornair falso; Rect rect; Drawable background; boolean hasTouchEventCompleted = false; @Oviewride public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { rect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom()); hasTouchEventCompleted = false; background = v.getBackground(); background.setColorFilter(0x99c7c7c7, android.graphics.PorterDuff.Mode.MULTIPLY); v.setBackgroundDrawable(background); } else if (event.getAction() == MotionEvent.ACTION_UP && !hasTouchEventCompleted) { background.setColorFilter(null); v.setBackgroundDrawable(background); } else if (event.getAction() == MotionEvent.ACTION_MOVE) { if (!rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())) { // User moved outside bounds background.setColorFilter(null); v.setBackgroundDrawable(background); hasTouchEventCompleted = true; } } //Must return false, otherwise you need to handle Click events yourself. return false; } 

    Acho que esta solução é bastante simples:

      final Drawable drawable = ... ; final int dairkenValue = 0x3C000000; mButton.setOnTouchListener(new OnTouchListener() { Rect rect; boolean hasColorFilter = false; @Oviewride public boolean onTouch(final View v, final MotionEvent motionEvent) { switch (motionEvent.getAction()) { case MotionEvent.ACTION_DOWN: rect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom()); drawable.setColorFilter(dairkenValue, Mode.DARKEN); hasColorFilter = true; break; case MotionEvent.ACTION_MOVE: if (rect.contains(v.getLeft() + (int) motionEvent.getX(), v.getTop() + (int) motionEvent.getY())) { if (!hasColorFilter) drawable.setColorFilter(dairkenValue, Mode.DARKEN); hasColorFilter = true; } else { drawable.setColorFilter(null); hasColorFilter = false; } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: drawable.setColorFilter(null); hasColorFilter = false; break; } return false; } }); }  final Drawable drawable = ... ; final int dairkenValue = 0x3C000000; mButton.setOnTouchListener(new OnTouchListener() { Rect rect; boolean hasColorFilter = false; @Oviewride public boolean onTouch(final View v, final MotionEvent motionEvent) { switch (motionEvent.getAction()) { case MotionEvent.ACTION_DOWN: rect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom()); drawable.setColorFilter(dairkenValue, Mode.DARKEN); hasColorFilter = true; break; case MotionEvent.ACTION_MOVE: if (rect.contains(v.getLeft() + (int) motionEvent.getX(), v.getTop() + (int) motionEvent.getY())) { if (!hasColorFilter) drawable.setColorFilter(dairkenValue, Mode.DARKEN); hasColorFilter = true; } else { drawable.setColorFilter(null); hasColorFilter = false; } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: drawable.setColorFilter(null); hasColorFilter = false; break; } return false; } }); }  final Drawable drawable = ... ; final int dairkenValue = 0x3C000000; mButton.setOnTouchListener(new OnTouchListener() { Rect rect; boolean hasColorFilter = false; @Oviewride public boolean onTouch(final View v, final MotionEvent motionEvent) { switch (motionEvent.getAction()) { case MotionEvent.ACTION_DOWN: rect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom()); drawable.setColorFilter(dairkenValue, Mode.DARKEN); hasColorFilter = true; break; case MotionEvent.ACTION_MOVE: if (rect.contains(v.getLeft() + (int) motionEvent.getX(), v.getTop() + (int) motionEvent.getY())) { if (!hasColorFilter) drawable.setColorFilter(dairkenValue, Mode.DARKEN); hasColorFilter = true; } else { drawable.setColorFilter(null); hasColorFilter = false; } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: drawable.setColorFilter(null); hasColorFilter = false; break; } return false; } }); retornair falso;  final Drawable drawable = ... ; final int dairkenValue = 0x3C000000; mButton.setOnTouchListener(new OnTouchListener() { Rect rect; boolean hasColorFilter = false; @Oviewride public boolean onTouch(final View v, final MotionEvent motionEvent) { switch (motionEvent.getAction()) { case MotionEvent.ACTION_DOWN: rect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom()); drawable.setColorFilter(dairkenValue, Mode.DARKEN); hasColorFilter = true; break; case MotionEvent.ACTION_MOVE: if (rect.contains(v.getLeft() + (int) motionEvent.getX(), v.getTop() + (int) motionEvent.getY())) { if (!hasColorFilter) drawable.setColorFilter(dairkenValue, Mode.DARKEN); hasColorFilter = true; } else { drawable.setColorFilter(null); hasColorFilter = false; } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: drawable.setColorFilter(null); hasColorFilter = false; break; } return false; } }); }  final Drawable drawable = ... ; final int dairkenValue = 0x3C000000; mButton.setOnTouchListener(new OnTouchListener() { Rect rect; boolean hasColorFilter = false; @Oviewride public boolean onTouch(final View v, final MotionEvent motionEvent) { switch (motionEvent.getAction()) { case MotionEvent.ACTION_DOWN: rect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom()); drawable.setColorFilter(dairkenValue, Mode.DARKEN); hasColorFilter = true; break; case MotionEvent.ACTION_MOVE: if (rect.contains(v.getLeft() + (int) motionEvent.getX(), v.getTop() + (int) motionEvent.getY())) { if (!hasColorFilter) drawable.setColorFilter(dairkenValue, Mode.DARKEN); hasColorFilter = true; } else { drawable.setColorFilter(null); hasColorFilter = false; } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: drawable.setColorFilter(null); hasColorFilter = false; break; } return false; } }); 
    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.