Android片段顶层布局无法通过编程访问

Android片段顶层布局无法通过编程访问,android,android-layout,android-fragments,Android,Android Layout,Android Fragments,我无法通过在xml中为布局指定的id到达片段的顶层“”,它原来是空对象。但我可以访问其子视图的父视图。该父级不是布局本身,而是包含布局的“”。当我通过编程将子元素添加到这个片段中时,它们不会与已经存在的子元素对齐,这表明这些子元素实际上位于嵌套布局中 这种行为真让我困惑。有人能解释发生了什么事吗 我声明一个顶层碎片布局,如下所示: 剥离兄弟片段和布局设置以提高可读性 MainActivity.java如下所示 protected void onCreate(Bundle savedInstanc

我无法通过在xml中为布局指定的id到达片段的顶层“”,它原来是空对象。但我可以访问其子视图的父视图。该父级不是布局本身,而是包含布局的“”。当我通过编程将子元素添加到这个片段中时,它们不会与已经存在的子元素对齐,这表明这些子元素实际上位于嵌套布局中

这种行为真让我困惑。有人能解释发生了什么事吗

我声明一个顶层碎片布局,如下所示:

剥离兄弟片段和布局设置以提高可读性

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/main活动(2346):来自ID的布局为空

08-22 12:06:24.856:D/MainActivity(2346):ID父项名称:show_weights_fragment

实际的模拟器输出显示这两个文本没有对齐,这让我假设它们不包含在同一个

尝试将代码从onCreate移动到onCreateView

从Android文档:


onCreateView(视图、字符串、上下文、属性集)的标准实现,在使用getSystemService(类)返回的LayoutInflater进行膨胀时使用。此实现处理标记以将片段嵌入活动中简短回答:如果在
中设置了id,请使用片段的id
R.id.show\u weights\u fragment
访问其视图


具有用于处理片段ID的语句:

注意:每个片段都需要一个唯一的标识符,如果活动重新启动,系统可以使用该标识符恢复片段(您可以使用该标识符捕获片段以执行事务,例如删除它)。有三种方法可以为片段提供ID:

  • 为android:id属性提供唯一的id
  • 为android:tag属性提供一个唯一的字符串
  • 如果您未提供前两个,系统将使用容器视图的ID
这激发了这样一种假设,即如果设置了片段的id,它只会以另一种方式工作。我找不到关于这一点的文档,但表明这一假设成立:

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\u weights\u fragment

我想答案只是一个猜测。但是我尝试了,结果是一样的。我尝试将布局请求移动到片段
onStart()
。所有布局元素都应该已经创建并可用。还是一样的结果。
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);
}
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;
}