Now I am working on Android application which has one main Activity that is displaying some data via GLSurface. This data can be changed in many ways. For this I have several fragments with some lists of variants with extra logic. Problem is that I need somehow transfer data from one place to another.
For example:
I have fragment with list of elements. I used RecyclerView with custom adapter. I am filling list with data from DB. SomeThingDBEntity for example. When I am getting it from Room DB (using Room entities), but it has some extra fields that only required for showing elements in RecyclerView. I need to send user's choice from adapter to fragment, then from fragment to activity, than activity sends it to some class that incapsulates logic of work with GLSurface. SomeThingGLentity for example. Now I am passing only fields, that requered by SomeThingGLentity for showing data (int, String etc.), but in future this list can grow. I can also send directly SomeThingDBEntity and get required fields only in the end when apply changes to SomeThingGLentity. But is it OK to use Room DB entity this way?
Is there any better way of doing this? I can also create third class which will only contain required fields. But where to place and how to call it? Maybe there are some patterns or guidelines of best way of doing it...
It looks like you need a data mapper. Something similar to this - https://github.com/android10/Android-CleanArchitecture/blob/master/data/src/main/java/com/fernandocejas/android10/sample/data/entity/mapper/UserEntityDataMapper.java.
If you use this approach, you will be able to encapsulate the transformation logic from your DBEntity to your BusinessEntity, and if you will change the data format in one of them, only your mapper will need to be edited.
Related
Displaying an array of objects in a GtkTreeView can be quite complicated, as you have to copy the values from the array into a GtkListStore and then write a lot of code to keep them synchronized. (Or store the objects in the ListStore directly, which is then clumsy to access)
Android has an elegant solution to this issue by having an Adapter class, which is a wrapper for an array where all you have to define is a function that gets the nth item of the array and fills a widget or row with it. (Along with methods for handling the nth row being clicked, etc.)
Does a similar class exist in Gtk? (or a 3rd party addition)
How would one go about implementing a class like this?
There is no such a class in Gtk. If you want to implement it, you will need to rewrite (or subclass) GtkListStore (source), or to be more precise, write a new class which realizes GtkTreeModel interface. Plus you should somehow notify your model when the array changes.
Assume we have an Activity with n TextViews that represent one line notes. These notes are stored somewhere (local database, network etc), and each time onResume() being called, the proper number of TextViews are drawn according to that stored data.
Now, lets say the user want to delete a note, what would be the best way the resolve the specific TextView, back to its storage entity?
At the moment, the only way I know is by using View.Tag, and having some manager to translate it to data entity, but it look rather messy.
Are there any other options?
In Android, the Adapter acts a bridge between the view and the data model. You could display the n TextViews in either a ListView or a GridView, and when the user adds or deletes a note, the local or server database is first updated. Upon completion of the web service call and/or the local database update, the new data is added to the underlying Adapter. The View is then refreshed by calling adapter.notifyDataSetChanged(). This would be the way to do it.
Approaches:
If updating the local SQLite database, you could consider using a
CursorAdpater
to hold the data for the View, as it directly maps the entries in
the local database to the View.
If making use of a ContentProvider, it is even possible to combine
a CursorAdapter with a
LoaderManager
and a
CursorLoader:
these plug into the Activity / Fragment life-cycle and monitor
the underlying ContentProvider for changes that are published
automatically to the View on a separate thread.
It is also possible to use a
Filter
in conjunction with the Adapter to define a dynamic mechanism that
sorts the data entries on-the-fly. The filtering is performed by the
Filter on a separate thread, as per a query entered by the user,
possibly in an
AutoCompleteTextView.
References:
See the Retrieving a List of
Contacts
tutorial. The example here retrieves a set of contacts from the
contacts ContentProvider based on a dynamic, alphabetical search by
the user. It makes use of CursorAdapter, CursorLoader and
LoaderManager to monitor and update the data, and it displays the
search results in a ListView.
See also the Android Realtime (Instant) Search with Filter Class example, which shows how a Filter is to be used.
Android AutoCompleteTextView with Custom Adapter filtering.
Android AutocompleteTextView using ArrayAdapter and Filter.
I need to fetch list of data from server, feed to adapter, and show in list view.
Question is who should do the backend call, activity or adapter or ?
And please elaborate why. This question is more about why than how.
Please answer in an model view controller or similar (I know strictly speaking android does not have MVC) context.
Edit:
It's now obvious to me adapter is very bad place to fetch data (imagine how un-flexible it will be. E.g., what if there are two end points for similar kind of data. Or I have two adapter for same data set, it make no sense to let one of the adapters fetch data). Other component should be fetching data and filling adapter. Activity is a good component to do so.
The accepted answer provides an illustration of doing it.
Never fetch data from an Activity because it will block the UI.
You should extend AsyncTask with parameters and return type as you wish.
Do your work on the method doInBackground (#Override it) and on the method onPostExecute (#Override it), call some public method on your Activity to give to it the data you fetched.
Finally, the Activity with the fresh data should feed it to do Adapter.
This is how I always get my data and I get the results 100% as I want (add a progressBar and make it visible before fetching the data and make it invisible after you give it to the adapter).
Hope I was clear enough to you. If you want some code as an example, please ask.
Workflow:
1 - Activity -> new MyAsyncTask(...).execute(); //get the data #Override doInBackGround
2 - MyAsyncTask.onPostExecute() {myActivity.giveFreshData(...)} //deliver the data
3 - Activity.giveFreshData(...) {MyListAdapter.giveMyData(...)}
Altough it isn't MVC this is how you should separate the UI from the data consumption and the data representation.
Neither of them, I would create a class that make the requests and transfom it into objects, then the activity take this objects and pass them to the adapter.
Actually you can fetch data directly from an activity, only if this is an async task. (but it would generate duplicated code)
The Adapter class it is usually used to transform objects into something visible in lists and stuff like that
The activity would be like a controller, that interacts with the class that fetch data from the server and the adapter.
then you will need a class to fetch the data and return it into java objects (is it not necessary, but if you are using MVC it is the ost correct way to do it). Also if you call directly an asynctask from the activity, if exists more activities that need to do this same request, then you will have duplicated code (and everybody know that it is never good). Then it is that why we need another class that will transform requests into objects in a callback captured by the activity, this class can be reused from all activities or classes.
Good afternoon,
I have a simplistic app (just learning) that reads some xml data from a mocked up file. The XML data is well formed into 6 categories and I use the SAX parser to read it. My app basically has two buttons prev & next. So when the app loads I'd like to see the first category of xml data. When the user presses next button...well then I'd like to see the next category of data etc. to the end. My question is how do I go back and forth through the data? Do I load it all into a data object with some form of sorting and iterate back and forth throught the object or do I add an atty field to a parent element and just search the xml for the requested atty and child data? I don't forsee the xml ever getting very large. Just trying to get more experienced input into how to go about synchronizing the data with the gui.
TIA
JB
There are many ways you could go about it. One that is generally a decent path is parse the XML into a data structure that can be used by an Adapter to create the view structures and return them so be shown. That will give you a good level of control over how your data looks and allow you to tie in to many different complex View structures pretty easily.
The data structure that you store it in also has many possibilities. Which ones work best would depend on your particular dataset generally.
Given what I know about your data an ArrayList seems like a straightforward approach. Create yourself a class that will hold all of the data about one category. Create objects of that class in your parser as you are pulling the data out of the XML file, each time you get to a new category add your object to an ArrayList. When your done you should have an List structure that has 1 category object(with all of its data) at each index.
Once you've got that set up make yourself an ArrayAdapter with your List. Override the getView() method to inflate your View objects and populate them with the data from your List.
This Adapter can then feed a parent View (ViewPager, ViewSwitcher, ListView etc...) These parent views will make it easy to iterate over your data structures (i.e. switching from one category to the next and back.)
I'm looking for guidance as to how to modularize my code. I have an activity and a listAdapter and they are getting pretty complex. I'm not sure what code should live where and how much knowledge each of these 2 classes should have of each other. How do you decide whether to put code in an activity or its adapter? And what patterns do you use to keep these classes as lean as possible?
Your description is too generic, so I cannot give you an exact answer (would be useful to explain why they are getting bigger and bigger, what is the extra code good for).
But generically speaking, just think about what each class supposed to do. The "Activity" (as I see it), is a main controller, it "knows everybody", and it connects the other components together (the ListView with the list adapter). The list adapter's purpose is simply to map data to views. If they are getting bigger, extract new (utility) classes.
For example assume a big part of the code in ListAdapter formats timestamps (eg. takes timestamp as long value, and based on current time creates a string like "2 hours ago"). Then it makes sense to create a new utility class called TimeFormat (with a constructor which takes a context, you'll need it later to fetch string resources). Then the ListAdapter will create an instance of this class.
Another example would be data saving. In that case you could create a class called "Model" or "Document" (again with a constructor taking a "Context" instance). It would be responsible (for example) to load the data by parsin XML files, and to save the data by generating XML files. In this case this class would be instantiated by the activity.
Also note that the ListAdapter should really do what it supposed to do: create/setup views based on data. It should never depend on other views (in other views it should work with any ListView in any layout file). So if you have "findViewById" call, which access a view outside of the ListView (or the ListView itself), then that code should be moved to the activity.
Also, when in doubt you can try to find an open source application, which is relatively mature, and does something similarn (and see how that is solving the problem).
Per the adapater documentation in android
An Adapter object acts as a bridge between an AdapterView and the underlying data for that view. The Adapter provides access to the data items. The Adapter is also responsible for making a View for each item in the data set.
So if your code has to do with getting the data to display or creating the views, then it goes in the adapter. Everything else goes in the Activity or else where. If you're spending a lot of code retrieving the information you want to display, consider using some sort of AsyncTaskLoader class. Note that loader classes can be accessed from API Levels less than 3.0 using the android compatibility package.