When should InverseBindingAdapter be used? - android

Why do I need InverseBindingAdapter in Android DataBinding, When should we use it?

The word Inverse is really saying everything you need to know, if you think of what DataBinding is actually doing.
If you enable DataBinding for your Layout you can perceive it as a pair of two things:
View (all Views included in <layout></layout>)
Model (all variables included in <data></data>)
Regular DataBinding makes sure that a change in the Model will have its effects in the View. It is invoked by #{expression}.
Inverse DataBinding makes sure that a change in the View will have its effects in the Model. It is invoked by #={expression} (the = char is essential here).
If you think what are the ways to make a change in the View, those can be:
Changes in content (e.g. text in TextView)
Changes of checked state (e.g. in RadioGroup)
Changes in focus
...
Some of them are enabled by default and for others you will need to write a custom InverseBindingAdapter. More on that here.
If you still need more information on that topic I suggest you watch Google I/O 2016 presentation on Advanced DataBinding.

Related

Compose UI: How to query the semantic tree at runtime (not in test)?

In my app I want to display some sort of tutorial to guide users through the app - something like this. The app already uses tutorials in other parts therefore I want to integrate Compose UI support into the existing tutorial framework.
For this purpose I need to get the position and size of several composables. Therefore I want to set semantic
properties to the views I want to identify like this:
Text(text = text, Modifier.semantics {
set(customPropertyKey, "CustomValue")
})
How can I query the semantics tree in order to find out details like position and size about the composable with the value "CustomValue"?
This is possible in Junit tests using composeTestRule.onNode(...). However, how can I do that at runtime (not in a unit test)?
I know that reading the position and size might work using the onGloballyPositioned callbacak but this would lead to much boilerplate code which I try to avoid.
#CommonsWare's solution seems viable. Just create a boolean to denote whether tutorial is active, then use it inside the Composables to render accordingly. If you want the size and position of the items, you could simply store them inside the viewmodel. To get the values, just use the onGloballyPositioned{...} Modifier. You can retrieve the size by calling it.size (or name the labda parameter) inside it and the coordinates with the same approach.
Also I would suggest that you implement the stuff from the ground up. Maybe migrate slowly in a scratch project. If you try to migrate with the same sematics as the view system, creating an unbalanced hybrid, you will not be able to get the full advantage of the declarative paradigm that Compose is built on.

Tips to boost performance of TileLayout?

