EditText content get jiberrish and overlaps previous content on orientation change - android

I am using an EditText under the Material Design and I am having problems in screen orientation. I was able to save the content onSavedInstanceState and reinstate back what was written on edittext back again but there seems to be a bug-like behavior going on.
Look at these following pics:
Original orientation when activity start:
When I rotate the screen, I still get a hold of the content but when I place the carret on an existing text span, it returns the carret to 0 (Beginning of edit text) and then when I typed something it looks like this:
I encountered this situation once and that was very long time ago. IIRC I was able to solve it by completely replacing the content onCreateView's savedInstanceState, it doesn't seem to work anymore.
Any ideas?
[EDIT]
A lot of people will be expecting to answer "ONCONFIGURATIONCHANGED". No please, this is not merely the solution for the underlying problem. In fact, I tried it and didn't work, don't want to implement that solution anyways. I believe this doesn't warrant band aid solution, at least as a last resort.
Read the answer to this: Why not use always android:configChanges=“keyboardHidden|orientation”?
Here is my layout file for the 'Fragment' containing the edit text:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical"
tools:context=".HomeScreenActivity"
android:weightSum="1">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar_note"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsingtoolbarlayout_note"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:expandedTitleMarginStart="48dp"
app:expandedTitleMarginEnd="64dp">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar_note"
android:layout_width="match_parent"
android:layout_height="?attr/colorPrimary"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
app:layout_collapseMode="pin">
....
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:fillViewport="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="#+id/edittext_note"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="6"
android:gravity="top"
android:freezesText="true"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="16dp" />
<include
layout="#layout/layout_rte_toolbar_black_icon"
android:layout_width="match_parent"
android:layout_height="0dp"
android:gravity="bottom"
android:layout_weight="0.60"/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
Next here is my Activity layout, a very simple layout actually:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/framelayout_note"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Here is create method callback for Activity:
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Log.i("NoteActivity.OnCreate" , TAG);
setContentView(R.layout.activity_note);
NoteFragment fragment = NoteFragment.createInstance();
fragment.setOnToolbarButtonSelected(this);
getSupportFragmentManager()
.beginTransaction()
.add(R.id.framelayout_note , fragment)
.commit();
}
Here is the create/onSavedInstanceState method callback for the fragment
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Log.i("NoteFragment.onCreateView", TAG);
if(savedInstanceState != null)
{
mTitle = savedInstanceState.getString(KEY_EDITTEXT_TITLE, TAG);
mContent = Html.fromHtml(savedInstanceState.getString(KEY_EDITTEXT_CONTENT, TAG));
}
mNoteDataController = ((NotifireApplication) getActivity().getApplication()).getNoteDataController();
setHasOptionsMenu(true);
setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater , ViewGroup parent, Bundle savedInstanceState)
{
Log.i("NoteFragment.onCreateView", TAG);
View view = inflater.inflate(R.layout.fragment_note, parent, false);
mNoteContent = (EditText) view.findViewById(R.id.edittext_note);
mNoteTitle = (EditText) view.findViewById(R.id.edittext_note_title);
if(mContent != null) mNoteContent.setText(mContent);
if(mTitle != null) mNoteTitle.setText(mTitle);
initToolbar(view);
return view;
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState)
{
Html.toHtml(mNoteContent.getText());
savedInstanceState.putString(KEY_EDITTEXT_CONTENT, Html.toHtml(mNoteContent.getText()));
savedInstanceState.putString(KEY_EDITTEXT_TITLE, mNoteTitle.getText().toString());
super.onSaveInstanceState(savedInstanceState);
}

Got the problem. Actually All this work that you have done in fragment should have been done in activity. In this scenario since you are using frame layout, I think what is happening is that your old fragment is in place and once you rotate the device a new instance of fragment gets created and placed above it.
In my opinion this is the reason why your older text is there which is actually in your previous fragment. My opinion is either handle onConfiguration change and don't create new fragment on orientation change.
Second if you want to test what I'm saying is you can use linearlayout with vertical orientation and you will see that there are two fragments.

