8

私はアンドロイドレイアウトデザインを持っており、そのレイアウトにはと円をもう 1 つAppBar含むレイアウトがあります。これは同じ高さから外れています。したがって、高さ/幅を取得しようとすると、0 しか返されません。ToolbarLinearLayoutDrawableTextViewToolbarAppBar

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: ここでは、Toolbarおよびを初期化しAppBar、両方の幅と高さをログに出力しようとしていますが、ゼロが返されます。

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ます。前に述べたスタックオーバーフローの質問から、ビューが画面に描画されていないことがわかったので、待つ必要があります。しかし、ここで私の疑問は、私が指定したデザインは複雑なものではないということです? 画面に描画するのに時間がかかるのはなぜですか?私は何かを逃していますか?

Hierarchy Viewer を使用して、子レイアウトの読み込みが遅くなる原因を調べました。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以下は、私が取得している階層ビューアの画像です

4

5 に答える 5

3

あなたはこれについて間違って考えています。レイアウトに問題はありません(質問に関連しているため)。それを証明するために、レイアウトを完全に変更して、もう一度やり直してください

@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つしかないビューの出力はまだです

12-14 10:17:04.902 3004-3004/? D/いくつかのタグ: w: 0、h: 0

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

したがって、レイアウトに問題はありません (ただし、誤称があります。logToolbarLayoutParams メソッドを呼び出しますが、レイアウト パラメーターにまったくアクセスしていません。レイアウト パスが発生する前に、ビュー オブジェクトのプロパティを取得しようとしています。多分これはあなたの混乱です)。つまり、Android のレイアウト システム、ビューグループ、およびビューを理解していないということです。Romain Guy は、カスタム FlowLayout を構築する方法について、Devoxx のある時点で非常にクールな話をしました。サイトがダウンしているか、ビデオが削除されていますが、GitHub のコードは次のとおりです。メソッド onLayout を見ると、ViewGroup がすべての子をループして child.layout() を呼び出していることがわかります。このメソッドが呼び出されるまで、view.getWidth および view.getHeight メソッドは 0 を返します。このメソッドは、OS がスケジュールするたびに呼び出されます。したがって、基本的には、OS がレイアウトをスケジュールする直前であっても、幅と高さにアクセスしようとしています。自分でカスタム ビューグループを作成し、いくつかのブレーク ポイントを追加して、試してみてください。

于 2016-12-14T18:29:33.960 に答える
1

toolbar.getWidth()ビューを測定して配置したのビューの幅が表示されます。 ビューを膨張させた後、その幅と高さは常にaも aも発生していないためです。
0measure()layout()

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()onMeasure() 名前が示すように、と onLayout()の両方が呼び出されているため、正しいデータが報告されます。ビューの寸法は既知です。これは、ビューが描画されたことを意味するものではありませ。3番目で最後のステップです。onDraw()

また、レイアウトの複雑さや使用しているビューに違いはありません。ビューのインフレーション直後には、測定パスとレイアウト パスは発生しません。


ビューの正しい寸法を取得して操作するには、次の 3 つのオプションがあります。

  1. ViewTreeObserver.OnGlobalLayoutListener#onGlobalLayout()あなたがすでに提案したように使用してください
  2. 後でビューが描画されたことを確認できるときにサイズを確認します (たとえば、 でのユーザーの操作時OnClickListener) 。
  3. カスタムして独自の を作成しますViewonMeasureonLayout、およびonDraw自分自身のすべてを処理する機会が得られます。
于 2016-12-14T21:37:10.477 に答える
-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このような問題を解決する最も簡単な方法です

于 2016-12-14T11:10:22.217 に答える