【问题标题】:Null view after replacing fragment替换片段后的空视图
【发布时间】:2015-08-21 07:44:25
【问题描述】:

问题来了
我有一个FragmentDisplayFragment 并且我已经在content frame 中有一个节目,然后我做

DisplayFragment a = DisplayFragment.newInstance();
getSupportFragmentManager().beginTransaction()
            .replace(R.id.contentFrame, DisplayFragment)
            .commit();

然后我想使用View v = a.getView(); 获得fragmentview,但它返回null view
谁能告诉我为什么?因为我必须更改新Fragment 的一些视图设置。

onCreateView() in DisplayFragment

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_display, container, false);
    //Some TextView setup
    Button button = (Button) view.fineViewById(R.id.button);
    return view; }

【问题讨论】:

  • 可以添加DisplayFragment的代码吗?我怀疑这是因为片段转换的延迟。
  • getSupportFragmentManager().beginTransaction() .replace(R.id.contentFrame, a); .commit();

标签: android android-fragments fragment android-view


【解决方案1】:

您需要使用延迟或将View v = a.getView(); 放入循环中,这将首先观察您的片段是否已成功附加、创建和添加到您的活动中。为此,您可以检查 isAdded()isInLayout() 如果两者都返回 true 则只调用 getView()

现在为什么会这样,当您使用提交添加/替换片段时,将片段将首先执行它将开始片段生命周期,即 onAttach()、onCreate()、onCreateView() 等等。现在,您将从 getView() 获得 null 只是因为您的视图尚未创建。 Fragment Life Cycle。如果您对此有疑问,请告诉我。

【讨论】:

    【解决方案2】:

    我假设您在commit 之后立即调用View v = a.getView();

    因为getView方法只在onCreateView返回后才返回非空值。

    在您的情况下,在调用commit() 之后,需要时间来完成DisplayFragment a 的所有生命周期回调(从onCreate -> onCreatedView,..)。
    因此,在 commit() 之后,getView 方法仍然返回 null

    【讨论】:

      【解决方案3】:

      声明 DisplayFragment a;作为类参考。因为提交后你只想访问 View v = a.getView();由于片段生命周期,它不可用。你可以在执行代码块之后得到。

      确保你必须在类 DisplayFragment 上提到 OnCreateView() 方法

       @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container,
              Bundle savedInstanceState) {
        if (container == null) {
              // We have different layouts, and in one of them this
              // fragment's containing frame doesn't exist.  The fragment
              // may still be created from its saved state, but there is
              // no reason to try to create its view hierarchy because it
              // won't be displayed.  Note this is not needed -- we could
              // just run the code below, where we would create and return
              // the view hierarchy; it would just never be used.
              return null;
          }
          Log.i("Right", "onCreateView()");
          return inflater.inflate(R.layout.right, container, false);
      } 
      

      【讨论】:

        【解决方案4】:

        我和你有同样的问题。 由于片段的交易没有立即发生。这就是为什么有时findViewById() 不能正常工作的原因。但是我们可以使用executePendingTransactions() 方法来执行挂起的事务。我在我的项目中使用了以下代码来执行 pedingTransactions。

        Fragment f = (Fragment)(FragmentClass.class).newInstance();
        
        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        ft.replace(R.id.your_fragment_container_name,f).commit();
        fm.executePendingTransactions(); //Notice the FragmentManager Class object
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-07-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多