我无法通过其xml中给出布局的id到达片段的顶级”,它原来是一个空对象.但我可以访问其子视图的父级.那个父母不是布局本身,而是“包含布局”.当我以编程方式将子项添加到此片段时,它们不会与已存在的子项对齐,这表明这些子项实际上位于嵌套布局中.
这种行为真的让我感到困惑.任何人都可以解释发生了什么?
我声明了一个顶级碎片布局,如下所示:
Sibling fragments and layout settings stripped for readability
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_view"
>
<fragment
android:layout_gravity="center_horizontal|center_vertical"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="40dp"
android:layout_weight="0.3"
android:name="foo.bar.foobar.fragments.ShowWeightsFragment"
android:id="@+id/show_weights_fragment"
tools:layout="@layout/frag_show_weights"
/>
</LinearLayout>
layout / frag_show_weights定义如下:
<LinearLayout 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:id="@+id/layout_container_weights"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="Foo"
android:id="@+id/xmlTextChildren"
android:layout_gravity="center" />
</LinearLayout>
MainActivity.java如下所示
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView t = (TextView) findViewById(R.id.xmlTextChildren);
t.setText("Foo");
LinearLayout parentLayout = (LinearLayout) findViewById(R.id.xmlTextChildren).getParent();
LinearLayout layoutFromID = (LinearLayout) findViewById(R.id.layout_container_weights);
TextView v = new TextView(this);
v.setText("Bar");
if (layoutFromID == null) Log.d(TAG, "Layout from ID is null");
Log.d(TAG, "ID parent name: " + getResources().getResourceEntryName(parentLayout.getId()));
parentLayout.addView(v);
}
日志输出如下:
08-22 12:06:24.855: D/MainActivity(2346): Layout from ID is null
08-22 12:06:24.856: D/MainActivity(2346): ID parent name: show_weights_fragment
并且实际的模拟器输出显示两个文本不对齐,这使我假设它们不包含在相同的< LinearLayout>内.
最佳答案 简答:如果您在< fragment>中设置了ID,请使用片段的ID R.id.show_weights_fragment来访问其视图.
The documentation for Fragments有一个处理ID片段的声明:
Note: Each fragment requires a unique identifier that the system can use to restore the fragment if the activity is restarted (and which you can use to capture the fragment to perform transactions, such as remove it). There are three ways to provide an ID for a fragment:
- Supply the android:id attribute with a unique ID.
- Supply the android:tag attribute with a unique string.
- If you provide neither of the previous two, the system uses the ID of the container view.
如果设置了片段的id,这就会激发这种假设,即它只是相反的方式.我找不到关于此的文档,但the sources for FragmentManagerImpl
显示,这个假设成立:
public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
if (!"fragment".equals(name)) {
return null;
}
[...]
int id = a.getResourceId(com.android.internal.R.styleable.Fragment_id, View.NO_ID);
String tag = a.getString(com.android.internal.R.styleable.Fragment_tag);
[...]
if (id != 0) {
fragment.mView.setId(id);
}
if (fragment.mView.getTag() == null) {
fragment.mView.setTag(tag);
}
return fragment.mView;
}
这也是您的日志显示的内容:parentLayout.getId()== R.id.show_weights_fragment.