When the screen orientation changes, two instances of NoteFragment are being created and added to the container view. This is your root problem. One NoteFragment is being created and added by FragmentActivity#onCreate. Another NoteFragment is being created in the onCreate callback of your activity which subclasses FragmentActivity.
You can fix this by checking whether savedInstanceState is null before adding your fragment in onCreate. If savedInstanceState is null, then add your fragment. If not, then the activity is being re-created after a configuration change and the logic of FragmentActivity will restore fragments fro you, so do nothing.

In the onConfigurationChanged() First Get the data of your Edit text into a global variable and then call setContentView() and now set the Data into your Edit text.
This should work.

Related

Add nested fragments in Parent fragment from activity

I have an SchoolActivity that has two buttons:
-Primary (adds the PrimaryFragment)
-Secondary (adds the SecondaryFragment)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.yuv.mycollege.MainActivity">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="#+id/button_primary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Primary"/>
<Button
android:id="#+id/button_secondary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Secondary"/>
</LinearLayout>
<!-- Main content area for fragments-->
<FrameLayout
android:background="#color/colorPrimary"
android:id="#+id/main_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:padding="4dp"/>
</LinearLayout>
Both the fragments has content and footer area, which are themselves are fragments (PrimaryContentFragment, PrimaryFooterFragment, SecondaryContentFragment, SecondaryFooterFragment)
I am adding the fragments from the activity using:
public void onClick(View view) {
Button button = (Button)view;
Toast.makeText(this, "Going to Add Children", Toast.LENGTH_SHORT).show();
switch(view.getId()) {
case R.id.button_primary:
getSupportFragmentManager().beginTransaction()
.replace(R.id.main_container, new PrimaryFragment())
.addToBackStack("primary")
.commit();
break;
case R.id.button_secondary:
getSupportFragmentManager().beginTransaction()
.replace(R.id.main_container, new SecondaryFragment())
.addToBackStack("secondary")
.commit();
break;
}
}
And, finally adding the each children fragments using:
The layout file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/content_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#color/colorAccent"
android:layout_weight="8"
></FrameLayout>
<FrameLayout
android:id="#+id/footer_container"
android:background="#color/colorPrimaryDark"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
></FrameLayout>
</LinearLayout>
The children fragments adding:
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.primary_fragment, container, false);
getChildFragmentManager()
.beginTransaction()
.add(R.id.content_container, new PrimaryContentFragment())
.add(R.id.footer_container, new PrimaryFooterFragment())
.addToBackStack("primarychildren")
.commit();
return view;
}
I am adding the similar logics for the another fragment also and so on for the rest which is working.
THE PROBLEM:
The solution as stated is working but seems as very raw naive approach. Could anybody suggest the better architecture I could follow such as:
all the fragments (Primary/Secondary/...) uses the same designs so
can I create some base class to inherit common features
all the footer are similar for all of fragments but with simple text change
(might be like breadcrumb) So, Can I use same footer for all
fragments with some settext method ...
how can I effectively communicate between activity and fragments
BEING A NEW ANDROID DEV, MY ONLY CONCERN IS AM I DOING THE RIGHT WAY !!!
Try this using bundle :-
ContentFragment content=new ContentFragment();
content.setArguments( ( new Bundle()).putString("value","primary"));
getChildFragmentManager()
.beginTransaction()
.add(R.id.content_container, content)
.add(R.id.footer_container, new PrimaryFooterFragment())
.addToBackStack("primarychildren")
.commit();
Similarly For secondary use :-
ContentFragment content=new ContentFragment();
content.setArguments( ( new Bundle()).putString("value","secondary"));
Use same content and footer fragments just set the texts by using bundle arguments
All the fragments (Primary/Secondary/...) uses the same designs so can
I create some base class to inherit common features
If they are using the same design and with slight changes in their content, then there's no need of create different Fragment classes. You can just pass necessary values from your calling Activity or Fragment to populate the contents in each of your child fragments.
All the footer are similar for all of fragments but with simple text
change (might be like breadcrumb) So, Can I use same footer for all
fragments with some settext method ...
If they are just simple text changes, then please use the setArguments and getArguments methods to pass values between Fragments rather creating different Fragment classes.
Here's how you can pass values between fragments. And here's how you can pass data from your Activity to Fragment.
How can I effectively communicate between activity and fragments
Please follow the two links above to communicate between Activity and Fragment.
Update
Following up the comment, as you have said that the PrimaryFragment and SecondaryFragment are mostly likely, I would suggest you to have one single Fragment having all these. Instead of having PrimaryFragment, SecondaryFragment and a CommonFragment, you might consider a single Fragment having the footer Fragment as well. When you are about to launch an instance of that Fragment, just pass necessary values to populate data as the contents of those Fragment.
Please let me know if I have not clarified enough.

