Set data for dynamic view - android

I am generating an dynamic layout from API JSON response. Once the layout is created I need to fetch values from a model class and assign it to the dynamically generated view. The problem is how can I achieve this in runtime? I know this is possible with reflection but is there any other alternative approaches. Since reflection is very slow this might affect app performance.

Related

Some questions about Room and Paging Library

I am trying to set up all my lists with Room Persistance Library and Paging Library but I am facing some problems when implementing PagedListAdapter.
Question 1
I don't want to write any if, when... conditions in the onBindViewHolder so the scrolling is completely fluid. I have a model with its attributes. As an example, I want to set the visibility of a view that it is inside the layout (like a TextView) depending on a Boolean of the model, but I don't want to use an if. What would be the correct way of achieving that?
Should I create an Int attribute in the model which has the View.VISIBLE or View.GONE? But then the model can get very complex with lots of attributes and all of them are on all the model objects of the Room database.
Should I create another model which only has the attributes needed for the adapter UI? But then every time the real model is modified, I also have to modify the adapter model in order to see changes on the UI. And I think that's not good at all.
Do you know if there is somewhere where I can do this asynchronously in PagedListAdapter?
Question 2
I need to use functions like getString(R.string.resource), which requires a context. I also need to use Glide to load an image into an ImageView, but it requires an Activity context or Fragment context. I tried to inject it using dagger but that's not possible. It is safe to pass that context through the constructor? Or what is the best way of doing that?
(I suppose the same problem happens implementing RecyclerViewAdapter)
In my studied application I have table which save the current player state. This table I use in multiselect queries, so when I change this table, Paging library will change my DataSource. Example app.
I use Context instance from View instance with method View.getContext().

How can I do for-loops with Android databinding?

Most popular MVVM-frameworks allow some kind of loops for list type properties. For example Knockout has the foreach-binding. It allows you to loop through the elements of the list property and for each element the markup contained in the foreach-loop is duplicated. Inside the copy, the current element is used as the context for data-binding.
I was looking for something similar in Android, but I only saw the possibility to bind a list to a specific ui-element. But this is bad with respect to declarativeness because I need to create a UI element in code.
Is there a way to simulate something similar using the data binding features from Android? If not, is there a workaround? Or a way to extend the binding syntax?
As #tynn answered, this kind of api is not available.
To achieve the same result, you can setup an adapter for RecyclerView in XML itself. I have implemented this feature in my MVVM library. See Setup RecyclerView from XML itself.
Your XML will look as follows:
<android.support.v7.widget.RecyclerView
bind:items="#{vm.itemVms}"
bind:layout_vertical="#{true}"
bind:view_provider="#{#layout/row_item}" />
<!-- Same arguments for ViewPager-->
<android.support.v4.widget.ViewPager
bind:items="#{vm.itemVms}"
bind:view_provider="#{#layout/row_item}" />
Additionally, there is support for displaying different kinds of child views based on your ViewModel. See Using different types of child views
It's not possible as is. The android databinding library uses static XML layout and binds values to attributes. Creating static layout dynamically is not supported and I assume won't ever be. If you want to create a view hierarchy dynamically you still should use views with adapters. That's something you can do with databindings. Just create your own databinding adapter for binding a list to a RecyclerVier. You could bind to a pair of binding:iterator and binding:layout attributes for example and set the RecyclerVier.Adapter inside the databinding adapter.

Recyclerview with different cards and different data sources

