I am tring to handle rotation for complex view manually, including restoring the propper position and size. At this moment i am trying to do it in onLayout
(better ideas are velcome). Sometimes it works good, but often first rotation is misplaces or view is drawn without childs.
private int oldOrientation = -1;
/**
* Override method to configure the dragged view and secondView layout properly.
*/
@Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
Log.e("mylayout", "onLayout " + df.format(new Date(Calendar.getInstance().getTimeInMillis())));
if (isInEditMode()) {
super.onLayout(changed, left, top, right, bottom);
} else {
dragView.setVisibility(INVISIBLE);
if (isDragViewAtTop() && (oldOrientation != getResources().getConfiguration().orientation || oldOrientation == -1)) {
dragView.layout(left, top, right, transformer.getOriginalHeight());
secondView.layout(left, transformer.getOriginalHeight(), right, bottom);
ViewHelper.setY(dragView, top);
ViewHelper.setY(secondView, transformer.getOriginalHeight());
ViewHelper.setX(dragView, left);
ViewHelper.setX(secondView, left);
oldOrientation = getResources().getConfiguration().orientation;
} else if (isClosedAtLeft() && (
oldOrientation != getResources().getConfiguration().orientation
|| oldOrientation == -1)) {
dragView.layout(left, top, right, transformer.getOriginalHeight());
secondView.layout(left, transformer.getOriginalHeight(), right, bottom);
ViewHelper.setY(dragView, top);
ViewHelper.setY(secondView, transformer.getOriginalHeight());
ViewHelper.setX(dragView, left);
ViewHelper.setX(secondView, left);
closeToLeft();
oldOrientation = getResources().getConfiguration().orientation;
} else if (isClosedAtRight() && (
oldOrientation != getResources().getConfiguration().orientation
|| oldOrientation == -1)) {
dragView.layout(left, top, right, transformer.getOriginalHeight());
secondView.layout(left, transformer.getOriginalHeight(), right, bottom);
ViewHelper.setY(dragView, top);
ViewHelper.setY(secondView, transformer.getOriginalHeight());
ViewHelper.setX(dragView, left);
ViewHelper.setX(secondView, left);
closeToRight();
oldOrientation = getResources().getConfiguration().orientation;
} else if ((oldOrientation != getResources().getConfiguration().orientation
|| oldOrientation == -1)) {
dragView.layout(left, top, right, transformer.getOriginalHeight());
secondView.layout(left, transformer.getOriginalHeight(), right, bottom);
ViewHelper.setY(dragView, top);
ViewHelper.setY(secondView, transformer.getOriginalHeight());
ViewHelper.setX(dragView, left);
ViewHelper.setX(secondView, left);
smoothSlideTo(SLIDE_BOTTOM);
oldOrientation = getResources().getConfiguration().orientation;
}
dragView.setVisibility(VISIBLE);
}
}
In this code, i try to restore initial stte after rotation, when onLayout is called and then move it to place, the view was before rotation (there are 4 states, out of creen to left, out of screen to right, top of scren or bottom right corner).
Edit:
<?xml version="1.0" encoding="utf-8"?>
<manifest
package="com.github.pedrovgs.sample"
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-sdk android:minSdkVersion="8" />
<!-- Permissions -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<!-- Application configuration -->
<application
android:name=".DraggablePanelApplication"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<!-- Maps API KEY -->
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="AIzaSyC1rMU-mkhoyTvBIdTnYU0dss0tU9vtK48" />
<!-- Main Activity -->
<activity
android:name=".activity.MainActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Places sample -->
<activity
android:name=".activity.PlacesSampleActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/places_sample_activity_title" />
<!-- TV Shows sample -->
<activity
android:name=".activity.TvShowsActivity"
android:label="@string/tv_shows_sample_activity_title" />
<!-- Youtube Sample -->
<activity
android:name=".activity.YoutubeSampleActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/youtube_sample_activity_title" />
<!-- Video Sample -->
<activity
android:name=".activity.VideoSampleActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/video_sample_activity_title" />
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
</application>
</manifest>
sample activity xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:draggable_panel="http://schemas.android.com/apk/res-auto"
android:id="@+id/fl_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Movie Thumbnail -->
<ImageView
android:id="@+id/iv_thumbnail"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
style="@style/image_view"/>
<!-- DraggablePanel -->
<com.github.pedrovgs.DraggablePanel
android:id="@+id/draggable_panel"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
draggable_panel:x_scale_factor="@dimen/x_scale_factor"
draggable_panel:y_scale_factor="@dimen/y_scale_factor"
draggable_panel:top_fragment_height="@dimen/top_fragment_height"
draggable_panel:top_fragment_margin_right="@dimen/top_fragment_margin"
draggable_panel:top_fragment_margin_bottom="@dimen/top_fragment_margin"
draggable_panel:enable_horizontal_alpha_effect="false"/>
</FrameLayout>
If you are trying to go deep in Laying out your View
s you do not need this for your View
's Activity
android:configChanges="keyboardHidden|orientation|screenSize"
if that is set after rotation, android care less of whether to recreate your Activity
hence re-drawing,-re-measuring,-re-positioning re-etc-etc.
so if you start your app with an ImageView
placement [10 100] after rotation boy your ImageView
will be assumed to be placed [10 100] sometimes it might even give you weird offscreen co-ordinates.
You have extended a ViewGroup
instead of a View
and yet haven't added any child
to the DraggableView
in the xml or in the code. I don't see any addChild
or any child related code in DraggableView
. You have used topFragment
, bottomFragment
, etc.. and you used addFragmentToView()
to make fragment transaction inside the ViewGroup
. Bad idea!
I know it's hard and time consuming. But you need to step back and think about the Design of this view. I would strongly suggest you treat these topFragment
,etc.. as children to the DraggableView
, and not have a FragmentManager
inside this View and perform addTransaction
.
Once you start adding the fragments as children to your ViewGroup
, lot of complications will just go away. I say this from my past experience. onLayout()
is used to arrange the Child Views
inside the ViewGroup
. Once you rotate the device, onLayout()
will again be called and will arrange the child views as you want. It would be very simple. Dragging operation will be made much simple once you start conceptualizing like this.
If you think having Framgents
as child in the ViewGroup
is absurd, kindly look at the ViewPager
code here. This uses fragments as input but still treat them as children to the layout.
onLayout()
itself.onSaveInstanceState()
. Save only the text
or drawable
data in this.onCofigurationChanged()
.You may not be able to do this now, but in the longer run, you might want to refactor and do it this way.
Remember the true purpose of onLayout()
:
Called from layout when this view should assign a size and position to each of its children. Derived classes with children should override this method and call layout on each of their children.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With