2012-06-14 24 views

risposta

17

A meno che qualcun altro ha una risposta migliore, il mio metodo attuale è brizzolati fuori ogni oggetto separatamente.

PorterDuffColorFilter greyFilter = new PorterDuffColorFilter(Color.GRAY, PorterDuff.Mode.MULTIPLY); 
myLayout.getBackground().setColorFilter(greyFilter); 
myImageView.setColorFilter(greyFilter); 
myTextView.setTextColor(0xff777777); 

Per i bambini più o nidificati probabilmente un ciclo con instanceof sarebbe adatto ma non ne ho bisogno.

Modifica: Questo filtro non è in realtà grigio, un filtro migliore è qui: Drawable => grayscale Che può essere utilizzato allo stesso modo.

+2

'myLayout.getBackground(). SetColorFilter (greyFilter);' Lo stavo cercando. Grandi cose. –

+0

Penso che Sam Lu ansewr sia il più preciso – Moxor

7

Dipende interamente dal metodo che si sta utilizzando per "oscurare" gli elementi. In tal caso, chiamando setEnabled(false) sul genitore ViewGroup, i flag di stato predefiniti (come disabilitato) non scorrono verso le viste secondarie. Tuttavia, esistono due modi semplici per personalizzarlo:

Un'opzione è per aggiungere l'attributoandroid:duplicateParentState="true" a ogni visualizzazione figlio nel proprio XML. Questo dirà ai bambini di ottenere le bandiere dello stato dal genitore. Ciò rispecchierà comunque TUTTI i flag, inclusi quelli premuti, spuntati, ecc ... non solo abilitati.

Un'altra opzione è quella di creare una sottoclasse personalizzato del vostro ViewGroup e sovrascrivere setEnabled() di chiamare tutti i punti di vista del bambino, così, cioè

@Override 
public void setEnabled(boolean enabled) { 
    super.setEnabled(enabled); 

    for(int i=0; i < getChildCount(); i++) { 
     getChildAt(i).setEnabled(enabled); 
    } 
} 
+0

No, no, non disattivare. Grigio fuori (colore!) – Ixx

12

E 'facile da fare che attraverso la definizione di un gruppo di visualizzazione personalizzata come segue:

public class MyViewContainer extends XXXLayout { 
    //XXLayout could be LinearLayout, RelativeLayout or others 
    private Paint m_paint; 

    //define constructors here and call _Init() at the end of constructor function 

    private void 
    _Init() 
    { 
     ColorMatrix cm = new ColorMatrix(); 
     cm.setSaturation(0); 
     m_paint = new Paint(); 
     m_paint.setColorFilter(new ColorMatrixColorFilter(cm)); 
    } 

    @Override protected void 
    dispatchDraw(Canvas canvas) 
    { 
     canvas.saveLayer(null, m_paint, Canvas.ALL_SAVE_FLAG); 
     super.dispatchDraw(canvas); 
     canvas.restore(); 
    } 
} 

Tutte le viste figli di MyViewContainer verranno mostrati in grigio. :-)

8

La risposta di Sam Lu è un buon inizio, ma ho avuto problemi di prestazioni e ho deciso di passare ai livelli hardware. Con strati di hardware, si può fare in questo modo:

private final Paint grayscalePaint = new Paint(); 

ColorMatrix cm = new ColorMatrix(); 
cm.setSaturation(0);   
grayscalePaint.setColorFilter(new ColorMatrixColorFilter(cm)); 

public void setGrayedOut(boolean grayedOut) {  
    if (grayedOut) { 
     setLayerType(View.LAYER_TYPE_HARDWARE, grayscalePaint); 
    } else { 
     setLayerType(View.LAYER_TYPE_NONE, null);  
    }  
} 

essere attenti a non fare gli strati in dispatchDraw() sé come che in crash l'applicazione.

+0

semplicemente passando a LAYER_TYPE_HARDWARE causerà "" W/OpenGLRenderer: il layer supera le dimensioni massime supportate dalla GPU (1088x4288, max = 4096x4096) "" crash su grandi viste. E '" max = 4096x4096 "' dipende dal modello del telefono –

0

Quello che mi piace fare è creare una vista che si sovrapponga alla vista che si sta tentando di colorare e impostare lo sfondo su un colore trasparente. Quindi è possibile attivare la tinta e disattivare impostando che le opinioni visibilità

<FrameLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <ViewYouWantToTint 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"/> 

    <View 
     android:id="@+id/disabled_tint_overlay" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:background="@color/darkTint" 
     android:visibility="invisible"/> 

</FrameLayout> 

Poi nel controller:

m_DisabledBlackTintOverlay = (View) view.findViewById(R.id.login_disabled_black_tint_overlay); 

m_DisabledBlackTintOverlay.setVisibility(View.VISIBLE); 
Problemi correlati