Android OnGlobalLayoutListener,这里发生了什么
Android OnGlobalLayoutListener, What Is Happening Here
背景:
我一直在为我的工作进行概念验证。要求是当应用程序首次启动时,会打开一个欢迎屏幕,向用户介绍该应用程序和新功能。那里一切都很好,花花公子。欢迎屏幕是一个长的可滚动列表,其中包含突出显示新功能的部分。当这个可滚动列表第一次打开时,屏幕中间有 2 个文本部分,屏幕底部有一个文本,让用户知道向下滚动以获取更多内容。在那之后,每个部分基本上应该只是包装它的内容。我找到了一种让它工作的方法,但我很难弄清楚它的工作原理和原因。这是有效的代码。
布局:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
tools:context=".MainActivity" >
<LinearLayout
android:id="@+id/linlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- first section -->
<LinearLayout
android:id="@+id/f1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:text="top text"
android:layout_gravity="center_horizontal"
android:gravity="bottom"
android:paddingTop="35dp"
android:textColor="@android:color/holo_red_dark"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:text="middle text"
android:layout_gravity="center_horizontal"
android:textColor="@android:color/holo_red_dark"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:text="bottom text"
android:layout_gravity="center_horizontal"
android:gravity="bottom"
android:textColor="@android:color/holo_red_dark"/>
</LinearLayout>
<!-- second section -->
<ImageView
android:id="@+id/f2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ff8222"/>
<!-- third section -->
<ImageView
android:id="@+id/f3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/darker_gray"/>
</LinearLayout>
Java:
final LinearLayout layout = (LinearLayout)findViewById(R.id.linlayout);
final LinearLayout f1=(LinearLayout) findViewById(R.id.f1);
final ImageView f2=(ImageView) findViewById(R.id.f2);
final ImageView f3=(ImageView) findViewById(R.id.f3);
ViewTreeObserver vto = layout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
layout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
int width = layout.getMeasuredWidth();
int height = layout.getMeasuredHeight();
f1.setLayoutParams(new LinearLayout.LayoutParams(width, height));
f2.setLayoutParams(new LinearLayout.LayoutParams(width, height));
f3.setLayoutParams(new LinearLayout.LayoutParams(width, height));
}
});
问题:
通过代码,我看到它正在将每个 "section" 的宽度和高度设置为外部线性布局的宽度和高度。因为那是 match_parent 每个部分的大小与屏幕大致相同。到目前为止是有道理的。现在,长的可滚动列表中有 3 个部分与屏幕的宽度和高度相匹配。要求说只有第一部分应该匹配屏幕的宽度和高度。因此,由于第一个部分的高度是 match_parent,而其他 2 个部分的高度是 wrap_content。我想删除这两行 Java 代码
f2.setLayoutParams(new LinearLayout.LayoutParams(width, height));
f3.setLayoutParams(new LinearLayout.LayoutParams(width, height));
应使以下 2 部分包含其内容。但它实际上导致第一部分像它应该的那样全屏显示但是滚动被禁用所以我无法向下滚动以查看其他部分。谁能解释这里发生了什么?如果有更好的方法来实现我在这里尝试做的事情,我很想听听。
我实际上能够使用以下代码使其正常工作。事实证明,ImageView 被设置为包装其内容是一个问题,但由于没有图像只有颜色,所以它一定不知道包装在哪里。但是这段代码对我有用。
布局
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
tools:context=".MainActivity" >
<LinearLayout
android:id="@+id/linlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/f1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:text="top text"
android:layout_gravity="center_horizontal"
android:gravity="bottom"
android:paddingTop="35dp"
android:textColor="@android:color/holo_red_dark"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:text="middle text"
android:layout_gravity="center_horizontal"
android:textColor="@android:color/holo_red_dark"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:text="bottom text"
android:layout_gravity="center_horizontal"
android:gravity="bottom"
android:textColor="@android:color/holo_red_dark"/>
</LinearLayout>
<LinearLayout
android:id="@+id/f2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/holo_red_dark"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="middle text"
android:layout_gravity="center_horizontal"
android:textColor="@android:color/holo_red_dark"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="bottom text"
android:layout_gravity="center_horizontal"
android:gravity="bottom"
android:textColor="@android:color/holo_red_dark"/>
</LinearLayout>
<LinearLayout
android:id="@+id/f3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/holo_red_dark"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="middle text"
android:layout_gravity="center_horizontal"
android:textColor="@android:color/holo_red_dark"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="bottom text"
android:layout_gravity="center_horizontal"
android:gravity="bottom"
android:textColor="@android:color/holo_red_dark"/>
</LinearLayout>
</LinearLayout>
Java
final LinearLayout layout = (LinearLayout)findViewById(R.id.linlayout);
final LinearLayout f1=(LinearLayout) findViewById(R.id.f1);
ViewTreeObserver vto = layout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
{
@Override
public void onGlobalLayout()
{
layout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
int width = layout.getMeasuredWidth();
int height = layout.getMeasuredHeight();
f1.setLayoutParams(new LinearLayout.LayoutParams(width, height));
}
});
背景:
我一直在为我的工作进行概念验证。要求是当应用程序首次启动时,会打开一个欢迎屏幕,向用户介绍该应用程序和新功能。那里一切都很好,花花公子。欢迎屏幕是一个长的可滚动列表,其中包含突出显示新功能的部分。当这个可滚动列表第一次打开时,屏幕中间有 2 个文本部分,屏幕底部有一个文本,让用户知道向下滚动以获取更多内容。在那之后,每个部分基本上应该只是包装它的内容。我找到了一种让它工作的方法,但我很难弄清楚它的工作原理和原因。这是有效的代码。
布局:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
tools:context=".MainActivity" >
<LinearLayout
android:id="@+id/linlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- first section -->
<LinearLayout
android:id="@+id/f1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:text="top text"
android:layout_gravity="center_horizontal"
android:gravity="bottom"
android:paddingTop="35dp"
android:textColor="@android:color/holo_red_dark"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:text="middle text"
android:layout_gravity="center_horizontal"
android:textColor="@android:color/holo_red_dark"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:text="bottom text"
android:layout_gravity="center_horizontal"
android:gravity="bottom"
android:textColor="@android:color/holo_red_dark"/>
</LinearLayout>
<!-- second section -->
<ImageView
android:id="@+id/f2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ff8222"/>
<!-- third section -->
<ImageView
android:id="@+id/f3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/darker_gray"/>
</LinearLayout>
Java:
final LinearLayout layout = (LinearLayout)findViewById(R.id.linlayout);
final LinearLayout f1=(LinearLayout) findViewById(R.id.f1);
final ImageView f2=(ImageView) findViewById(R.id.f2);
final ImageView f3=(ImageView) findViewById(R.id.f3);
ViewTreeObserver vto = layout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
layout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
int width = layout.getMeasuredWidth();
int height = layout.getMeasuredHeight();
f1.setLayoutParams(new LinearLayout.LayoutParams(width, height));
f2.setLayoutParams(new LinearLayout.LayoutParams(width, height));
f3.setLayoutParams(new LinearLayout.LayoutParams(width, height));
}
});
问题:
通过代码,我看到它正在将每个 "section" 的宽度和高度设置为外部线性布局的宽度和高度。因为那是 match_parent 每个部分的大小与屏幕大致相同。到目前为止是有道理的。现在,长的可滚动列表中有 3 个部分与屏幕的宽度和高度相匹配。要求说只有第一部分应该匹配屏幕的宽度和高度。因此,由于第一个部分的高度是 match_parent,而其他 2 个部分的高度是 wrap_content。我想删除这两行 Java 代码
f2.setLayoutParams(new LinearLayout.LayoutParams(width, height));
f3.setLayoutParams(new LinearLayout.LayoutParams(width, height));
应使以下 2 部分包含其内容。但它实际上导致第一部分像它应该的那样全屏显示但是滚动被禁用所以我无法向下滚动以查看其他部分。谁能解释这里发生了什么?如果有更好的方法来实现我在这里尝试做的事情,我很想听听。
我实际上能够使用以下代码使其正常工作。事实证明,ImageView 被设置为包装其内容是一个问题,但由于没有图像只有颜色,所以它一定不知道包装在哪里。但是这段代码对我有用。
布局
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
tools:context=".MainActivity" >
<LinearLayout
android:id="@+id/linlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/f1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:text="top text"
android:layout_gravity="center_horizontal"
android:gravity="bottom"
android:paddingTop="35dp"
android:textColor="@android:color/holo_red_dark"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:text="middle text"
android:layout_gravity="center_horizontal"
android:textColor="@android:color/holo_red_dark"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:text="bottom text"
android:layout_gravity="center_horizontal"
android:gravity="bottom"
android:textColor="@android:color/holo_red_dark"/>
</LinearLayout>
<LinearLayout
android:id="@+id/f2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/holo_red_dark"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="middle text"
android:layout_gravity="center_horizontal"
android:textColor="@android:color/holo_red_dark"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="bottom text"
android:layout_gravity="center_horizontal"
android:gravity="bottom"
android:textColor="@android:color/holo_red_dark"/>
</LinearLayout>
<LinearLayout
android:id="@+id/f3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/holo_red_dark"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="middle text"
android:layout_gravity="center_horizontal"
android:textColor="@android:color/holo_red_dark"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="bottom text"
android:layout_gravity="center_horizontal"
android:gravity="bottom"
android:textColor="@android:color/holo_red_dark"/>
</LinearLayout>
</LinearLayout>
Java
final LinearLayout layout = (LinearLayout)findViewById(R.id.linlayout);
final LinearLayout f1=(LinearLayout) findViewById(R.id.f1);
ViewTreeObserver vto = layout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
{
@Override
public void onGlobalLayout()
{
layout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
int width = layout.getMeasuredWidth();
int height = layout.getMeasuredHeight();
f1.setLayoutParams(new LinearLayout.LayoutParams(width, height));
}
});