2013-01-08 12 views
7

Nella mia app ho una visualizzazione dell'ora che si aggiorna ogni secondo. Ogni volta che la TextView utilizzata per il campo dei secondi cambia, lo strumento Opzioni sviluppatore-> Mostra aggiornamenti di superficie lampeggia sull'intero schermo. Mi sono guardato intorno e posso davvero trovare solo this question che chiarisce bene che non c'è modo di impedire che TextView causi un relayout per almeno parte della finestra. Quindi ero sicuro di verificare che i miei TextView fossero avvolti nel loro contenitore, ma ho ancora lo stesso problema. Ogni chiamata a setText() fa lampeggiare l'intera vista.Chiamare TextView.setText() ridisegna l'intero schermo nonostante la gerarchia delle viste

La mia gerarchia è la seguente:

  • Frammento
    • RelativeLayout (Frammento Root View)
      • LinearLayout
        • RelativeLayout
          • My Time TextViews
      • vari altri componenti vista che cambiano raramente

vorrei risolvere questo problema, se possibile. Devo provare a ridurre il numero di visualizzazioni, se possibile, e ho intenzione di lavorarci, ma questo è ancora un problema che vorrei rimuovere dall'app.

risposta

10

Mostra gli aggiornamenti di superficie lampeggia l'intero schermo quando l'accelerazione hardware è attiva ma non significa che l'intera finestra è stata ridisegnata. C'è un'altra opzione che puoi usare che ti mostra esattamente quale parte dello schermo è stata ridisegnata quando è attiva l'accelerazione hardware ("Mostra aggiornamenti della vista della GPU").

+0

Ok, questo ha molto più senso, grazie. Ora ho solo bisogno di ridurre il numero di visualizzazioni. – Jared

1

Ho riscontrato un problema simile in cui stavo aggiornando un timer che ha causato il passaggio di una misura ogni volta. Se si dispone di qualcosa che è costoso da misurare, come un ListView, influisce sulle prestazioni. Nel mio caso, avevo un ListView che non aveva bisogno di modificare le dimensioni quando il timer è stato aggiornato, quindi ho creato un supporto ListView personalizzato per interrompere il passaggio della misura dal ListView. Ora funziona senza intoppi!

public class CustomListviewHolderLayout extends FrameLayout { 

    public int currentWidth = 0; 
    public int currentHeight = 0; 

    public CustomListviewHolderLayout(Context context) { 
     super(context); 
    } 

    public CustomListviewHolderLayout(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public CustomListviewHolderLayout(Context context, AttributeSet attrs, 
      int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    @Override 
    protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) { 
     //Debug Prints 
     String wMode = ""; 
     switch(MeasureSpec.getMode(widthMeasureSpec)){ 
      case MeasureSpec.AT_MOST: 
       wMode = "AT_MOST"; break; 
      case MeasureSpec.EXACTLY: 
       wMode = "EXACTLY"; break; 
      case MeasureSpec.UNSPECIFIED: 
       wMode = "UNSPECIFIED"; break; 
      default: 
       wMode = ""; 
     } 
     String hMode = ""; 
     switch(MeasureSpec.getMode(heightMeasureSpec)){ 
      case MeasureSpec.AT_MOST: 
       hMode = "AT_MOST"; break; 
      case MeasureSpec.EXACTLY: 
       hMode = "EXACTLY"; break; 
      case MeasureSpec.UNSPECIFIED: 
       hMode = "UNSPECIFIED"; break; 
      default: 
       hMode = ""; 
     } 
     Log.i("RandomCustomListViewHolder", "wMode = " + wMode + ", size = " + MeasureSpec.getSize(widthMeasureSpec)); 
     Log.i("RandomCustomListViewHolder", "hMode = " + hMode + ", size = " + MeasureSpec.getSize(heightMeasureSpec)); 
     //only remeasure child listview when the size changes (e.g. orientation change) 
     if(getChildCount() == 1){ 
      if(((MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) || 
       (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.AT_MOST)) 
       &&((MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY) || 
       (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST))){ 
       //check if height dimensions are different than before 
       int newWidth = MeasureSpec.getSize(widthMeasureSpec); 
       int newHeight = MeasureSpec.getSize(heightMeasureSpec); 
       if((newWidth != currentWidth) || (newHeight != currentHeight)){ 
        //remeasure if different 
        Log.i("RandomCustomListViewHolder", "measuring listView"); 
        View childView = getChildAt(0); 
        childView.measure(widthMeasureSpec, heightMeasureSpec); 
        currentWidth = newWidth; 
        currentHeight = newHeight; 
        this.setMeasuredDimension(newWidth, newHeight); 
       } else { 
        //still set this view's measured dimension 
        this.setMeasuredDimension(newWidth, newHeight);  
       }    
      } else { 
       //Specify match parent if one of the dimensions is unspecified 
       this.setMeasuredDimension(ViewGroup.LayoutParams.MATCH_PARENT, 
         ViewGroup.LayoutParams.MATCH_PARENT);     
      } 
     } else { 
      //view does not have the listview child, measure normally 
      super.onMeasure(widthMeasureSpec, heightMeasureSpec);   
      currentWidth = 0; 
      currentHeight = 0; 
     } 
    } 
} 
Problemi correlati