So this my pictures are supposed to change each time the value of limonadeState is being changed. But...they don't.
Can the reason for that be that the images are XML?
Because you're not listening for changes of limonadeState.
assuming you put when statement inside the Activity's onCreate method, and onCreate runs only once in a lifecycle #see https://developer.android.com/guide/components/activities/activity-lifecycle
to achieve your expected behaviour, extract when statement and wrap inside a function and call manually on limonadeState state changes.
Related
Why Is onCreate() Preferred To Do All The Main App Tasks? Why not onResume() or onStart()? Why only onCreate()? I tried to do the main tasks like binding findViewById() setting text to text views and a lot more. They all work fine. When why do we always are preferred to do that task in onCreate()?
OnCreate serves as the first entry point into your activity, so logically it makes sense to do as much of the initialization here as possible. Often times there are cases when things need to get configured with higher priority - crash reporting services, dependency injection etc. where this would get escalated to a custom application class.
according to the docs
protected void onCreate (Bundle savedInstanceState)
Called when the activity is starting. This is where most initialization should go: calling setContentView(int) to inflate the activity's UI, using findViewById(int) to programmatically interact with widgets in the UI...
so, I suppose it is fair to say that most initialization will get done inside of onCreate, which usually means that if you were to place this into a lifecycle method which could get executed repeatedly, that could be considered redundant as you'd be assigning the same values to variables repeatedly, unless that's something you actually want to do.
However, lazy initialization is also a concept to keep in mind, being able to initialize something inside of onCreate doesn't always mean that you should, it is often times better to delay initialization until you actually need the instance.
regarding
I tried to do the main tasks like binding findViewById() setting text to text views and a lot more. They all work fine.
they definitely would, findViewById can always be used and isn't limited to being inside of onCreate, in fact the result of findViewById doesn't even have to be assigned to a variable for you to be able to use it
I am altering a recyclerview and would like to be notified of when that update is finished. I read How to know when the RecyclerView has finished laying down the items? that you are notified in the callback to addOnGlobalLayoutListener, but that is called too many times unless you add the last line.
Here is what I tried:
my_rv.viewTreeObserver.addOnGlobalLayoutListener {
calculate(myAdapter.getItems())
my_rv.viewTreeObserver.removeOnGlobalLayoutListener(this)
}
in order for the last line to compile, my fragment needs to override onGlobalLayout. What am I supposed to put in onGlobalLayout? I never see that callback even called.
It's because in your calculate method you change the layout, like setting text, setting image resource, etc. so in the first call you need to remove the listener to avoid listening to the next GlobalLayout events.
and it is better to remove removeOnGlobalLayoutListener in first line:
my_rv.viewTreeObserver.addOnGlobalLayoutListener {
my_rv.viewTreeObserver.removeOnGlobalLayoutListener(this)
calculate(myAdapter.getItems())
}
I have started studying Android programming recently after taking a very long break (half a decade) from programming altogether. It's been going well so far.
I have noticed that Seek Bar's progress survives onDestroy event after a rotation (configuration change) happens and this happened on a fragmented activity. Then I created an empty activity and added the widget in the layout and the result is the same (as I expected but still tried due to some code). I also tried overriding the onCreate method and passing a null SavedBundleInstance into super.onCreate() and the result is the same. So I don't know where the Seek Bar's progress location is saved before onDestroy and then passed back unless I am missing some static variable in the SeekBar class or its super classes. (I just thought about that now, I should check it)
Can someone explain why this happens?
Usually, Android Views save their state upon rotation. The same happens for example with EditText. If you input something and then rotate the device, the text will be kept.
It's done inside the specific View class.
But how is this state persisted through orientation changes?
In Activities, for example, you have onSaveInstanceState(Bundle bundle). That method is called by the system before a configuration change occurs. What you do, to persist the state of the Activity, is to store inside bundle the values you want to save. Then, when the Activity is created again, this bundle is passed back to you, for example in the onCreate method. This way you can restore your state.
But what about Views? They use a similar mechanism. If we want the details we have to look at the source code. Let's look at the source code of ProgressBar. It turns out that the View has a onSaveInstanceState, too (this line). You can see there, that the progress is being saved.
I hope this clarifies the mechanism.
I have inherited some code hence I don't have true freedom to change it. :(
I have a main activity, from which other activities (I will refer to these as sub activities from now on) are called. Whenever one of these completes, it calls finish and returns data to the main activity.
Each activity (including the main one) has a bar on the top that displays a custom view. The custom view contains a canvas which has a drawing that is dependant upon the state of the network.. i.e. wifi/mobile etc...
Since that 'state' data never changes, it's held within a singleton and the view gets data from the singleton to define what it draws. That is working with no issues, i.e. the data is always as I expect it.
When I first launch the MainActivity, as the network changes, the data changes and each call to 'invalidate' the view receives a system call to 'onDraw' as I would expect.
In each of the sub activities the same is again true.
Upon finishing a sub activity and returning to the mainActivity, calls to invalidate no longer cause a call to onDraw to occur.
I have looked at this for quite a while now and just cannot figure out what is going wrong.
In my constructor I have:
setWillNotDraw(false);
Whenever the data changes the following methods are called:
invalidate();
requestLayout();
Now, there's one more thing... upon returning to the activity at that immediate point, I refresh and this DOES draw correctly, i.e. invalidate does trigger an onDraw call... any subsequent network changes (which are propogated) fail to result in the onDraw call.
I'm wondering if this is to do with the view somehow being detached. I can see that 'onDetachedFromWindow' is called, however the trigger for this is the destruction of the subactivity, hence I don't see why that should affect the MainActivity but it's the only thing I can think of.
I'm hoping I've provided enough information for someone to help me...
Well, in the end my answer has very little to do with the question and I guess this is an example of how an issue can be solved by going back to absolute basics and checking for the obvious.
My activities all inherit from an abstract activity. Within that activity there is an instance of the view. The views in which I was having trouble were using that declaration as opposed to having their own instance, hence behaviour from one activity was then affecting another inadvertently.
So, if I'd been able to post up all the code, I'm sure someone else would have spotted this but, unfortunately I couldn't in this instance.
Still, whilst this posting doesn't provide a resolution that will help others, maybe it does say... step back and check the obvious first!
To handle orientation changes, im overriding:
onConfigurationChanged
But regardless of where I make the call to
super.onConfigurationChanged(config);
The super always gets executed AFTER my code
Is it possible to have code be executed after the super, which is after its rotated?
Edit: I guess there's no way around this. It seems that when you override a function, the super gets executed last no matter what.
set a break point on your super.onConfiguratioNChanged, I highly doubt that "regardless of where [you] put the call" it still calls it last.