使用Fragment时,调用findViewById返回NULL

29

我是Android开发的新手,当然也是在使用Fragments。

我想在主活动中访问我的fragment的控件,但是'findViewById'返回null。 没有fragment时,代码可以正常工作。

这是我的部分代码:

fragment:

<?xml version="1.0" encoding="utf-8"?>
<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="wrap_content"
    android:orientation="vertical"
    tools:ignore="HardcodedText" >

    <EditText
        android:id="@+id/txtXML"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:ems="10"
        android:scrollbars="vertical">
    </EditText>

</LinearLayout>

MainActivity的onCreate方法:

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.setContentView(R.layout.main);

        this.initialisePaging();

        EditText txtXML = (EditText) findViewById(R.id.txtXML);}

在这个地方,txtXML 是空的。

我的代码缺少什么或者我应该怎么做?


请发布您的initializePaging()方法。 - blacharnia
this.initialisePaging(); 这里没有什么重要的,只是将片段添加到 viewPager 中。 - mammadalius
7个回答

21

在onCreateView中尝试像这样处理你的碎片

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    if (container == null) {
        return null;
    }

    LinearLayout ll = (LinearLayout )inflater.inflate(R.layout.tab_frag1_layout, container, false);
EditText txtXML = (EditText) ll.findViewById(R.id.txtXML);

    return ll;
}

这个问题之前已经解决过了。我要找的是在MainActivity上的txtXML,而不是在Fragment本身上的。 - mammadalius

18

你应该在FragmentonCreateView方法中inflate片段的布局,然后就可以使用Activity上的findViewById简单访问它的元素。

在这个示例中,我的片段布局是一个LinearLayout,所以我将inflate结果强制转换为LinearLayout。

    public class FrgResults extends Fragment 
    {
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
        {
            //some code
            LinearLayout ll = (LinearLayout)inflater.inflate(R.layout.frg_result, container, false);
            //some code
            return ll;
        }
    }

1
请确保在使用 Android 的 support v4 库时,使用 FragmentActivitygetSupportFragmentManager 来避免出现 null。如果您仅构建新版本的 Android API,则使用常规的 Activity 和方法 getSupportFragmentManager。不要混合这两种实现方式。 - George Pligoropoulos

6

我晚了,但如果其他人遇到此问题。您应该在onCreateView方法中填充视图。然后覆盖onCreateActivity方法,您可以在那里使用getView().findViewById。

@Override public View onCreateView(LayoutInflater inflater, ViewGroup     container, Bundle savedInstanceState) 
{
     return      inflater.inflate(R.layout.fragment, container, false);
}

你说得对。我的问题之前已经解决了。请展示一些代码片段,以便其他人可以使用它来解压缩。 - mammadalius
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment, container, false); } - gdi
亲爱的@Futan,请将您的评论作为单独的答案编写,清晰地描述以便于其他人使用,当然我可以选择它作为被接受的答案。 - mammadalius

3

如果你想在Activity类中访问Fragment的视图,不能使用findViewById方法,你可以这样做...

你的Activity文件中必须有一个Fragment类的对象。在该Fragment类中创建EditText类的getter方法,并在Activity中访问该方法。

在需要Edittext对象的事件中,在Fragment类中创建回调函数。


我选择使用片段来简化我的解决方案并提高性能,但现在看起来它变得更加复杂了。 - mammadalius
它并不复杂…… 它非常强大,可以为您提供更多的灵活性。 - Nixit Patel

2

1) 尝试以下操作:

Eclipse 菜单 -> 项目 -> 清除...

更新

2) 如果您有两个或多个“主”布局实例,请检查它们是否都具有“txtXML” ID 的视图。

3)

片段是应用程序用户界面或行为的一部分,可以放置在 Activity 中。与片段的交互是通过 FragmentManager 完成的,可以通过 Activity.getFragmentManager() 和 Fragment.getFragmentManager() 获取它。

Fragment 类可以用于许多方式,以实现各种结果。它是核心的,表示在较大的 Activity 中运行的特定操作或接口。片段与其所在的 Activity 密切相关,不能单独使用。虽然 Fragment 定义了自己的生命周期,但该生命周期取决于其 Activity:如果 Activity 停止,则无法启动其中的任何片段;当 Activity 销毁时,所有片段都将被销毁。

请参阅 此文档。您必须使用 FragmentManager。


你只有一个“主”布局实例吗? - Bobs
是的,只有一个实例,我必须添加这个注释:txtXML 不在我的 main 布局上,它在另一个布局上,我想在片段中使用它。 - mammadalius
ењЁе†Ќж¬ЎиЋ·еЏ–Fragmentж—¶иї”е›ћдє†nullгЂ‚ View myFragment = findViewById(R.layout.tab_frag2_layout); - mammadalius

0
如果你想像在activities onCreate中一样使用findViewById,你可以简单地把所有内容放在重写的onActivityCreated方法中。

在onActivityCreated方法中,它返回相同的null。 - hopeTo

0
所有上面的答案都告诉你应该如何“返回布局”,但并没有确切地告诉你如何引用返回的布局,因此我无法使用任何给出的解决方案。我采用了不同的方法来解决这个问题。在处理片段的片段类中,进入onViewCreated()类并在其中创建一个上下文变量,保存父活动(在我的情况下是主要活动)的上下文。
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    Context fragmentContext = (MainActivity) view.getContext();
}

完成这个步骤后,你可以使用新的上下文对象,在onViewCreated()方法中访问你的Fragment中的元素。

EditText editText = context.findViewById(R.id.textXML);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接