无法实例化片段确保类名存在,是公共的, 并且有一个空的构造函数是公共的
是因为我的片段不是静态类吗? 是因为我的片段是一个内部阶级吗?
如果我将Fragment设为静态类,那么我对findViewById的所有引用都会失败,这意味着很多重构。
如何在不将内部片段变为静态类的情况下解决此问题?
答案 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。这就是我的原因。