I have a problem when I rotate my device, my activity is re-executed and the values change.For example, suppose that you have an activity with a button, when this button is clicked, it will show the increased value in a text view (a counter). And when you put your device in landscape mode, the activity will run again, and you will see (again) the value increased. My question is, is there a way to not run the activity again when you rotate the device ?
Please read this. You will see that there are two solutions for handling configuration changes:
You can declare that you are handling the change on your own by updating activity in the manifest. This way your activity will not be restarted and onConfigurationChanged() will be called:
<activity ...
android:configChanges="orientation|screenSize"
...>
You can pass your data objects to the new activity via onSaveInstanceState() function. Passing large objects can slow down the app. It is better you separate data from the view for example by using ViewModels, which are retained in these kind of changes.
First way may seem easy, but it is not recommended as you can see in the link provided at the beginning:
Caution: Handling the configuration change yourself can make it much
more difficult to use alternative resources, because the system does
not automatically apply them for you. This technique should be
considered a last resort when you must avoid restarts due to a
configuration change and is not recommended for most applications.
Add android:configChanges in your activity
<activity name= ".YourActivity" android:configChanges="orientation|screenSize"/>
In the manifest file add android:configChanges = "orientation|screenSize"
to the activity tag.
For ex:
<activity
android:name=".dummyActivity"
android:configChanges = "orientation|screenSize"/>
If you want to handle orientation changes manually you can do so by overriding the onConfigurationChanged() method in Activity.
For more info refer Handling Configuration Changes
add this to the manifest
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
If configChanges contains uiMode, remove it. If you don't want to uninstall uiMode, you can update these libraries.
androidx.appcompat:appcompat:1.2.0-rc01
androidx.core:core:1.3.2
Related
So I have this activity that creates 4 fragments for me, which are a bottom navigation bar.
when I change to dark mode or light mode, the fragments reset and take me back to the "main fragment" which is basically home in the bottom navigation bar.
so my question is how do I stay in the tab I was in while changing UI mode? while of course changing the UI mode of the fragments as well
The best aproach is to let activity recreate itself with its fragments, some configuration changes might be required to show correct UI. And its always possible that your user will move your app to the background, system will kill it after a while and then when your user will go back to it - you will be back with your problem of recreation. I am talking about it to prevent you from using hacks like configChanges in androidmanifest which prevent Activity recreation on configuration change event.
But back to the main point:
when configuration change destroys your Activity, fragments will be automatically recreated when new instance of Activity will be created. But its up to you to save some of its state. I am not sure how your UI and code looks like. The very basic way to save and restore state (like active tab in your question) is to use: Activity.onSaveInstanceState(Bundle) / Activity.onCreate(savedInstanceState: Bundle?) and Fragment.onSaveInstanceState(Bundle)/Fragment.onCreate(savedInstanceState: Bundle?) mechanism. You save relevant variables in bundles in onSaveInstanceState, and later in onCreate restore this state using savedInstanceState variable, but only if its non null - which happens when Activity is created for the first time.
This is a broad topic, you can find more on this here:
https://developer.android.com/topic/libraries/architecture/saving-states
https://developer.android.com/guide/fragments/saving-state
I have two seperate xml file for potrait and landscape view of an activity, but when I rotate my phone xml file changes but activity restarts. How can I change layout file without restarting activity.
The better approach to this would be to use a ViewModel with your activity so that even if it gets destroyed, your data will persist in the ViewModel and can be reloaded once the view is created in the landscape orientation.
However, if you still wish to handle the layout change without restarting the activity, you will need to do the following changes
Set the android:configChanges flag in your AndroidManifest to orientation
<activity
android:name="com.example.MainActivity"
android:configChanges="orientation"/>
Override the onConfigurationChanged method in your activity and load the new view. This part is a little tricky as you will have to discard the previous view before you inflate the new one. One approach would be to have a container in your activity and you can load two fragments in it, one for portrait and one for landscape orientation.
For more information, you can read this documentation
Keep in mind that while this will work, using the android:configChanges attribute is not recommended
I'm relatively new to Android but have made quite a few apps over the past year so forgive me.
I know that when you are running an app on a device and change the screen orientation by turning the device the activity that is showing is completely recreated. I go to the youtube app (I am using Nexus 7 w/ Android 4.2.2) and play some video and then flip the screen to change orientation. The video keeps playing and everything is re-sized accordingly... How is this possible if the activity is completely recreated?
Thank you.
In your AndroidManifest.xml add, android:configChanges and this would avoid the activity being re-created on orientation change. I hope your landscape and portrait mode has the same layout.
<activity android:label="Your Activity Name"
android:configChanges="keyboardHidden|orientation|screenSize"
android:name="com.yourpackage">
To add more to this, i would suggest you to look at the onPause() and onResume() methods and if you are playing with Fragments then have a watch on onSaveInstanceState and onRetainInstanceState rather than applying the xml changes as "Activity is destroyed by design."
http://developer.android.com/training/basics/activity-lifecycle/index.html
If you are worried about losing the value of local variables within your activity... You could use Singleton Pattern for some of those variables. This not a beautiful solution, but could work.
I have another question!
I have a configure Activity in my app. On it, I have a ListView. Now adding & removing items to & from it works, but when I rotate the screen to landscape or back, all added & non-saved items in the ListView get removed... I wonder why this is... Why is this?
When screen orientation changes, by default, the activity will be destroyed and create again. That means, the onCreate will be called again once the orientation changed. There are basically two way to solve your problem:
Save your activity state before destory and load it back when create
Set the Activity in AndroidManifest that not to handle screen orientation change.
E.g.
<activity name="..."
android:configChanges="orientation" .../>
When you rotate the handset, the onStart method of you Activity is invoked. Check maybe you do some sort of initialization there.
I've solved it partially. Now it is able to hold on to the changes when changing to landscape view, but not the other way back to the normal view. I did it through the use of protected void onSaveInstanceState(Bundle saveState). But as I said, this doesn't work when it changes back from Landscape... Anybody got any ideas about this?
When you long press on something in Android, a context menu comes up. I want to add something to this context menu for all TextViews in the system.
For example, the system does this with Copy and Paste. I would want to add my own, and have it appear in every application.
Currently Android does not support this, you cannot override or hook functionality globally at the system level without the particular activity implementing an intent or activity that you expose. Even in the case of publishing an intent it wouldn't matter unless the application running is a consumer... and all the base system applications and obviously all applications prior to yours would not be without updating the app to consume.
Basically as it stands, this is not possible.
What exactly are you trying to accomplish with this global context menu, some sort of global "Search For" or "Send To" functionality that runs through your application?
Add intent-filter in your file android-manifest.xml:
<activity
android:name=".ProcessTextActivity"
android:label="#string/process_text_action_name">
<intent-filter>
<action android:name="android.intent.action.PROCESS_TEXT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
Get highlighted by user text in activity your app in method onCreate():
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.process_text_main);
CharSequence text = getIntent()
.getCharSequenceExtra(Intent.EXTRA_PROCESS_TEXT);
// process the text
}
More information in the article on medium.
Thanks for user: YungBlade
Him answer on ru.stackoverflow.com
This might be a little bit hacky, but you can trap the menu key at the application/activity level, check to see if your current active view is a text entry view, and then build and display your own custom popup menu.
It is possible, it's just a little tricky.
If you create/inflate a TextView, call setFocusable(false) on it, and then set it as the active view your Activity will still receive key events.
You will have to forward all those events (trackball, touch, key) to your View tree by hand. (Inside your "onKeyDown" function you'd have to call the appropriate "onKeyDown" method for the top level View) You effectively have to trap the notion of 'focus' and dole it out to the correct view yourself.
While a little ugly, it may give you the desired results.
This would, however, only work in your own application. Previous answers are correct about it being impossible across the entire phone.
Push the Share button (tree of three dots) within selection menu. Then you should select your own app. Does't work for input field content, unfortunately.
Hmm; I don't know if you can extend built in types like in example. Ruby (my Java knowledge is not so deep enough).
However you can derive your own MyTextView from TextView. Then substitute all your TextView in layouts like this:
<TextView android:id="#+id/TextView01" />
to
<com.mydomain.mypackage.MyTextView android:id="#+id/TextView01" />
to automatically change type of all these fields.
Then you need to override all constructors
(especially TextView(Context context, AttributeSet attrs) ).
After that all layout inflaters (automatic or manual) will create this type with no fuss.
Then you can create/register context menu callbacks as you wish.