Issue
I have the following 2 values folders under my project resources :
- This is my
dimens.xml
forportrait
display of a 320dp width screen :
- This is my
dimens.xml
forlandscape
display of a 320dp width screen :
What I'm getting is a correct display at the application start (for the landscape display as well as the portrait display) :
- Application starts in portrait mode correctly :
- Application starts in landscape mode correctly :
Now my problem is when I rotate the screen during application runtime (say that the application first started in portrait mode), the application doesn't seem to retrieve values from the correct values folders which is supposed to be "values-w320dp-land
" :
And vice-versa, if I rotate the screen after I started the application in ladscape mode, the application doesn't seem to retrieve values from the correct values folders which is supposed to be "values-w320dp-port
", and I get this :
UPDATE 1
This is the activity declaration in AndroidManifest.xml
:
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:name=".utils.json.VolleyApplication" >
<activity
android:name="com.test.momo.CategoriesActivity"
android:label="@string/app_name"
android:configChanges="orientation|screenSize" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<!--Monitor for Changes in Connectivity-->
<!--<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>-->
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
And this is my GridView declaration in the activity layout :
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gridview_categories"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:columnWidth="@dimen/gridview_row_item_size"
android:numColumns="@integer/num_columns"
android:verticalSpacing="@dimen/gridview_row_item_spacing"
android:horizontalSpacing="@dimen/gridview_row_item_spacing"
android:stretchMode="none"
android:layout_marginLeft="@dimen/gridview_row_item_spacing"
android:layout_marginRight="@dimen/gridview_row_item_spacing"
android:scrollbars="none"/>
UPDATE 2
So I finally got very close to the solution. Now when I rotate my screen at runtime, my GridView adjusts itself to the portrait ot landscape mode correctly after I did some changes on the code of the activity here :
@Override
public void onResume() {
super.onResume();
gridView.setNumColumns(getResources().getInteger(R.integer.num_columns));
gridView.setColumnWidth(getResources().getDimensionPixelSize(R.dimen.gridview_row_item_size));
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
gridView.setNumColumns(getResources().getInteger(R.integer.num_columns));
gridView.setColumnWidth(getResources().getDimensionPixelSize(R.dimen.gridview_row_item_size));
}
Except that, this is what I get when (and only when) I rotate screen from portrait to landscape at runtime :
As you can see, the first element of my GridView seems to preserve its height and width values of portrait mode. While the rest of the GridView elements display correctly.
What am I missing here?
Solution
When you specify android:configChanges
in your manifest, the activity will receive a onConfigurationChanged
callback. An implementation could look as follows:
@Override
public void onConfigurationChanged(Configuration newConfig) {
// Absolutely detach any adapters from lists.
// RecyclerView adapters have caches that need to be cleared.
// We can reuse adapter but not widgets.
mList.setAdapter(null);
// Inflate new view hierarchy.
setContentView(R.layout.the_same_layout_as_in_on_create);
// Update variables so they point to newly inflated widgets
ButterKnife.bind(this); // update variables to point
// Reattach adapters
mList.setAdapter(mAdapter);
// Here follows everything else that touches widgets in onCreate...
}
Please note that if I changed language on my phone the activity would still do a full restart since it's not in android:configChanges
.
Also note that when using this approach the activity does not follow the lifecycle onPause-onStop-onDestroy-onCreate-onStart-onResume.
My advice is learn how to properly save state and fragments and just recreate the whole activity. The most expensive operation is inflating layout and you have to do that anyway.
Answered By - Eugen Pechanec
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.