I have a recyclerview and I have at least 3 types of cards with different properties. Logic for switching cards layout is a non issue, but I am wondering what is the best way for me to grab the data.
I guess I can add different webservice data to a list or I can add them to an array where one column is key for type of ws.
I just need some pointers about how other people would do it. My recyclerview today has 3 cards layouts and the view resides inside a fragment. I do the WS calls in the main activity.
I at first wanted to use classes but some cards will use many properties and some few. Like a card for watch widget dosent need data. Current weather needs 3 properties and weather forecast maybe 15. I am thinking maybe I should pass an array that references type of card and then grab the data (as a key)? If I use classes I would have to make very generic names and not all cards would use all of them (not that this is hard to do, but Im thinking it looks silly).
In theory I guess looking at google now shows the different types of cards with different properties from different sources. How would you guys arrange the dataset for such usage?
Maybe you could use a parent class and extend from that the classes for every different type of card. Check the viewType in your ViewHolder and cast the item to the one that represents.

Android: Best way to fill Activity with new data

i got the following "problem".
I want to have an activity thats shows me the standings of some teams at a specific gameday.
therefor i would add a spinner and a TableLayout. At the first Start the activity should show the standings of the actual gameday but then you can choose any other gaymeday and the standing should get updated.
Whats the best way to create this activity?
assemble the whole TableLayout with all TableRows and TextViews, give them ids and update those views via id during runtime. Problem: huge unflexible hardcoded layout.xml
assemble the layout during runtime, add ids, update via ids
assemble the layout during runtime. on update remove old views and create new ones
assemble the layout during runtime. on update restart the activity
just whant to know which one is the best. or is there any other way to achieve that
thx Cheetah
If I were you, I'd actually use a GridView with an Adapter. This will abstract away all the handling of layout changes. You just have to worry about mapping your data to appropriate views. This example maps ImageViews to a GridView, but there's no reason you couldn't map to TextViews containing your data in a GridView. Also, because you're using an adapter, you can take advantage of all the Loader classes and they're asynchronous loading capabilities.
In addition, using the approach will allow you program to easily adapt as your dataset changes. You may want to add more data to the table in the future and this approach will allow you to easily do that without having to constantly change your xml layouts.
Does the number of views change? If no. Best way is to use the already existent views and update their values. Try to avoid recreating/reinflating views since that's an expensive task.

Android: What care should I take when using a View's setTag() property?

Because Java uses object references and not objects themselves, what prevents me from using setTag() to tag a view with an entire object instead of an object's property? Is it just the attribute lookup time when trying to resolve one of the attributes after the getTag() call or is there any other specific thing I should be concerned about?
As for my specific problem, I am using a custom listview that has an imageview and a textview. Initially I bind the listview to a custom adapter to fetch some xml data and then use certain tags inside each item's xml to populate my listview. So the "entire object" I was referring to was the parsed version of the entire XML of an item...
One of the most popular uses of the setTag(Object) method is exactly keeping a reference to a class instance - if you have used custom ListView and custom Adapter, you should know about the ViewHolder pattern.
Without knowing much about your particular problem, I would say - Is this dangerous sometimes? Yes, if used irresponsibly. Does this mean you should avoid it at any cost? No, absolutely not.
Edit: Why do you want to have the parsed data for your views bound to them?
Do you really need it, or you can populate some type of a model? If you want to access the tag of a view in a context, where your view doesn't carry the same meaning/position (like the convertView does in our favorite ViewHolder example :)), I would think using tags is OK.
Otherwise, I'm sure that if you give it a little more thought, you'll find another approach better suited for your problem.
There are two api for settag one with just value and another with key and value. First api is very safe, but you need to be very careful when using second api.
Internally in the View.java Android maintains a static hashmap mapping view to a sparse array. The key and value passed in the settag is stored on the sparse array. There are two important things need to be considered.
First don't save value object having any reference to the activity. This would result in a memory leak as activity will have strong reference from the value and value has a strong reference from the static hashmap maintained by the View.class.
Second every look up for gettag internally have to lookup a hashmap and a sparse array. Which is not very efficient.
Thanks
Suriya.
Take care to avoid situations such as:
the View is being recycled and thus the existing contents of the tag probably don't suit the new use-case for the view.
that some library or other mechanism is using the tag as a "trick" that is not sociable with your use of it.

Categories

Resources