我的应用程序在方向更改时崩溃。当发生这种情况时,我已经注意遵循默认建议,即每个片段都有一个无参数构造函数,并且由于我在MainActivity中实现了Fragments,因此它们被声明为static。然而,我仍然面临同样的例外,好像我没有这样做。
public class MainActivity extends FragmentActivity {
public static final String URL = "url";
public static final String ID = "id";
private SettingsPageAdapter pageAdapter;
private ViewPager pager;
private FrameLayout layoutTabBar;
public static class SettingsPageAdapter extends FragmentPagerAdapter {
private final List<Fragment> fragments;
public SettingsPageAdapter(FragmentManager fm) {
super(fm);
fragments = new ArrayList<Fragment>();
}
public void addWebViewItem(String url, String id) {
final Fragment settingsFragment = new SettingsWebView();
final Bundle bundle = new Bundle();
bundle.putString(URL, url);
bundle.putString(ID, id);
settingsFragment.setArguments(bundle);
this.fragments.add(settingsFragment);
}
public void addItem(Fragment f, String id) {
final Bundle bundle = new Bundle();
bundle.putString(ID, id);
f.setArguments(bundle);
this.fragments.add(f);
}
@Override
public Fragment getItem(int position) {
return this.fragments.get(position);
}
@Override
public int getCount() {
return this.fragments.size();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.bar, new BarFragment()).commit();
}
pageAdapter = new SettingsPageAdapter(getSupportFragmentManager());
pageAdapter.addWebViewItem("https://www.google.com", "WebView 1");
pageAdapter.addWebViewItem("https://m.bbc.co.uk", "WebView 2");
pageAdapter.addWebViewItem("http://thorbek.net", "WebView 3");
pageAdapter.addItem(new ContainerFragment(), "container");
pager = (ViewPager) findViewById(R.id.container);
pager.setOffscreenPageLimit(pageAdapter.getCount() - 1);
pager.setAdapter(pageAdapter);
pager.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int arg0) {
Log.d("PAGER", "onPageSelected");
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
Log.d("PAGER", "onPageScrolled");
}
@Override
public void onPageScrollStateChanged(int arg0) {
Log.d("PAGER", "onPageScrollStateChanged");
final int currentItem = pager.getCurrentItem();
final BarFragment barFragment = (BarFragment) getSupportFragmentManager()
.findFragmentById(R.id.bar);
barFragment.setCurrentItem(currentItem);
}
});
layoutTabBar = (FrameLayout) findViewById(R.id.bar);
initAnimation();
}
private void initAnimation() {
...
}
public static class BarFragment extends Fragment {
private final List<Button> buttons = new ArrayList<Button>();
private int currentIndex = -1;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_buttonbar,
container, false);
initButtons(rootView);
return rootView;
}
@SuppressWarnings("deprecation")
public void setCurrentItem(int index) {
if (currentIndex != index) {
resetButtons();
buttons.get(index).setBackgroundDrawable(
buttons.get(index).getContext().getResources()
.getDrawable(R.drawable.button_settings_pressed));
currentIndex = index;
}
}
@SuppressWarnings("deprecation")
private void initButtons(final View rootView) {
...
}
@SuppressWarnings("deprecation")
private void resetButtons() {
...
}
}
Java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.test/com.example.test.MainActivity}: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.example.test.MainActivity$BarFragment: make sure class name exists, is public, and has an empty constructor that is public
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2351)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2403)
at android.app.ActivityThread.access$700(ActivityThread.java:165)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1379)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5391)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment com.example.test.MainActivity$BarFragment: make sure class name exists, is public, and has an empty constructor that is public
at android.support.v4.app.Fragment.instantiate(Fragment.java:435)
at android.support.v4.app.FragmentState.instantiate(Fragment.java:101)
at android.support.v4.app.FragmentManagerImpl.restoreAllState(FragmentManager.java:1823)
at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:264)
at com.example.test.MainActivity.onCreate(MainActivity.java:79)
at android.app.Activity.performCreate(Activity.java:5122)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1150)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2315)
Caused by: java.lang.IllegalAccessException: access to class not allowed
at java.lang.Class.newInstanceImpl(Native Method)
at java.lang.Class.newInstance(Class.java:1319)
at android.support.v4.app.Fragment.instantiate(Fragment.java:420)
MainActivity.java:79是 super.onCreate(savedInstanceState);
因此它会立即被引入onAreate of MainActivity。
答案 0 :(得分:2)
异常非常清楚
make sure class name exists, is public, and has an empty constructor that is public
您的BarFragment课程必须是公开的
public static class BarFragment extends Fragment
或者,您可以通过在创建片段时执行以下操作来避免片段重新创建
setRetainInstance(true)
答案 1 :(得分:1)
您的BarFragment看起来不公开。尝试将其更改为
public static class BarFragment extends Fragment
此外,您不应将自己的空构造函数添加到片段中。默认构造函数将自动设置,并应正确处理恢复状态。如果需要将参数传递给片段,请尝试使用静态newInstance方法并为其分配一个包。
有关进一步说明,请参阅这些文档:
http://developer.android.com/reference/android/app/Fragment.html#Fragment%28%29
基本上删除你添加的构造函数。
祝你好运
答案 2 :(得分:0)
setRetainInstance(true);
我刚刚放了这条线,它解决了我的问题。
我的代码示例:
public class PlaceholderFragment extends Fragment{
String str;
public PlaceholderFragment (String strDesc1){
this.str=strDesc1;
setRetainInstance(true); //Hear put this line
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState){
View rootView = inflater.inflate(R.layout.quiz_play_descrption_frg_one_, null,false);
TextView txtdisc=(TextView) rootView.findViewById(R.id.txt_Discription_quizPlayFragment);
txtdisc.setText(str);
return rootView;
}
}
答案 3 :(得分:0)
当方向改变时,活动再次重新创建,你必须使用savedInstanceState维护碎片状态。
if(savedInstanceState == null)
{
mFragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = mFragmentManager.beginTransaction();
FragmentOne fragment = new FragmentOne();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();
}