Vue sur les enfants Prendre trop de temps pour dessiner à l'écran

J'ai une conception de mise en page Android dans laquelle j'ai une disposition AppBar qui contiendra une Toolbar et une autre conception LinearLayout avec un cercle Drawable comme TextView . Qui est à la même hauteur. Donc, lorsque j'essaie d'obtenir la Toolbar ou la hauteur / largeur d' AppBar elle ne retourne que 0.

Activity_main.xml:

  <android.support.design.widget.AppBarLayout android:id="@+id/app_bar" android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?actionBarSize" android:background="@color/colorPrimary" app:layout_scrollFlags="enterAlways" /> <LinearLayout android:layout_width="match_parent" android:layout_height="?actionBarSize" android:layout_gravity="center_horizontal" android:background="@color/colorPrimary" android:orientation="horizontal" app:layout_scrollFlags="enterAlways"> <LinearLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_gravity="center_horizontal" android:layout_marginLeft="2dp" android:layout_weight="1" android:orientation="horizontal"> <TextView android:id="@+id/marked_questions" style="@style/textview_summary_omr_toolbar_count" android:background="@drawable/bg_percentage_default" android:text="18" /> <TextView style="@style/textview_heading_summary_omr_toolbar" android:text="Marked" /> </LinearLayout> <LinearLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_gravity="center_horizontal" android:layout_marginLeft="2dp" android:layout_weight="1" android:orientation="horizontal"> <TextView android:id="@+id/correct" style="@style/textview_summary_omr_toolbar_count" android:background="@drawable/bg_percentage_6" android:text="18" /> <TextView style="@style/textview_heading_summary_omr_toolbar" android:text="Correct" /> </LinearLayout> <LinearLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_gravity="center_horizontal" android:layout_marginLeft="2dp" android:layout_weight="1" android:orientation="horizontal"> <TextView android:id="@+id/wrong" style="@style/textview_summary_omr_toolbar_count" android:background="@drawable/bg_percentage_wrong" android:text="18" /> <TextView style="@style/textview_heading_summary_omr_toolbar" android:text="Wrong" /> </LinearLayout> <LinearLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_gravity="center_horizontal" android:layout_marginLeft="2dp" android:layout_weight="1" android:orientation="horizontal"> <TextView android:id="@+id/conflicts" style="@style/textview_summary_omr_toolbar_count" android:background="@drawable/bg_percentage_3" android:text="0" /> <TextView style="@style/textview_heading_summary_omr_toolbar" android:text="Conflicts" /> </LinearLayout> <LinearLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_gravity="center_horizontal" android:layout_marginLeft="2dp" android:layout_weight="1" android:orientation="horizontal"> <TextView style="@style/textview_summary_omr_toolbar_count" android:text="Score:" android:textColor="@android:color/white" /> <TextView android:id="@+id/marks_scored" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:gravity="center" android:text="18/30" android:textColor="@android:color/white" android:textSize="18sp" /> </LinearLayout> </LinearLayout> </android.support.design.widget.AppBarLayout> </android.support.design.widget.CoordinatorLayout> 

MainActivity.java: Ici, j'initialise la Toolbar et AppBar et j'essaie d'imprimer la largeur et la hauteur des deux dans les journaux, ce qui me renvoie zéro.

 public class MainActivity extends AppCompatActivity { private Toolbar toolbar; private AppBarLayout app_bar; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); app_bar = (AppBarLayout) findViewById(R.id.app_bar); toolbar = (Toolbar) findViewById(R.id.toolbar); logToolbarLayoutParams(); } private void logToolbarLayoutParams() { Log.d(TAG,"Toolbar width/Height"+this.toolbar.getWidth()+"/"+this.toolbar.getHeight()); Log.d(TAG,"App_bar width/height"+this.app_bar.getWidth()+"/"+this.app_bar.getHeight()); } 

J'ai également mentionné cette question dans le stackoverflow .

 final AppBarLayout app_bar = (AppBarLayout) findViewById(R.id.app_bar); ViewTreeObserver vto = app_bar.getViewTreeObserver(); vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { app_bar.getViewTreeObserver().removeGlobalOnLayoutListener(this); Log.d(TAG, "Global layout"); logToolbarLayoutParams(); } }); 

Si j'ajoute le code suivant dans ma MainActivity il m'obtient la hauteur et la largeur appropriées de la Toolbar d' Toolbar . À partir de la question de stackoverflow que j'ai mentionnée précédemment, je l'ai constaté, les vues n'ont pas été dessinées sur l'écran, alors je dois attendre. Mais je doute ici, la conception que j'ai spécifiée n'est-elle pas complexe? Pourquoi prend-il beaucoup de temps à dessiner à l'écran? Est-ce que je manque quelque chose?

