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().
Related
So I have a few arrays of data I would like to display in an activity without having like 15 text views with unique ids. Is there a code efficient way to make a Table layout or something like it where I could feed in data and it would automatically place it in there respective text views? Thanks!
I think you can achieve that by using RecyclerView (with a GridLayoutManager). Have a look at this answer.
If there are only TextViews and you don't want a specific layout you can use SimpleAdapter, if you want to modify the layout you have to extend RecycleView.Adapter (there is an example in the answer above).
You can add/remove items into/from a List and use DiffUtil that
can calculate the difference between two lists and output a list of update operations that converts the first list into the second one.
There are a lot of tutorials about using this class. Have a look here or here.
Or you can use the notifyItemChanged() method:
If the list needs an update, call a notification method on the
RecyclerView.Adapter object, such as notifyItemChanged(). The layout
manager then rebinds any affected view holders, allowing their data to
be updated.
LE: There are some libraries available. Here is a list:
https://github.com/evrencoskun/TableView
https://github.com/HYY-yu/TableRecyclerView
https://github.com/Cleveroad/AdaptiveTableLayout
https://github.com/celerysoft/TableFixHeaders
is there a way I can get/return a View in my case a RecyclerView from the Adapter using it so as to reuse it in another Activity. And if possible how can I then re use it in the Activity?Without re-referencing it a new in the Activity
If I understood your question right, you are asking whether an Adapter for RecyclerView you have in an Activity can be used for another RecyclerView in another Activity. In that case, the answer is - YES, it can be used in as many places you wish..
Don't forget, Adapter is nothing but a design pattern in programming:
Adapter pattern works as a bridge between two incompatible interfaces.
This type of design pattern comes under structural pattern as this
pattern combines the capability of two independent interfaces.
As long as you have your Adapter class accessible (not a private inner class) by your other Activity, you can reuse it with different RecyclerView and different data.
I am creating an Android application that will mainly consists of ListViews in each activity. What I hope to achieve is a mechanism that will check to see if network connectivity is present and if so then then the data should be retrieved and supplied to the ListView. If there's no data present or the internet connection is unavailable then a seperate view should be loaded.
Which way is most efficient do to this. So far I have seen answers about using a ViewSwitcher or Viewflipper but I am not sure that's the right approach. Should I use fragments and then load a particular fragment based on the condition that was met? I just need some advice on how to accomplish this.
Have you considered just swapping the adapter? This question might be of some use to you.
I guess you might add some kind of factory method that will decide what adapter to instantiate depending on connectivity availability. Thus you will control both the data to be used and the appearance of list entries (I assume you will be using some custom extension of one of the existing adapters).
The best way is going to be to use the emptyView that's provided as part of the AdapterView base class. You just set the adapter as per usual, but if no data is retrieved (i.e. your adapter's data source is empty) you will show the empty view in place of the list. This empty view can be anything you want it to be.
As #Ivan says you should consider setting adapters in a dinamic way.
And about the fragments thing, only consider using independent fragments (or ListFragments) for this if you are going to re-use that fragments in other activities to avoid code duplication.
Who knows about programming for iOS and data source/delegate paradigm will understand me.
The best practice for implementing custom view in iOS:
Implement MyView class inherited from UIView
MyView has dataSource field.
On drawRect: method MyView asks dataSource for items to draw.
dataSource object conforms to required protocol and implements needed methods.
It is very similar how is implemented UITableView, but I am not talking right now about cells.
Could you please let me know the best practices to implement custom view (like MyView) in Android with MVC pattern?
See MVC pattern on Android
Read all the answers to get a rounded view of android patterns as I don't find the first one very helpful.
Design decisions have been made regarding fundamental application components which prevent pure MVC being implemented, for example the use of activities which don't allow decoupling of the layers.
I find viewing android apps in a MVC way confuses matters as you end up misusing components like activities and adapters by trying to adapt them to perform a function they weren't really designed to do.
UPDATE
You need to make the question a little more specific to get a good answer, provide details of what sort of view you require (list, grid, simple) and what sort of models you are using (where are they persisted etc).
Although it's fairly subjective I have found the following when programming with Android:
Models tend to end up being unavoidably dumb (the anemic anti-pattern). This can be because in many occasions you will find the adapter is passed content to present in the view in the form of an object or collection and then operations on those objects or collections should be performed through the adapter so the adapter is aware of when they are changed and can manage the view accordingly.
The adapter can be treated as a link between model and view, a controller if you like but without many of the advantages of a pure MVC controller. I have found that customising the adapter can be effective (although you end up with 'fat controllers' if you are viewing it from an MVC perspective). Any UI input which would invoke changes to the content can then be called by adapter methods which will edit the models using add/remove for lists, or cursor operations for the database etc.
To implement a custom view in Android, you should derive from an existing View, then override the methods you need, which will often include onDraw(), onMeasure(), and probably one or more event handlers1.
To implement something in the spirit of MVC, the data that your component represents should not be in the view class itself but instead in other classes. The exact design is up to you: you can have data stored in files, in Java objects, pull it from a Content Provider2, etc.
When drawing (override onDraw()), you should look at the state of your data and draw accordingly;
When handling an event that alters the data, alter the data in the model and call invalidate() on the view to request that it be redraw to reflect the changes.
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.