If I want to trigger a switch in the SettingsScreen and then the HomeScreen reacts to the change, what should be the best practice? Should I collect the same flow across two screens? Or should I update the UI state through the life cycle after returning to the HomeScreen?
It's better for storing that value inside a data store and observing updates in HomeScreen and just updating its value on SettingScreen.
of course if you provide more detail for example your codes, i can help better
Related
I am going through the Compose pathway and I keep seeing all of this emphasis on state hoisting. Is this in some way more relevant in the new Compose framework as compared to the old paradigm? It seems like it is just a good programming technique in general. I am worried I am missing a particular advantage in the Composable system.
From the perspective of an Activity or a Fragment they are nearly identical. A stream of states come in and the Activity or Fragment needs to react to the changes by updating its content.
In Compose, however, the composables are themselves tiny fragments of UI all the way down, so to speak. In Compose you can arbitrarily break a UI into smaller and smaller pieces that each react to state changes. It is in this decomposition (so to speak) that state hoisting becomes important and allows these smaller UI pieces to be reusable. Even when you use a Text or a Button they are just composable functions that layout and draw text or map user input to click events, etc.
If state is already in the UI model then it is already hoisted. No additional hoisting is necessary. State hoisting is only important if the composable has its own model of information. The TextField, for example, takes its state as a parameter instead of creating and holding it internally. This allows the state to be held directly in the UI model instead of needing to be synchronized with it. The model can decide if an when the state changes, the TextField just requests the state to change, it doesn't control it. Traditionally, a TextField would have it own internal model of the text and just send out onChange notifications when the value changed. This means there are at least two models of the value of the field, one held by the control and one held by the application model. Synchronizing these can be tricky.
Allowing hoisting of composable state allows there to be a single source of truth, the application model, instead of several states all needing to be synchronized to a single value. Compose does not dictate what the model is or how it is stored, it just needs to know when the value changes so it knows when to update the UI.
Say we have to code a custom View for a toggle button.
A toggle button typically has these two characteristics:
- Is clickcable (i.e. will somehow report click events)
- Has a state (on/off)
Where should we put the piece of code that makes the toggle button switch state whenever clicked?
Does it belong to the custom View itself?
Should the View be totally 'dumb' instead and just report clicks letting the business logic set its on/off state instead (e.g. via a setState() API on the View).
What are the pros and cons of both approaches?
Let's assume in our codebase we want to strive to let the business logic handle the application state as much as possible and let the Views just handle their "rendering": How the answers to the questions above will change in this respect?
Where should we put the piece of code that makes the toggle button
switch state whenever clicked?
A Widget runs on the home screen of the device, so the business logic needs to be called with a PendingIntent
here you can find a valid explanation, and also this blog gives some working examples, even more complex
Clickable widgets in android
When app is running, users adds some views in the Layout. I want to store this Layout, so that when i reopen the app it should return the same state.
How can I achieve that?
Use onSaveInstanceState() and onRestoreInstanceState() callbacks to save and restore your views.
More at Managing the Activity Lifecycle and Recreating an Activity.
[EDIT] - As per #kadatt comment.
I think what you are trying to do is possible duplicate of android-saving-state-of-dynamically-changed-layout.
I dont think there is any standard way of doing this. You will have to implement your own functionality to save state of dynamic UI in some form which can be loaded again.
I am working on an Android app that has multiple screens the user will need to navigate between and I am curious what the best practices are when switching between those screens. I am torn between creating a new Activity for each screen and simply changing the view (setContentView(R.layout.whatever)). The screens all share at least some variable values so I'm leaning toward changing views and using class level variables, but I'm worried a single activity could become very large and confusing with logic for multiple screens in a single file. I'd like to keep the code clean and separated, but I also don't want to be passing several variables around between views if that isn't needed.
Being new to Android development, I'm hoping some more experienced members of the community could share their thoughts and let me know how best to handle it.
Thanks!
Note:
I wasn't planning on using a viewflipper. My thought was to use a button click event and then call setContentView() to a new view for the page I wanted to bring up next.
Example: My application starts up using R.layout.main as it's view. User clicks the Help button and it calls a method that runs setContentView(R.layout.help); to display the help screen as opposed to switching to a help activity.
You should use an activity per screen as this will make the best use of the framework and allow the OS to selectively kill off screens if things get tight.
If you have a single activity and resources get tight the OS has two choices; kill everything or kill nothing, and if the user is not using your app then it's most likely it'll kill everything.
If you use an Activity per screen the OS can kill off some of the screens the user hasn't visited for a while, whilst still allowing others to remain active which allows the user to go back to them quickly.
As for sharing variables and values, you could use the SQLite database or SharedPreferences stores for passing them around if they are widely shared, or use the putExtra methods in Intent if they're only of use from one screen to the next.
If you have variables that you will reuse make a base class for them, that you will extend.
This can be a your custom activity that extends Activity.
As far I can tell you have to create separate activities for each views, only a few situation can be handled by viewflippers.
Which you think is the best way of doing a wizard like application (user can navigate between screens with a next and back button, and each screen has to save some state data) in Android platform.
I mainly can think in two approaches:
Having one activity+view for each screen and then i make the screen switch by calling each activity. What make this nice is that i can use the system back button as my back handler and i don't have to take care of that myself, aslo each activity will save it's own state.
Having one activity and many views, and what i switch views in each screen change, this helps me re-use more code, but makes saving states a mess.
What do you think? Which is the best way of doing this on Android?
This library is no longer being developed.
Use Android Navigation Component with combination of ViewModels to build a wizard flow.
I've developed a lightweight Android library, which is built on top of Android's ViewPager that can be used for creating wizard like activities. Check it out: WizarDroid.
I suggest going with 2 as it fits the goal of activities and views. Saving state in this case is easy - if you use the MVC pattern, you can simply have a model object that is passed along to the views. Each view will have portions of the model that it can read/write. No matter where you are, the model should always have the current state. If you get disposed, just save the model. Restore works automatically since you already read from the model when you show each page.
I've gone with the first approach as it seems more natural. Another app uses ViewFlipper for switching views but that's far from anything like wizard.
9 years ago this was obviously a very different kettle of fish - but I think the best way to do this now is with Fragments.
Have a Fragment for each 'page' in the wizard, letting it handle its own lifecycle and state.
Change page from within each Fragment with Fragment.getFragmentManager() - this returns the FragmentManager from the parent Activity, allowing the Fragment to replace itself.
I think 2 is better. Put each "page" in a view and then just alternate between showing and hiding them. Makes it trivial to do nice transitions. What state are you thinking of maintaining? The only one that doesn't work automatically would be focus and I think you probably want to reset that every time you switch pages. It is also trivial to catch back if you think that is the right behavior for your app.
With 1 you can reuse almost all of your code (just define your own WizardBase class) but I think activities are much slower to launch (and require more memory) than switching between views.