How to Using inflater to get a list view from fragment in Android Studio

I am trying to get a list view id from another xml file (fragment_friends.xml) while i am in activity_main.xml layout. I tried 2 ways, but they are not working properly.
Below code will cause the app to crash straight away because i am trying to get an id that does not exist in this layout (activity_main)
Original code
ListView friendList = (ListView) findViewById(R.id.friend_listView);
friendList.setAdapter(friendAdaptor);
Below code works, but i wont be able to insert or display any data into my database.
Try 1 code:
View inflatedView = getLayoutInflater().inflate(R.layout.fragment_friend, null);
ListView friendList = (ListView) inflatedView.findViewById(R.id.friend_listView);
friendList.setAdapter(friendAdaptor);
Below code the database and listView works, but my navbar drawer is gone and i when i try to get back to activity_main, app crashes
Try 2 code
setContentView(R.layout.fragment_friend);
ListView friendList = (ListView) inflatedView.findViewById(R.id.friend_listView);
friendList.setAdapter(friendAdaptor);
app_bar_main.xml
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<!--<include layout="#layout/content_main" />-->
<FrameLayout
android:id="#+id/flContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"/>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
app:srcCompat="#android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
I believe the root of your problem comes down to a lack of familiarity with the general Android Fragment APIs. That's fine; everyone is new when they start. But it means that your question is quite difficult to answer concisely (beyond "read about Fragments").
You should, of course, start by reading about Fragments: https://developer.android.com/guide/components/fragments.html
Still, I think we can cover things here in brief.
All Fragments must be hosted in an Activity. The normal way to do this is either by adding a <fragment> tag to your activity's xml layout, or by including a <FrameLayout> in your activity's xml layout and then using a FragmentTransaction to dynamically add/replace/remove fragments from that frame.
In your posted code, inside app_bar_main.xml, I see this:
<FrameLayout
android:id="#+id/flContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"/>
This is clearly the place where your fragments will eventually live, but you'll have to add them to the frame yourself in your Java code. You actually have a method that does this already:
private void displaySelectedScreen(int id){
Fragment fragment = ...
if(fragment != null){
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.flContent, fragment);
ft.commit();
}
...
}
It looks like this is meant to be used when your user clicks on an item in your navigation drawer, but the concept is the same. If you want your app to always start up with the "friends" fragment displayed, you can add this code to your activity's onCreate() method:
if (savedInstanceState == null) {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.flContent, new friend())
.commit();
}
Now you will have a friend fragment to work with!
However, fragment transactions aren't guaranteed to be executed right away, so even though (as a user) you'll always see this friend fragment when the app starts up, you won't necessarily be able to interact with it (as a programmer) immediately after writing this code. So you'll also have to move your call to populateFriendList() from your onCreate() method.
Instead, you should populate the friends list from within the friend fragment itself! Probably the right place to do this is inside the onActivityCreated() method of your fragment.
To find a view from inside a Fragment subclass, you can't just write findViewById() the way you can in an Activity. However, you can write this instead: getView().findViewById()... as long as you're doing this after your onCreateView() method has returned.
Anyway, this answer is getting extremely long even as I try to keep it as short as possible. I hope this is enough information for you to get your app up and running. Good luck.

