【问题标题】:Initializing fragments outside of OnCreate() in Android在 Android 中初始化 OnCreate() 之外的片段
【发布时间】:2021-04-13 12:42:43
【问题描述】:

我对 Android 开发非常陌生。我基本上有一个带有一些按钮的活动,例如“seeTreePicture”和“seeSeaPicture”。当我按下一个按钮时,我想使用我称为“ContentViewer”的片段来显示随机的树/海图片,并且图片下方还有按钮来破坏 ContentViewer 片段实例并返回菜单。问题是,如果我尝试在活动的 onCreate() 以外的任何地方使用 Fragment Transaction,当我尝试访问片段中的视图时会出现空指针异常。

我的活动和与片段相关的事情:

public class SeeActivity extends AppCompatActivity {

DisplayFragment displayFragment;
Button seeTreeButton;
Button seeSeaButton;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_see);

    seeTreeButton = findViewById(R.id.seeTreeButton);
    seeSeaButton = findViewById(R.id.seeSeaButton);
    displayFragment = new DisplayFragment();

    seeTreeButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
            fragmentTransaction.add(R.id.fragmentContainer, displayFragment);
            fragmentTransaction.commit();
            fragmentTransaction.addToBackStack(null);

            displayFragment.changeImage(randomTree);
        }
    });

}

}

在我的片段中,更改图像只是更改 ImageView 的图像源:

public void changeImage(int treeResource)
{
    img = getView().findViewById(R.id.imageView);
    img.setImageResource(treeResource);
}

尝试从片段中的 getView() 访问视图时出现空指针异常,这意味着未调用 onCreateView。但是,如果我将相同的事务放在活动的 onCreate() 方法中,它就可以工作。我做错了什么?

【问题讨论】:

    标签: android android-studio android-layout android-fragments android-activity


    【解决方案1】:

    因为片段事务不会立即发生。它发生异步。所以创建视图的实际工作还没有发生。您的选择是使用 commitNow() 而不是 commit(它将同步执行,但需要更多时间并可能导致您的应用明显暂停)或等待片段事务实际完成。这可以通过将其放入 Runnable 并将该 runnable 传递给 runOnCommit 来轻松完成

    【讨论】:

      【解决方案2】:

      您的代码的问题是您在片段完成视图初始化之前访问片段的getView()。当您在活动的onCreate() 方法中执行事务时没有崩溃的原因是,当您单击按钮时,您的片段已经通过onCreateView() 并初始化了它的视图。查看fragment lifecycle guide 并记住,您不应该在创建片段视图之前或销毁片段视图之后访问它。有关为什么您的片段视图未立即初始化的更多信息check out this guide。 至于解决方案,请考虑在将片段添加到事务之前为片段设置参数,如下所示:

      Bundle args = new Bundle();
      args.putInt(DisplayFragment.IMG_RESOURCE_ARG, randomTree);
      displayFragment.setArguments(args);
      

      然后在您的片段的onCreateView()onViewCreated() 方法中恢复此处的参数并设置图像资源:

      @Override
      public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
          int resourceId = requireArguments().getInt(IMG_RESOURCE_ARG);
          img = view.findViewById(R.id.imageView);
          img.setImageResource(resourceId);
      }
      

      【讨论】:

        猜你喜欢
        • 2016-12-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-26
        • 2012-09-09
        • 2020-11-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多