我有Android布局设计,其中我有AppBar
布局,其中包含Toolbar
和另外一个LinearLayout
设计,圈Drawable
为TextView
。这是相同的高度。因此,当我尝试获得Toolbar
或AppBar
高度/宽度时,它仅返回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:
在这里,我正在初始化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
的正确高度和宽度。从我之前提到的stackoverflow问题中,我开始知道,视图没有在屏幕上绘制,所以我必须等待。但我怀疑的是,我指定的设计并不复杂?
为什么它花了很多时间在屏幕上画画?我错过了什么吗?
我已经使用层次结构查看器找出了什么使得子布局加载缓慢。我发现我正在使用mulitple 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>
答案 0 :(得分: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 / SomeTag:w:0,h:0
12-14 10:17:04.902 3004-3004 /? D / SomeTag:mw:0,mh:0
所以你的布局没有任何问题(除了你有一个用词不当。你调用方法logToolbarLayoutParams,但你根本没有访问布局参数。你试图在布局之前获取视图对象的属性传球已经发生。也许这是你的混乱)。所以你缺少的是对Android的布局系统,视图组和视图的理解。 Romain Guy在Devoxx上有一个关于如何构建自定义FlowLayout的非常酷的演讲。网站已关闭或视频被拉动但是here's the code in GitHub如果您查看onLayout方法,您可以看到ViewGroup遍历其所有子节点并调用child.layout()。在调用此方法之前,view.getWidth和view.getHeight方法将返回0.此操作系统在调度时调用此方法。所以基本上,即使在OS安排布局之前,您也试图立即访问宽度和高度。自己创建一个自定义视图组,添加一些断点,并试一试。
答案 1 :(得分:1)
toolbar.getWidth()
会在测量和布局之后告诉您视图的宽度。
在给视图充气后,其宽度和高度始终为0
,因为measure()
和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()
都已被调用。视图的尺寸是已知的。这不意味着视图已被绘制。 onDraw()
是第三步,最后步骤。
您的布局有多复杂或使用哪种视图也没有任何区别。在观点膨胀之后,测量和布局通过不会立即发生。
要获得并使用视图的正确尺寸,您有3个选项:
ViewTreeObserver.OnGlobalLayoutListener#onGlobalLayout()
OnClickListener
中)View
。在那里,您有机会自己处理所有onMeasure
,onLayout
和onDraw
!答案 2 :(得分:0)
绘图视图需要相当长的时间,但我们可以通过删除嵌套布局来减少,并通过使用RelativeLayout或Constrain布局使视图层次结构变平。
找到透支。选择&#34;显示透支区域&#34;在Debug GPU中从设置中重写了开发人员选项。
答案 3 :(得分:-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()
将在 结束于视图的消息队列 中添加您的代码,此时所有尺寸都已计算完毕。 imho,那显然也是可以理解的,然后是OnGlobalLayoutListener()
。
希望它会对你有所帮助。
无论如何,这个解决方案仅仅是'#34;延迟获取大小&#34;,就像OnGlobalLayoutListener()
一样。但这是系统的正常行为,在屏幕上绘制视图需要一些时间。最好的方法是不要期望计算的维度 - 而是应该协调.xml文件中的视图之间的所有关系。像WRAP_CONTENT
和MATCH_PARENT
这样的属性是解决此类问题的最简单方法
答案 4 :(得分:-2)
您尝试在视图连接到屏幕之前获取视图的宽度和高度 您可以在onAttach方法
中创建自定义视图和所需的视图