Android. Fragment stays in activity after screen rotation issue

I have a two variants of activity_main.xml (for portrait/landscape orientation). In this activity, user can choose items and browse detailed information about selected item.
In portraint orientation, fragments added to flFragmentContainer dynamically, after item choosing, details fragment replaces list fragment:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/flFragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"></FrameLayout>
</LinearLayout>
In landscape orientation, fragments described in XML file statically:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<fragment
android:id="#+id/frgTaskList"
android:name="com.exprod.xchecklist.fragments.TaskListFragment"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
tools:layout="#layout/fragment_task_list" />
<fragment
android:id="#+id/frgTaskDetails"
android:name="com.exprod.xchecklist.fragments.TaskDetailsFragment"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
tools:layout="#layout/fragment_task_details">
</fragment>
</LinearLayout>
</LinearLayout>
Here is the code of onCreate() method (of MainActivity).
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fragmentManager = getSupportFragmentManager();
TaskDetailsFragment taskDetailsFragment = (TaskDetailsFragment)fragmentManager.findFragmentById(R.id.frgTaskDetails);
isDynamicMode = taskDetailsFragment == null || !taskDetailsFragment.isInLayout();
if(isDynamicMode){
FragmentTransaction transaction = fragmentManager.beginTransaction();
Fragment taskListFragment = new TaskListFragment();
if (savedInstanceState == null) {
transaction.add(R.id.flFragmentContainer, taskListFragment, TaskListFragment.FRAGMENT_TAG);
}else{
transaction.replace(R.id.flFragmentContainer, taskListFragment, TaskListFragment.FRAGMENT_TAG);
}
transaction.commit();
}
}
PROBLEM: When I rotate device to landscape orientation, I get twice calls of creation methods in first fragment (TaskListFragment) (onCreateView(), onActivityCreated(), ... ). This indicates that the old fragment remains in activity and recreated on orientation change.
How I can finally destroy old fragment?? I did not find the answer on the Internet.
P.S: Sorry for my bad English...
I see at least two approaches to do what you want.
Handle orientation change yourself:
As described in this document, you can prevent automatic Activity destroy and re-creation and handle orientation change yourself. In this case, you would remove the old Fragment before inflating a new layout into Activity.
Remove the old Fragment after Activity re-creation:
You could also add some logic that determines the orientation as described here (or use your current heuristic that sets isDynamicMode), and manually remove the unnecessary Fragments during onCreate().
The better way:
Although it is possible to do what you want, I can't undertand why would you like to do it this way - you use TaskListFragment in both portrait and landscape configurations, therefore the most logical thing to do is to reuse it. Except for simplifying things, it will also let you keep the state of that Fragment on orientation change (which, I believe, is desirable in your case).
Thanks for Vasiliy answer. I follow this link
and add
android:configChanges="oritentation"
to my manifest file:
<activity android:name=".MyActivity"
android:configChanges="orientation"
android:label="#string/app_name">
and the annoying behavior (fragment not attached to activity) when screen is rotated disappears
Just add to your activity
#Override
public void onSaveInstanceState(Bundle outState) {}
because implementation of this method in Android's Activity that is a parent of all Activities, saved Fragment.

Save State of WebView when fragment containing the webview is replaced

