我的应用程序包含片段,它主要是片段应用程序。我只有3个活动,其他都是碎片。但是,从应用程序的任何一点开始,当我以横向模式或纵向旋转手机时,应用程序将从头开始重新启动并从应用程序的起点继续。
我把android:configChanges="orientation|keyboardHidden|keyboard"
放在Manifest中,但它似乎根本没有效果。我只用一个Web视图填充片段。但我也改变了动作栏的颜色。这就是我在应用程序中所做的一切。它是一个静态应用程序,没有用户输入。以下是我的片段的示例代码:
public class CLASSNAME extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setRetainInstance(true);
}
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.LAYOUT, container, false);
ActionBar bar = getActivity().getActionBar();
bar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.COLOR)));
bar.setTitle("TITLE");
final WebView wFirst = (WebView) view.findViewById(R.id.WEBVIEWID);
wFirst.getSettings().setJavaScriptEnabled(true);
wFirst.setBackgroundColor(0x00000000);
wFirst.loadDataWithBaseURL(LOADING DATA);
wFirst.setWebViewClient(new WebViewClient() {SETTING UP WEBVIEW CLIENT});
return view;
}
}
我阅读了许多通过“保存实例状态”和其他方法得到解答的帖子,但在我的情况下,我不知道要保存什么以及如果方向发生变化,如何保持我的活动滚动。
这是 MainActivity.class 代码:
public class MainActivity extends Activity
implements NavigationDrawerFragment.NavigationDrawerCallbacks {
/**
* Fragment managing the behaviors, interactions and presentation of the navigation drawer.
*/
private NavigationDrawerFragment mNavigationDrawerFragment;
private static CharSequence mTitle;
public static Context context;
public static Context getContext() {
return context;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = getApplicationContext();
mNavigationDrawerFragment = (NavigationDrawerFragment)
getFragmentManager().findFragmentById(R.id.navigation_drawer);
mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
}
@Override
protected void onDestroy() {
super.onDestroy();
android.os.Process.killProcess(android.os.Process.myPid());
super.onDestroy();
}
@Override
public void onBackPressed() {
super.onBackPressed();
finish();
}
@Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getFragmentManager();
switch (position) {
case 1:
fragmentManager.beginTransaction()
.replace(R.id.container, new AlgebraicGraphs())
.commit();
break;
case 2:
fragmentManager.beginTransaction()
.replace(R.id.container, new Logarithms())
.commit();
break;
case 3:
fragmentManager.beginTransaction()
.replace(R.id.container, new Polynomials())
.commit();
break;
case 4:
fragmentManager.beginTransaction()
.replace(R.id.container, new Powers())
.commit();
break;
case 6:
fragmentManager.beginTransaction()
.replace(R.id.container, new AreaFormulas())
.commit();
break;
case 7:
fragmentManager.beginTransaction()
.replace(R.id.container, new SurfaceAreaFormulas())
.commit();
break;
case 8:
fragmentManager.beginTransaction()
.replace(R.id.container, new PerimeterFormulas())
.commit();
break;
case 9:
fragmentManager.beginTransaction()
.replace(R.id.container, new VolumeFormulas())
.commit();
break;
case 11:
fragmentManager.beginTransaction()
.replace(R.id.container, new TrigonometryGraphsFormulas())
.commit();
break;
case 12:
fragmentManager.beginTransaction()
.replace(R.id.container, new HyperbolicIdentities())
.commit();
break;
case 13:
fragmentManager.beginTransaction()
.replace(R.id.container, new TrigonometricIdentities())
.commit();
break;
case 16:
fragmentManager.beginTransaction()
.replace(R.id.container, new IntegralIdentities())
.commit();
break;
case 17:
fragmentManager.beginTransaction()
.replace(R.id.container, new IntegralSpecialFunctions())
.commit();
break;
case 18:
fragmentManager.beginTransaction()
.replace(R.id.container, new TableOfIntegrals())
.commit();
break;
case 20:
fragmentManager.beginTransaction()
.replace(R.id.container, new DerivativeIdentities())
.commit();
break;
case 21:
fragmentManager.beginTransaction()
.replace(R.id.container, new TableOfDerivatives())
.commit();
break;
default:
fragmentManager.beginTransaction()
.replace(R.id.container, new DefaultLayout())
.commit();
break;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_about) {
About about = new About();
about.show(getFragmentManager(), "about");
}
return false;
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
}
}
这是日志:
02-19 06:41:24.849 9788-9788/l.pocketformulas E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.IllegalStateException: Fragment Logarithms{4132f5d0} not attached to Activity
at android.app.Fragment.getResources(Fragment.java:828)
at l.pocketformulas.Logarithms$1.onPageFinished(Logarithms.java:71)
at android.webkit.CallbackProxy.handleMessage(CallbackProxy.java:444)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:155)
at android.app.ActivityThread.main(ActivityThread.java:5520)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1029)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:796)
at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:4)
在AndroidMenifest.xml
中使用此功能<activity
android:name="MyActivity"
android:configChanges="orientation|keyboard|keyboardHidden"
android:screenOrientation="sensor" />
Android会在默认情况下更改方向时重新启动活动。
在Android销毁活动之前,您需要通过调用onSaveInstanceState()
来保存您的数据/状态。
您可以通过android:configChanges="orientation"
将活动AndroidManifest file
添加到您的活动中来阻止这种情况。
<强>更新强>
当发生配置更改时,旧的Fragment不会被销毁 - 它会在重新创建时将其自身添加回Activity。 您可以通过使用相同的片段来停止发生的错误,而不是重新创建新的片段。只需添加以下代码:
if(savedInstanceState == null)
{
mFragmentManager = getFragmentManager(); // **update**
FragmentTransaction ft= mFragmentManager.beginTransaction();
MyFragment fragment = new MyFragment();
ft.add(R.id.container, fragment);
ft.commit();
}
请注意:如果您尝试从Fragment内部访问活动视图,则会出现问题,因为生命周期将会微妙地改变。 (从片段中获取父活动的视图并不容易)。
答案 1 :(得分:1)
在主要活动的OnCreate()
方法中使用此代码:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
或者您也可以在Orientation
中设置manifest.xml
,如:
<activity
android:name="com.example.fragment.AppMainTabActivity"
android:configChanges="keyboardHidden|orientation"
android:screenOrientation="portrait"
android:theme="@style/AppTheme"
android:windowSoftInputMode="adjustPan" >
</activity>
现在您的方向将设为纵向,永远不会改变。
<强>更新强>
@Override
protected void onSaveInstanceState(Bundle outState) {
webView.saveState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
}
现在,您的onCreate()
工具如下:
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.blah);
if (savedInstanceState != null)
((WebView)findViewById(R.id.webview)).restoreState(savedInstanceState);
}
这些方法可以在任何活动上被覆盖,它基本上允许您在每次创建/销毁活动时保存和恢复值,当屏幕方向改变时活动被销毁并在后台重新创建,因此您可以使用这些方法在更改期间临时存储/恢复状态。
答案 2 :(得分:1)
我确实通过在“ AndroidManifest.xml”上进行了简单配置解决了这个问题:
<activity android:name=".MainActivity" android:configChanges="orientation|screenSize|screenLayout|keyboardHidden">
答案 3 :(得分:0)
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
答案 4 :(得分:0)
根据您的设备,您可能需要在configChange中包含“屏幕尺寸”。否则你的活动将重新启动。
像这样:<activity
android:name="MyActivity"
android:configChanges="orientation|keyboard|keyboardHidden|screenSize"
android:screenOrientation="sensor" />