I am targeting mobile using FlashBuilder, I am using TileLayout to view items of data, I am setting useVirtualLayout to "true"
I have some questions please:
Is item renderer resued by default? or shall I set it to true my self?
How can I control the range of items being virtualized?
Is there any tips on boosting performance of building child items of TileLayout ?
If native TileLayout is slow, is there alternative control to use? if building my own would be better, is there any example to build custom layout?
It is set to true by default. There are a few instances where they are not virtualized, however. If you have the list sizing to fit its contents, I don't believe virtualization occurs. If I am not mistaken, virtualization only occurs when an ItemRenderer leaves the viewport of the parent List control. So if you have a list on a page and that page is controlling the scrolling and not the list, I don't believe virutalization occurs. That is what I have seen in the past. Not sure if that is how it actually works, but that is the impression I have gotten. Easy way to find out is to throw a trace statement in your DataChange handler. If it traces out after initialization, you know virtualization is working
I'm not sure you can control this. You may be able to write a custom layout that does it, but that is likely more trouble than it is worth
The TileLayout itself is likely not the issue you are having, it is the ItemRenderer.
On mobile, do not extend any ItemRenderer class except LabelItemRenderer and IconItemRenderer.
Do not write a renderer in MXML. Write in AS3.
Utilize the proper renderer life-cycle. This means you should do very little in your constructor. Maybe set a few properties, but do not instantiate any DisplayObject. Instead, override createChildren() and do it there. Override layoutContents() for positioning and sizing. Override drawBackground() for handling the background. I highly suggest reading this post from Flextras (you'll see him going by Reboog77 on SO) about writing mobile item renderers. https://www.flextras.com/blog/index.cfm/2011/6/24/Building-a-Mobile-ItemRenderer-in-Flex
Keep the renderers as simple as possible. If you can get away with drawing directly into the object using the Graphics class, do that instead of using a Rect or similar.
Text is slow to render. Do not change it often and keep the text seen in the renderer to a minimum
Use ContentCache for any images outside of the iconDisplay in IconItemRenderer. ContentCache will negate the need for reloading images every single time.(iconDisplay/icon already utilizes this by default)

How to set active tab in MVVMCross TabActivity

I want to set the active tab in a View that inherits MvxTabActivity from the ViewModel layer. Is there a suggested means to accomplish this or is there something in the MVVMCross framework I can use that I am missing?
My only plan at the moment is have the View send messages to the ViewModel when the tab changes and have the ViewModel send a message to the View when it needs to change the active tab.
I would much rather be able to bind properties from MvxTabAvtivity to the ViewModel though. E.G. the MvxTabActivity could have an "ActiveTab" property which is a simple string that names a tab and can be two-way bound to a property on the ViewModel.
This isn' out of the box behaviour.
But you can try to do this in several ways:
using messages (as you suggested)
using a custom presenter and send changepresentation hints - custom presenters are introduced in https://speakerdeck.com/cirrious/presenters-in-mvvmcross
creating and using a custom binding - https://speakerdeck.com/cirrious/custom-bindings-in-mvvmcross
I'm also sure other ways might be available.
Do be aware that the concept of changing tab might not fit well in all platforms - eg its unusual for a wp pivot or panorama to change item.

View/View subtree changed listener API

I'm trying to write a debug utility that will take certain actions (logging, screenshots, etc...) when a view in the current Activity's view hierarchy changes. Change here is anything that would result in the visual representation of the view tree to change: setting the text on a TextView, changing the background color on a View, or adding/removing children to/from a ViewGroup.
Ideally, I'm looking for an API that will notify me when these changes are about to occur and what view/view subtree they will be effecting.
I've spent a lot of time looking at possible solutions and the cleanest would be to use ViewTreeObserver's OnPreDrawListener and OnGlobalLayoutListener. They seem to be notified when the events of interest occur. However, they do not provide any context information as to which views are affected. AFAIK attaching these listeners to a view's ViewTreeObserver results in the notifications being fired whenever anything in the view tree changes and there is no way to create isolated ViewTreeObservers for individual views. This means that I would have to traverse the entire view tree at each notification to determine which property was changed.
Another approach would be to binary patch the View classes so that they callback to my API in methods like setBackgroundColor or any other methods of interest. android-aspectj could be used for that. The downside here is that this would only work for classes that I compiled and so is next to useless since I could just modify the source directly. Along the same idea, dexmaker would be a more complete solution as it allows for patching the classes at runtime. Here, however, we run into the problems of class loading. To patch the class I would have to load it through my own ClassLoader but all of the View classes would have already been loaded in by Android. One solution would be to clone the view tree after it was created but instead of using the stock loaded classes, use my own patched classes. This would almost work except for situations where the app has grabbed references to the view tree before my patching has been put into place. Of course I would also have to redo the clone at each layout change event (adding/removing views). I understand that this process would be slow but so far it is the most transparent and most complete solution.
Finally, and this is probably the most difficult approach, is there a way to use the method tracing system built into Android (Traceview) to receive trace events at runtime? Currently the system will dump the trace to a file on the SD card for offline processing. That is obviously too late for my needs but it would be nice if there were hooks exposed in the native SDK for intercepting these events.
Any and all suggestions are welcome. At this point I am not even looking for portable solutions so feel free to mention any reflaction/hidden API tricks. Thanks for reading this behemoth of a post.

Does Android UI development lend itself well to a particiular design pattern?

Does the Android platform lend itself well to a particular style of UI programming like MVC or MVP? Most of my UI experience is with spaghetti code on a very old embedded device or in GWT with MVP so I do not know where to start.
The MVC Pattern is more or less pre build into android.
You have three layers consisting of:
The Model Your data classes, Content providers etc. wrapping all your data.
The Controllers Treat all your activities as controller classes. Don't do anything in them that looks like business logic or data persitance. Just react to events from the model or the user and forward them to the correct layer.
The View Often the Activities are called the view because there it is the java code that is closest to the views. But in my opinion the view layer in Android is mostly defined in xml. You define your buttons, images, state changes etc in xml and then connect it with your application through your Activities.
There are some simple rules to follow to have a basic separation of this layers.
Define as much of your UI in xml only
instantiate Views yourself if there
is no other way to achieve something,
don't change the graphical state of
views from code, for example don't
change the background of a button if
the button is deactivated, or the
color of a font if a button was
clicked, do all this through stateful
drawables, and selectors in xml.
Don't do any data saving or logic in
your activity classes. Call to extra
model classes for this purpose. This
will make your activities clean and
short
If you want to change your data think
about going through a full
controller changes model -> model
informs controller about changes
-> controller changes UI cycle instead of having the controller
change the model and the UI
directly because other observers
of the modes may not be notified.
I do not know if the Android lends itself well to a specific design pattern when it comes to UI development per se, you can certainly use a particular pattern if it helps.
When in doubt you can check out the standard User Interface Guidelines and see what the guidelines are for particular interactions.

Categories

Resources