【问题标题】:Android: Fragment cannot get activityAndroid:片段无法获得活动
【发布时间】:2012-07-31 15:11:22
【问题描述】:

我有一个进行片段事务的活动

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();

我的片段 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");
}

savedInstranceState 似乎是空的。我应该在哪里找到我的捆绑包?

编辑2:

在回复中错过了 getArguments()。现在正在工作。

【问题讨论】:

    标签: android android-fragments


    【解决方案1】:

    确保在onAttach() 之后或之后调用getActivity(),因为之前它将返回null

    【讨论】:

    • 对不起,我不明白我应该在哪里调用 getActivity() 并将它传递给我的 setMyString() 函数。如果我在您建议您仍然编写的地方执行此操作,它可能会或可能不会返回 null。我该如何理解?
    • Fragment 将附加到null 活动直到onActivityCreated...也就是说,如果您在onCreateonCreateView 中调用getActivity(),它将返回@ 987654331@ 因为尚未创建 Activity。因此,请确保您在 onActivityCreated 或之后onActivityCreated
    • 这是错误的。一旦调用了 onAttach,就可以调用 getActivity() 而不会返回 null。 onActivityCreated 只是 Activity 完全创建且片段布局已实例化时的回调。
    • @AlexLockwood 为什么说它会在 onCreate() 中返回 null?我在 Android 框架中看到很多示例,它们在 onCreate() 中调用 getActivity()。这是一个例子:androidxref.com/4.4.3_r1.1/xref/packages/apps/Calendar/src/com/…
    • 是的,我不知道为什么我写了那个……只要您在onAttach() 之后调用getActivity(),该活动就应该可用。我编辑了我的原始回复来解决这个问题......老实说,我不确定这个答案是如何获得 5 票赞成的。我想我两年前更像是一个菜鸟。 :P
    【解决方案2】:

    您的Fragment 尚未附加到Activity,这也意味着您的布局尚未膨胀(请参阅Fragment lifecycle)。这里最好的解决方案是通过Fragment.setArguments(Bundle) 方法将您的String 值作为参数添加到Fragment。这可以通过Fragment.getArguments() 方法在接收Fragment 中检索到。

    【讨论】:

    • 我的布局被夸大了 onViewCreated 被调用。我可以看到我的布局。
    【解决方案3】:

    所以我也在使用相同的片段事务管理器,我可以看到您的代码的唯一问题是您在 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);
        }
    }
    

    我知道这并没有多大意义,但这就是我运行代码的方式,它运行良好:)

    【讨论】:

    • 抱歉不知道这很重要 :) 改了..希望现在看起来更好
    • 当然,缩进代码在 StackOverflow 上很重要……如果您的代码明显不可读,人们不会认为您是一个非常可靠的来源。我刚刚编辑了您的答案并删除了反对票。
    【解决方案4】:

    如果您需要在 OnCreateView 中调用 getActivity,请将您的所有代码从 onCreateView 移动到 onActivityCreate 并且只剩下几行

    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 不会运行(正确!?),因此微调器 s1 变为空。

    【讨论】:

      猜你喜欢
      • 2020-08-12
      • 1970-01-01
      • 1970-01-01
      • 2018-04-11
      • 1970-01-01
      • 2012-10-28
      • 1970-01-01
      • 2021-10-26
      相关资源
      最近更新 更多