I am using webview to create a basic web browser,
Currently I have one activity and multiple fragments :
-- Browser
-- something else
-- Something else
in Browser Fragment I have the webview :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".fragments.BrowserFragment">
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipe_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="#+id/webview_holder"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true">
<include
android:id="#+id/button_layout"
layout="#layout/bottom_btn_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"/>
<LinearLayout
android:id="#+id/web_page_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#id/button_layout"
android:orientation="vertical">
</LinearLayout>
<WebView
android:id="#+id/web_page"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#id/button_layout"/>
</RelativeLayout>
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
I am able to save the state of the webview on screen rotation , by using
#Override
public void onSaveInstanceState(Bundle outState) {
if(mWebView != null){
mWebView.saveState(outState);
}
super.onSaveInstanceState(outState);
}
and calling this OnActivityCreated :
mWebView = (WebView)getActivity().findViewById(R.id.web_page);
if (savedInstanceState != null){
mWebView.restoreState(savedInstanceState);
}else{
mWebView.loadUrl(makeUrl(url));
}
This works fine when screen rotates and activity is recreated.
But when I use navigation drawer and replace fragment in the same container and then try to come back to same fragment . The state of webview is lost.
I get the point that onSaveInstanceState() is not called when there is Fragment transaction. So I tried saving the webView state by calling onSaveInstanceState() from OnPause of the fragment. But in that case I get savedInstanceState as null in OnCreateView so I am not able to restore state.
I need to maintain state of multiple webviews and comeBack to them on click of a list.
I also tried saving webview, when onSave() is called in fragment, in a static HashMap in activity and try to assign it to webview of newFragment. But I get Blank screen in that case.
Could someone give me pointers how I can approach this.

Fragments not visible on orientation change

In the following code, the fragments are being dynamically inflated from a layout xml. The issue i am facing is that I dont see the fragments when i rotate the device.
If I look at the fragmentManager, I do see fragments are there. They are added and attached, but no where on the screen.
MenuCard extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content);
leftContainer = (FrameLayout) findViewById(R.id.leftContainer);
rightContainer = (FrameLayout) findViewById(R.id.rightContainer);
Fragment fragment = mFragmentManager.findFragmentById(R.id.leftFragment);
if (fragment == null) {
LayoutInflater.from(this).inflate(R.layout.left_fragment, leftContainer);
}
fragment = mFragmentManager.findFragmentById(R.id.rightFragment);
if (fragment == null) {
LayoutInflater.from(this).inflate(R.layout.right_fragment, rightContainer);
}
}
}
}
}
R.layout.left_fragment
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/leftFragment"
android:name="com.example.LeftFragment"
tools:layout="#layout/left_fragment">
</fragment>
R.layout.right_fragment
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/rightFragment"
android:name="com.example.LeftFragment"
tools:layout="#layout/left_fragment">
</fragment>
Adding the code for R.layout.content
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SlidingPaneLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/spl"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/leftContainer"
android:layout_width="320dp"
android:layout_height="match_parent"
android:background="#00AFF0"
/>
<FrameLayout
android:id="#+id/rightContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</android.support.v4.widget.SlidingPaneLayout>
you can try to add following lines in your manifest inside fragment Activity's declaration:
android:configChanges="screenSize|orientation"
This will prevent onCreate on screen orientation change.For handling of orientation change, you can override onConfigurationChanges.
So after a lot of reading of the fragment manager code i came across these magical lines:
// For fragments that are created from a layout, when restoring from
// state we don't want to allow them to be created until they are
// being reloaded from the layout.
which means the correct code for my case is
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content);
leftContainer = (FrameLayout) findViewById(R.id.leftContainer);
rightContainer = (FrameLayout) findViewById(R.id.rightContainer);
LayoutInflater.from(this).inflate(R.layout.left_fragment, leftContainer);
LayoutInflater.from(this).inflate(R.layout.right_fragment, rightContainer);
}
}
SupportFragmentManager will reuse the fragments in case of orientation change and only inflate the layouts.
I never tried your design but I find it interesting. Although I don't recommend it.
The UI is not recreated because orientation is changed. This is because Activity is not recreated, hence onCreate is not triggered when orientation is changed. When the screen is changed due to different factors, onCreateView is triggered. This I never tried in the Activity subclass. It is normally done in a Fragment subclass. Actually, onCreate is only triggered when the App is stopped due to user action or a crash.
If/when I find a good sample of onCreateView method in Activity, I'll post it.

Categories

Resources