J'ai utilisé Hierarchy Viewer pour savoir, ce qui rend la disposition des enfants à charger lentement. J'ai constaté que j'utilise Mulitple LinearLayout où Single RelativeLayout peut être utilisé pour obtenir la même structure. J'ai modifié ma conception de mise en page comme suit. Pourtant, je suis confronté au même problème.

Mis à jour: activity_main.xml:

 <android.support.design.widget.CoordinatorLayout android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.design.widget.AppBarLayout android:id="@+id/app_bar" android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?actionBarSize" android:background="@color/colorPrimary" app:layout_scrollFlags="enterAlways" /> <RelativeLayout android:id="@+id/summary_bottom_sheet" android:layout_width="match_parent" android:layout_height="?actionBarSize" android:layout_gravity="center_horizontal" android:background="@color/colorPrimary"> <TextView android:id="@+id/marked_questions" style="@style/textview_summary_omr_toolbar_count" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:background="@drawable/bg_percentage_default" android:text="18" /> <TextView android:id="@+id/marked_textview" style="@style/textview_heading_summary_omr_toolbar" android:layout_toEndOf="@+id/marked_questions" android:layout_toRightOf="@+id/marked_questions" android:text="Marked" /> <TextView android:id="@+id/correct" style="@style/textview_summary_omr_toolbar_count" android:layout_toEndOf="@+id/marked_textview" android:layout_toRightOf="@+id/marked_textview" android:background="@drawable/bg_percentage_6" android:text="18" /> <TextView android:id="@+id/correct_textview" style="@style/textview_heading_summary_omr_toolbar" android:layout_toEndOf="@+id/correct" android:layout_toRightOf="@+id/correct" android:text="Correct" /> <TextView android:id="@+id/wrong" style="@style/textview_summary_omr_toolbar_count" android:layout_toEndOf="@+id/correct_textview" android:layout_toRightOf="@+id/correct_textview" android:background="@drawable/bg_percentage_wrong" android:text="18" /> <TextView android:id="@+id/wrong_textview" style="@style/textview_heading_summary_omr_toolbar" android:layout_toEndOf="@+id/wrong" android:layout_toRightOf="@+id/wrong" android:text="Wrong" /> <TextView android:id="@+id/conflicts" style="@style/textview_summary_omr_toolbar_count" android:layout_toEndOf="@+id/wrong_textview" android:layout_toRightOf="@+id/wrong_textview" android:background="@drawable/bg_percentage_3" android:text="0" /> <TextView android:id="@+id/conflicts_textview" style="@style/textview_heading_summary_omr_toolbar" android:layout_toEndOf="@+id/conflicts" android:layout_toRightOf="@+id/conflicts" android:text="Conflicts" /> <TextView android:id="@+id/score_textview" style="@style/textview_summary_omr_toolbar_count" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toEndOf="@+id/conflicts_textview" android:layout_toRightOf="@+id/conflicts_textview" android:background="@null" android:gravity="center" android:text="Score:" android:textColor="@android:color/white" /> <TextView android:id="@+id/marks_scored" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_gravity="center_vertical" android:layout_toEndOf="@+id/score_textview" android:layout_toRightOf="@+id/score_textview" android:gravity="center" android:text="18/30" android:textColor="@android:color/white" android:textSize="18sp" /> </RelativeLayout> </android.support.design.widget.AppBarLayout> </android.support.design.widget.CoordinatorLayout> 

