安卓:片段无法获取活动

19

我有一个活动,其中进行了片段事务

DetailFragment newFragment = new DetailFragment();
transaction.replace(R.id.mylist, newFragment);
transaction.addToBackStack(null);
transaction.commit();

这个很好。现在我知道我的活动中有一个动态字符串,我需要替换我在newFragment中的布局。我认为我可以在transaction.commit()之后调用类似于以下内容的东西:

newFragment.setMyString("my dynamic value");

在 newFragment.java 文件中,我有以下内容:
public void setMyString(String s)
{
 TextView tv = (TextView) getActivity().findViewById(R.id.myobject);
 tv.setText(s);
}

问题在于getActivity()返回null。我该如何获取所需的上下文来查找我的布局元素?

编辑:

我尝试按照捆绑包的方式进行,因为这似乎是最干净的方法。所以我已经改变了我的代码:

Bundle b = new Bundle();
b.putString("text", "my dynamic Text");
DetailFragment newFragment = new DetailFragment();
transaction.replace(R.id.mylist, newFragment);
transaction.addToBackStack(null);
transaction.commit();

我的fragment的onCreateView方法如下所示:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
{
   View v = inflater.inflate(R.layout.mylayout, container, false);
   TextView t = (TextView) v.findViewById(R.id.texttobereplaced);
   t.setText(savedInstanceState.getString("text");
}

看起来savedInstanceState是空的。我应该在哪里找到我的bundle?

编辑2:

回复中漏掉了getArguments()。现在正在工作。

4个回答

20

请确保在onAttach()方法中或之后调用getActivity()方法,否则在此之前它将返回null


抱歉,我不理解在哪里应该调用getActivity()并将其传递给我的setMyString()函数。如果我按照你建议的那样做,你仍然会写可能会返回null。我该如何理解这个? - AndyAndroid
6
onActivityCreated 之前,Fragment 将附加到一个 null 的活动上...也就是说,如果在 onCreateonCreateView 中调用 getActivity(),它将返回 null,因为 Activity 还没有被创建。所以请确保您所有对 getActivity() 的调用都在 onActivityCreated 中或之后进行。 - Alex Lockwood
4
这是错误的。一旦调用了onAttach,就可以调用getActivity()而不返回null。onActivityCreated仅是在活动完全创建且片段布局已实例化时的回调函数。 - dymmeh
2
@AlexLockwood 为什么你说 onCreate() 方法会返回 null?我在 Android 框架中看到很多例子,在 onCreate() 方法中调用 getActivity()。这里有一个例子:http://androidxref.com/4.4.3_r1.1/xref/packages/apps/Calendar/src/com/android/calendar/QuickResponseSettings.java - IgorGanapolsky
2
是的,我不确定为什么我写了那个...只要在onAttach()之后调用getActivity(),活动就应该可用。我编辑了我的原始回答来解决这个问题...说实话,我不确定这个答案为什么会有5个赞。我想我两年前更像一个新手。:P - Alex Lockwood

18

1
我的布局被填充了,onViewCreated被调用了。我能看到我的布局。 - AndyAndroid

2

我也使用相同的片段事务管理器,但是我发现你代码中唯一的问题是你在newFragment类的onCreateView方法中定义了TextView tv,然后像这样进行实例化:

public class AboutFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.newFragment, container, false);
        TextView tv = (TextView) v.findViewById(R.id.textview);
        return v;
    }

    public void setMyString(String s) {
        tv.setText(s);
    }
}

我知道这样做可能没有太多意义,但这就是我运行代码的方式,而且它可以正常工作 :)


抱歉,我不知道那么重要 :) 已经更改了...希望现在看起来更好。 - Android2390
3
当然,在StackOverflow上缩进您的代码很重要......如果您的代码明显无法阅读,人们不会认为您是一个非常可信的来源。我刚刚编辑了您的答案并删除了反对票。 - Alex Lockwood

0

如果您需要在OnCreateView中调用getActivity,请将所有代码从onCreateView移动到onActivityCreated,并仅保留行

View v = inflater.inflate(R.layout.xxxx, container, false);
    return v;

在onCreateView中

但我有一个有趣的情况。

在我的onActivityCreated中

Spinner s1 = (Spinner) getActivity().findViewById(R.id.bitlength);
    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
            getActivity(), R.array.bitlengths,
            android.R.layout.simple_spinner_item);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    s1.setAdapter(adapter);

有时候onActivityCreated方法不会运行(正确地?),因此spinner s1变为空。

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