编辑:愚蠢的用户错误,我的 XML 格式错误。
--
我有一个包含三个片段的活动。在一个片段的 onResume() 中,我试图使用活动从另一个片段中获取视图。findViewById(),但该方法为来自一个特定片段的任何视图返回 null 。其他两个片段中的任何一个中的视图都很好。
如果我使用getRootView()和以下快速破解的代码转储整个视图树,我会看到有问题的视图确实是视图树的一部分,但id 为 -1。
private void dumpAllViews(View v, int indent)
{
// Java doesn't support variable width format code -- "%*c"
// Fake it with string concatenation. Lame!
Log.d(tag, String.format("%" + (indent * 4 + 1) + "c%s %d", ' ', v.toString(), v.getId()));
if (v instanceof ViewGroup)
{
ViewGroup vg = (ViewGroup)v;
for (int i = 0; i < vg.getChildCount(); i++)
{
dumpAllViews(vg.getChildAt(i), indent + 1);
}
}
}
为什么该片段中的所有视图都有 id -1?
编辑:对于好奇的,这是被丢弃的视图树。有问题的视图是第二个块内的视图,ID 为 2131165209 的视图。
com.android.internal.policy.impl.PhoneWindow$DecorView@4057e118 -1
android.widget.FrameLayout@4057e4f0 16908290
android.widget.RelativeLayout@4057eee8 -1
android.widget.FrameLayout@4057f2e0 2131165208
android.support.v4.app.NoSaveStateFrameLayout@40594dd0 -1
android.widget.RelativeLayout@405933e0 -1
android.widget.ImageView@405937d0 -1
android.widget.Button@40593b30 2131165223
android.widget.Button@40594260 2131165224
android.widget.TextView@40594820 -1
android.widget.FrameLayout@4057f5b0 2131165209
android.support.v4.app.NoSaveStateFrameLayout@405972e0 -1
android.widget.RelativeLayout@40595588 -1
android.widget.ImageView@40595978 -1
android.widget.Button@40595cd8 -1
android.widget.Button@40596448 -1
android.widget.Button@40596b78 -1
android.widget.TextView@4057f8c8 2131165210
android.widget.FrameLayout@405805a8 2131165211
android.support.v4.app.NoSaveStateFrameLayout@40592c20 -1
android.widget.RelativeLayout@4058e1c0 -1
android.view.View@4058e5a8 2131165213
com.mycompany.MyCustomWidget@4058e7b8 -1
android.widget.TextView@40592158 2131165210
android.widget.TextView@405926c0 2131165259
android.widget.RelativeLayout@40580878 2131165212
android.view.View@40580cc8 2131165213
android.widget.FrameLayout@40580e50 2131165214
android.widget.FrameLayout@40581120 2131165215
android.widget.LinearLayout@40581440 2131165216
android.widget.FrameLayout@405816c8 2131165217
android.widget.FrameLayout@40581930 2131165218
android.widget.RelativeLayout@40581d00 -1
android.widget.Button@40582878 2131165261
android.widget.LinearLayout@40583ac0 -1
android.widget.Button@40583d48 2131165262
android.widget.Button@405846e0 2131165263
android.widget.Button@40585078 2131165264
android.widget.Button@40585a10 2131165265
android.widget.LinearLayout@405863a8 -1
android.widget.Button@40586630 2131165266
android.widget.Button@40586e50 2131165267
android.widget.Button@40587670 2131165268
android.widget.Button@40587e90 2131165269
编辑 2:这是所有相关的 XML。首先是“片段容器”布局,然后是各个片段的布局。“中心,减半”注释之后的所有内容此时都未使用,但为了完整性而包含在内。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<!--
Total contents:
Top bar
Bottom bar
Middle area (full screen)
Middle area (half/half, tablet only)
Middle area (40/60, tablet only)
-->
<!-- Note to self:
Why are the placeholder FrameLayouts and not just Views?
Once I get this bootstrapped I should try switching them
to Views and see if that works just as well.
-->
<!-- Top -->
<FrameLayout
android:id="@+id/top_fragment"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
/>
<!-- Bottom -->
<FrameLayout
android:id="@+id/bottom_fragment"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
/>
<TextView
android:text="This space unintentionally left blank"
android:textColor="#FFF"
android:textSize="18sp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<!-- Center, full -->
<FrameLayout
android:id="@+id/center_fragment_full"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="@id/top_fragment"
android:layout_above="@id/bottom_fragment"
/>
<!-- Center, halved -->
<RelativeLayout
android:id="@+id/center_fragment_half_container"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="@id/top_fragment"
android:layout_above="@id/bottom_fragment"
>
<View android:id="@+id/keystone"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_height="0dip"
android:layout_width="0dip"
android:visibility="invisible"
/>
<FrameLayout
android:id="@+id/center_fragment_half_left"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_toLeftOf="@id/keystone"
/>
<FrameLayout
android:id="@+id/center_fragment_half_right"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_toRightOf="@id/keystone"
/>
</RelativeLayout>
<!-- Center, uneven split (roughly 40/60) -->
<LinearLayout
android:id="@+id/center_fragment_uneven_split_container"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="@id/top_fragment"
android:layout_above="@id/bottom_fragment"
android:orientation="horizontal"
>
<FrameLayout
android:id="@+id/center_fragment_uneven_split_left"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_toLeftOf="@id/keystone"
android:layout_weight="2"
/>
<FrameLayout
android:id="@+id/center_fragment_uneven_split_right"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_toRightOf="@id/keystone"
android:layout_weight="3"
/>
</LinearLayout>
<include layout="@layout/slide_out_menus"/>
</RelativeLayout>
这是代替顶部栏的布局;它的 ID 很好:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<ImageView
android:layout_height="@dimen/bars"
android:layout_width="fill_parent"
android:background="@drawable/rectangle_1"
android:layout_alignParentTop="true"
/>
<Button android:id="@+id/button3"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:background="@drawable/button_3"
android:layout_marginTop="5dip"
android:layout_marginLeft="4dip"
/>
<Button android:id="@+id/button4"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:background="@drawable/button_4"
android:layout_marginTop="5dip"
android:layout_marginRight="4dip"
/>
<TextView
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:background="@drawable/top_bar1"
android:text="Title text"
style="@style/style_2"
android:gravity="center_horizontal|center_vertical"
android:layout_marginTop="4dip"
android:layout_marginLeft="4dip"
android:layout_marginRight="4dip"
android:layout_toRightOf="@id/button3"
android:layout_toLeftOf="@id/button4"
android:layout_alignParentTop="true"
android:scaleType="fitXY"
/>
</RelativeLayout>
这是在底部栏中替换的布局;它的 ID 坏了:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<ImageView
android:layout_height="@dimen/bars"
android:layout_width="fill_parent"
android:background="@drawable/rectangle_1"
/>
<Button android="@+id/button1"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:background="@drawable/button_1"
android:layout_alignParentLeft="true"
android:layout_marginLeft="3dip"
android:layout_marginTop="5dip"
style="@style/style_1"
android:text="foobar"
/>
<Button android="@+id/button2"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:background="@drawable/button_2"
android:layout_alignParentRight="true"
android:layout_marginRight="3dip"
android:layout_marginTop="5dip"
style="@style/style_1"
android:text="@string/menu"
/>
<Button android="@+id/button5"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:background="@drawable/button_5"
android:layout_centerHorizontal="true"
style="@style/style_1"
android:textSize="14dip"
android:layout_marginTop="7dip"
/>
</RelativeLayout>
最后,这是我目前在中间替换的布局;它的ID很好。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<View android:id="@+id/keystone"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_height="0dip"
android:layout_width="0dip"
android:visibility="invisible"
/>
<com.mycompany.MyCustomWidget
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
/>
<TextView
android:id="@+id/current_location_label"
android:text="Current Location"
android:textColor="#FFF"
android:textSize="13sp"
android:layout_centerHorizontal="true"
android:layout_above="@id/keystone"
android:paddingBottom="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/current_location_data"
android:text="City\nSTATE"
android:textColor="#ACF"
android:textSize="22sp"
android:gravity="center"
android:layout_centerHorizontal="true"
android:layout_below="@id/keystone"
android:paddingTop="0dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>