2016-12-06 70 views
7

我有,我有一個AppBar佈局,將包含一個Toolbar和一個更LinearLayout設計圈DrawableTextView Android的佈局設計。這是相同的高度。所以,當我試圖讓ToolbarAppBar高度/寬度它返回僅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: 我在這裏初始化ToolbarAppBar並嘗試在日誌中打印兩者的寬度和高度,這會使我返回零。

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()); 

} 

我也提到在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(); 
      } 
     }); 

如果我加入我的MainActivity它讓我的Toolbar適當的高度和寬度下面的代碼。從我之前提到的stackoverflow問題,我開始知道,這些視圖並沒有畫在屏幕上,所以我必須等待。但我的疑問是,我指定的設計不是一個複雜的設計? 爲什麼它花費大量時間在屏幕上繪圖?我錯過了什麼嗎?

我已經使用層次結構查看器找出,什麼是使孩子佈局加載緩慢。我發現我正在使用多個LinearLayout,其中可以使用單個RelativeLayout來獲得相同的結構。我改變了我的佈局設計,如下所示。 我仍然面臨同樣的問題。

更新: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> 

以下是層次觀衆Hierarchy_viewer圖片我獲得

+1

使用層次結構查看器來測試佈局的性能問題。 https://developer.android.com/studio/profile/optimize-ui.html –

+0

發佈您的更新層次結構查看器和您的Java代碼。因爲它可能不是你的等級問題。 – Noorul

+0

如果你只是問爲什麼你需要使用'OnGlobalLayoutListener',那是因爲'View's不會被佈置或繪製在'onCreate()'中。就是這樣。這與您的特定佈局無關,或者它有多複雜。 –

回答

3

你在想這個錯誤this重要文章。你的佈局沒有問題(因爲它涉及到你的問題)。爲了證明這一點,徹底改變你的佈局,然後再試一次

@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()); 
} 

一個視圖中的輸出只有1名兒童仍然是

10月12日至14日: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

因此,有什麼不對您的佈局(除非你做你調用方法logToolbarLayoutParams有用詞不當,但你沒有訪問佈局PARAMS可言。 。你正試圖在佈局傳遞發生之前在視圖對象上獲取屬性,也許這就是你的困惑)。所以你缺少的是對Android的佈局系統,視圖組和視圖的理解。關於如何構建自定義FlowLayout,Romain Guy在Devoxx的某個時刻進行了一次非常酷的演講。無論是網站關閉還是視頻被拉出,但是here's the code in GitHub如果您查看onLayout方法,您可以看到ViewGroup遍歷其所有子節點並調用child.layout()。在調用此方法之前,view.getWidth和view.getHeight方法將返回0.此方法在操作系統調度時調用。所以基本上,即使在操作系統計劃佈局之前,您也正試圖立即訪問寬度和高度。自己製作一個自定義視圖組,添加一些中斷點,並給它一個鏡頭。

+0

中使用層次結構查看器搜索一些有用的信息,感謝解釋。 – HourGlass

-2

您嘗試其安裝到屏幕 之前得到寬度和高度的觀點你可以在onAttach方法中創建一個自定義視圖和wath需要

+0

是啊艾德我知道這一點。我想明白爲什麼花費很多時間。這就是爲什麼我在ADB – HourGlass

-1

我剛剛在同一個案中解決了同樣的問題。所有與ViewTreeObserver.OnGlobalLayoutListener()解決方案看起來很髒,不適合我。最簡單的辦法知道的寬度和高度,在當前的屏幕看起來是這樣的:

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

view.post()將在年底在視圖的消息隊列,添加你的代碼在所有尺寸都已經計算。恕我直言,這顯然更容易理解,然後OnGlobalLayoutListener()。 希望它能幫助你。

無論如何,這個解決方案只是「延遲獲取尺寸」,如OnGlobalLayoutListener()。但這是系統的正常行爲,需要一些時間才能在屏幕上繪製視圖。最好的方法是不要期待計算的維度 - 而是應該協調.xml文件中視圖之間的所有關係。像WRAP_CONTENTMATCH_PARENT屬性,是解決類似的原因最簡單的方法這個

-1

工程視圖需要相當長的時間,但我們可以通過刪除嵌套佈局減少,使視圖層級扁平無論是使用的RelativeLayout或約束佈局。

找到透支。在調試GPU中選擇「顯示透視區域」從設置中重畫開發者選項。

研究this和developer.android優化佈局話題

1

toolbar.getWidth()會告訴你的看法的寬度後,它一直測量奠定了
充氣後,其寬度和高度始終爲0,因爲measure()layout()均未發生。

​​

onGlobalLayout()報告正確的數據,因爲—顧名思義—兩者onMeasure()onLayout()已被調用。視圖的尺寸是已知的。這樣做不是意味着視圖已被繪製onDraw()是第三個和最後一步。

它也不會影響您的佈局有多複雜或您使用的是哪種視圖。測量和佈局過程不會在視圖膨脹後立即發生。


要獲得和你的觀點的正確尺寸的工作,你有3種選擇:

  1. 使用ViewTreeObserver.OnGlobalLayoutListener#onGlobalLayout()像你已經建議
  2. 檢查大小到以後的時間,當你可以確保視圖已被繪製(例如,在用戶交互中,在OnClickListener中)
  3. 定製並創建您自己的View。你有機會親自處理所有的onMeasure,onLayoutonDraw