Voici la visionneuse hiérarchique Hierarchy_viewer Image que j'obtiens

  • Dernier mot affiché dans une vision de texte
  • Android, capturez l'URL de redirection de Webview
  • Comment gérer les pages Web "infinies"?
  • Modification des cadres vidéoView Android
  • Comment augmenter l'espacement entre les paragraphes dans une vue de texte
  • Android WebView ne s'arrête pas après l'utilisateur appuie en arrière
  • Charger un SWF dans un WebView
  • Comment puis-je créer une vue de texte qui modifie automatiquement sa taille de police pour s'adapter à l'espace?
  • 5 Solutions collect form web for “Vue sur les enfants Prendre trop de temps pour dessiner à l'écran”

    Vous songez à ce problème. Il n'y a rien de mal avec votre mise en page (en ce qui concerne votre question). Pour le prouver, modifiez complètement votre mise en page et réessayez

     @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recyclerView); Log.d("SomeTag", "w: " + recyclerView.getWidth() + ", h: " + recyclerView.getHeight()); Log.d("SomeTag", "mw: " + recyclerView.getMeasuredWidth() + ", mh: " + recyclerView.getMeasuredHeight()); } 

    La sortie pour une vue avec seulement 1 enfant est encore

    12-14 10: 17: 04.902 3004-3004 /? D / SomeTag: w: 0, h: 0

    12-14 10: 17: 04.902 3004-3004 /? D / SomeTag: mw: 0, mh: 0

    Donc, il n'y a rien de mal avec votre mise en page (sauf que vous avez un nom incorrect. Vous appelez la méthode logToolbarLayoutParams, mais vous n'accédez pas les paramètres de mise en page. Vous essayez d'obtenir des propriétés sur l'objet de vue avant que le passage de mise en page ne se soit produit . Peut-être que c'est votre confusion). Donc, ce que vous manquez, c'est une compréhension du système de mise en page, des groupes de vues et des vues d'Android. Romain Guy a eu une conversation vraiment cool à un point sur Devoxx sur la façon de créer un FlowLayout personnalisé. Soit le site est en panne ou la vidéo est tirée, mais voici le code dans GitHub Si vous regardez la méthode onLayout, vous pouvez voir qu'un ViewGroup effectue un suivi de tous ses enfants et appelle child.layout (). Jusqu'à ce que cette méthode soit appelée, les méthodes view.getWidth et view.getHeight renverront 0. Et cette méthode est appelée par le système d'exploitation quand il l'agende. Donc, fondamentalement, vous essayez d'accéder à la largeur et à la hauteur immédiatement avant même que le système d'exploitation ne planifie une mise en page. Créez un groupe de visualisation personnalisé vous-même, ajoutez des points de rupture, et donnez-lui un coup de feu.

    toolbar.getWidth() vous indiquera la largeur de la vue après avoir été mesurée et définie .
    Après avoir gonflé la vue, sa largeur et sa hauteur seront toujours 0 car ni une measure() ni une layout() n'ont eu lieu.

     protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); toolbar = (Toolbar) findViewById(R.id.toolbar); // check after inflation -> will be 0 logToolbarLayoutParams(); } 

    onGlobalLayout() rapporte les données correctes, car, comme le nom l'indique, les deux, onMeasure() et onLayout() ont été appelés. Les dimensions de la vue sont connues. Cela ne signifie pas que la vue a été dessinée . onDraw() est la troisième et dernière étape.

    Cela ne modifie pas non plus la complexité de votre mise en page ou les vues que vous utilisez. Les passes de mesure et de mise en page ne se produisent pas immédiatement après l'inflation de la vue.


    Pour obtenir et travailler avec les dimensions correctes de votre vue, vous avez 3 options:

    1. Utilisez ViewTreeObserver.OnGlobalLayoutListener#onGlobalLayout() comme vous l'avez déjà suggéré
    2. Vérifiez la taille plus tard, lorsque vous pouvez vous assurer que la vue a été dessinée (p. OnClickListener . OnClickListener l'interaction de l'utilisateur, dans un OnClickListener )
    3. Allez personnalisé et créez votre propre View . Là vous avez l'opportunité de gérer tous les onMeasure , onLayout , et onDraw vous-même!

    Les vues de dessin prennent un temps considérable, mais nous pouvons réduire en supprimant la mise en page imbriquée et rendre la hiérarchie de vue plane soit en utilisant RelativeLayout ou Constrain layout.

    Pour trouver un retrait excessif. Sélectionnez "Afficher les zones de retrait" dans Debug GPU surcharger les options de développeur à partir des paramètres.

    Étudiez ceci et cet article important de developer.android sur l'optimisation du thème des mises en page

    Je viens de résoudre le même problème dans le même cas. Toutes les solutions avec ViewTreeObserver.OnGlobalLayoutListener() sont sales et ne fonctionnent pas pour moi. La façon la plus simple de connaître la largeur et la hauteur à l'écran actuel ressemble à ceci:

     toolbar.post(new Runnable() { @Override public void run() { int headerWidth = toolbar.getWidth(); int headerHeight = toolbar.getHeight(); // do whatever you want ... } }); 

    view.post() ajoutera votre code à la fin à la file de message de l'affichage , lorsque toutes les tailles seront déjà calculées. Imho, c'est évidemment et plus compréhensible, puis OnGlobalLayoutListener() . J'espère que cela vous aidera.

    Quoi qu'il en soit, cette solution est simplement «retardée pour obtenir des tailles», comme OnGlobalLayoutListener() . Mais c'est un comportement normal du système, il faut du temps pour dessiner des vues sur l'écran. La meilleure façon de ne pas s'attendre à des dimensions calculées – au lieu de cela, vous devez coordonner toutes les relations entre les vues dans les fichiers .xml. Les attributs comme WRAP_CONTENT et MATCH_PARENT sont les moyens les plus faciles de résoudre des problèmes comme celui-ci

    Vous essayez d'obtenir la largeur et la hauteur d'une vue avant d'être attaché à l'écran, vous pouvez créer une vue personnalisée et dont vous avez besoin dans la méthode onAttach

    coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.