无法实例化Fragment

时间:2011-08-10 19:30:38

标签: android android-fragments

  

无法实例化片段确保类名存在,是公共的,   并且有一个空的构造函数是公共的

是因为我的片段不是静态类吗? 是因为我的片段是一个内部阶级吗?

如果我将Fragment设为静态类,那么我对findViewById的所有引用都会失败,这意味着很多重构。

如何在不将内部片段变为静态类的情况下解决此问题?

13 个答案:

答案 0 :(得分:26)

  

是因为我的片段是一个内部类

如果您的片段是内部类,则它必须是静态内部类。理想情况下,它是一个独立的公共Java类。

  

如果我将Fragment设为静态类,那么我对findViewById的所有引用都会失败,这意味着很多重构

无论如何,你需要进行重构。窗口小部件现在由片段拥有,而不是活动。片段应尽可能少地了解包含它们的活动,因此可以根据需要在不同的活动之间进行随机播放,以支持手机,平板电脑,电视等。

  

如何在不将内部片段转换为静态类的情况下解决这个问题?

您将其设置为独立的公共Java类。

答案 1 :(得分:15)

你的片段不应该有构造函数(参见this documentation及其示例)。

您应该定义newInstance()静态方法,并通过参数(包)传递任何参数

例如:

public static final MyFragment newInstance(int title, String message)
{
    MyFragment fragment = new MyFragment();
    Bundle bundle = new Bundle(2);
    bundle.putInt(EXTRA_TITLE, title);
    bundle.putString(EXTRA_MESSAGE, message);
    fragment.setArguments(bundle);
    return fragment ;
}

在onCreate上阅读这些论点:

@Override
public Dialog onCreate(Bundle savedInstanceState)
{
    title = getArguments().getInt(EXTRA_TITLE);
    message = getArguments().getString(EXTRA_MESSAGE);

    //...
    //etc
    //...
}

这种方式如果分离并重新附加对象状态可以通过参数存储,就像附加到Intents的bundle一样。

答案 2 :(得分:10)

正如CommonsWare所说,让它静态或独立,另外不知道为什么你需要重新调整才能让findViewById工作。建议:

使用onCreateView中充斥的视图,

inflatedView.findViewById(.....)

或在onActivityCreated(.....)

中调用它
getActivity().findViewById(......)

但是,即使你仍然需要大量的重构,那可能就是这样,将应用程序转换为使用片段并不是免费的,只需完成一个项目即可。

答案 3 :(得分:4)

我也有这个问题 - 事实证明它很混乱,因为我的自定义Fragment有一个构造函数。

我重命名了构造函数方法,并在实例化时调用了新方法,并且它有效!

答案 4 :(得分:4)

public static class MyDialogFragment extends DialogFragment {

    public MyDialogFragment(){

    }

    public Dialog onCreateDialog(Bundle savedInstanceState) {
            LinearLayout main = new LinearLayout(getActivity());
    main.setOrientation(LinearLayout.VERTICAL);


            return (new AlertDialog.Builder(getActivity()).setTitle(
    getText("Title")).setView(main).create());
            }
 }

答案 5 :(得分:3)

在我的情况下,我错过了构造函数,上面@eoghanm的帖子帮助了我

public static class MyDialogFragment extends DialogFragment {

    public MyDialogFragment(){
    }
...
}

答案 6 :(得分:2)

使用setRetainInstance(true)为我们工作。我们的内部课程现在看起来像这样:

public class SectionsPagerAdapter extends FragmentPagerAdapter {
    public SectionsPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
    // getItem is called to instantiate the fragment for the given page.
        Fragment fragment = new MySectionFragment();
        Bundle args = new Bundle();
        args.putInt(MySectionFragment.ARG_SECTION_NUMBER, position + 1);
        fragment.setArguments(args);
        fragment.setRetainInstance(true);
        return fragment;
    }
    // ...
}

public class MySectionFragment extends Fragment {
    public static final String ARG_SECTION_NUMBER = "section_number";
    @SuppressLint("ValidFragment")
    public MySectionFragment() {
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        //...
    }       
    // ...
}

PS。这是一个关于setRetainInstance(boolean)的有趣的:Understanding Fragment's setRetainInstance(boolean)

答案 7 :(得分:1)

如果您不想使内部类静态,请尝试覆盖对话框片段的onPause方法,如下所示:

public void onPause()
{
  super.onPause();
  dismiss();
}

因此当应用程序暂停时应该销毁该片段并且没有异常。我尝试过并且有效。

答案 8 :(得分:0)

确保片段不是抽象的。复制和粘贴使这种事情发生:(

答案 9 :(得分:0)

内部类构造函数必须传入外部类的实例。所以据说编译器找不到没有参数的构造函数。所以它应该被放入其他java文件的静态。

答案 10 :(得分:0)

我遇到了这个问题 你需要使用完整的班级名称: 例如: Fragment.instantiate(MainActivity.this,com.XX.yourFragmentName);

必须是完整的班级名称

答案 11 :(得分:0)

哈哈,我的热闹问题是我在我的片段中调用了getString()作为成员级变量,这是一个很大的不可,因为我觉得它太早了。我希望错误更具描述性!

答案 12 :(得分:0)

还值得尝试检查您的默认 Fragment 构造函数是 public,而不是 Android Studio 可能建议的 package-private。这就是我的原因。