Expandable ListView with custom objects - java

I'm fairly new to android and am slowly adjusting to how android works.
I am in the process of creating an android application which uses a .net web service to pull back data from a sql database. I have two methods which return a json response with a list of custom objects.
I am parsing these into arrays of matching objects on the android client. I am looking to implement a multiple tier grid displaying information from these two arrays. The items in the first array will have child items contained within the second array.(one to many relationship)
I am guessing I will need to create two custom array adapters? (which will allow me to have custom layouts for each tier).
I have had a look around and struggled to find a comprehensive example of using the expandable list view. What data source will this expect? (some kind of hash table I would imagine?)
Does my approach above sound reasonable?
Any advice would be appreciated.
Thanks,

ExpandableListView expects a class which implements the interface ExpandableListAdapter as the data source. There are several implementations included in the Android SDK. The SimpleExpandableListAdapter would probably get you up and running the fastest, it uses Lists and Maps for it's data. It won't give you the ability to use different layouts for each group within the list but it will let you have a different layout for groups and children.
If SimpleExpandableListAdapter isn't enough then you are going to want to write your own adapter. I'd suggest extending BaseExpandableAdapter (this Adapter implements ExpandableListAdapter and takes care of some of the housekeeping aspects for you, it leaves the rest of the implementation to you). There is a simple example that shows how to do this in the API Demos ExpandableList1.java example.
Your implementation will likely be more complex than the example, but it should give you some idea how to do it.

Related

Making UI elements dynamically in android apps in android studio using java

I am wondering if it is possible to create UI elements dynamically in android apps without using xml or design? The number of elements and type of elements will be different based on the requirements I get from a json array. So, can I create buttons, textviews, etc in my activityClass file, without actually having them in my xml file??
if yes, then how complicated would it be? can you provide an example please?
Also, are there any libraries for android that I can use that would just dynamically create the fields for me based on types and number of fields as an input?
Yes. You just create the View objects using new, then add them to their parent layouts using .addView(newView). If necessary, add them with the correct LayoutParams object.
I will say that this is MUCH harder to write and debug than xml, so it should be done only if something absolutely has to be manual. Even if you are getting things from a JSON blob, its best to make as much of that just deciding what xml to inflate as possible.

Design for survey app

I'm very new to java and want to ask for a help about design. I'm going to build a simple survey app for android in java.
Here is how I see the app:
The main page (activity_main) contain LineEdit for ID and two buttons: Login and SignUp. This activity onCreate loads all registered users and questions from DB.
Sign up page (activity_signup) contains several LineEdit fields for user info as well as SignUp button. Also it provides free ID onCreate.
Profile page (activity_profile) contains some user info (as TextView), possibly and a Survey button.
Survey page (activity_survey) contains Question, Answers and two buttons: Prev and Next.
Please mention if something might be improved.
Questions:
Should I store all users and questions as private field in class MainActivity or somewhere else? (Assume that DB is so small that it perfectly fits in RAM)
How can I modify the DB with newly created user from activity_signup? It is rather general question, like how can I access private fields from other activities preserving encapsulation?
I'd like to have a filed like private static User current_user in class ProfileActivity. But I can get the user only from DB, which is private field of class MainActivity. How can I pass the user from activity_main to activity_profile (again preserving encapsulation)?
activity_survey contain answers of different types, e.g. Yes/No; single/multiple choice (+ your variant) etc. How can I handle this in java? My idea is to create an abstract class AbstractQuestion with method fillLayout and inherit several class ConcreteQuestion (here concrete should be replace with an appropriate title) from it which contains implementation of certain type of question. Store all questions in array of AbstracQuestion's. Is it doable in java or is there more right way to do this?
Thanks in advance for any help!
Don't store such objects in Activity. You have several options for data persistence - these are listed here https://developer.android.com/training/basics/data-storage/index.html - of course that does not cover any "external" sources such as databases like Realm or Firebase but let's keep to the basics.
If your data is complex and you think that it would be easy for you to retrieve it using SQLite queries then the SQLite Database is the way to go. You can access it using ContentProvider which can be queried from any place where you have Context.
You can also store it locally on your internal or external storage with simple Serializable classes. Imagine a single object let's call it Database that is Serializable and that contains all the data you need. You could load it in your App startup (like in extended Application class) and store the reference so it won't get garbage collected. Then you can access it from a Application static method you could write to get the reference. It is probably the fastest way to implement a simple storage with fairly complex structure but that is probably not the best if your data is "big". It will increase your App start time (preferably make the load and save operations asynchronous).
If your data is simple you can use SharedPreferences to store "key-value" data. This is a little like second approach but using the Android framework to do it.
The option 2 and 3 require that your data is Serializable or Parcelable. As Android says that Parcelable should not be used for persistence but rather for communication let's skip that one.
You can either make you objects Serializable or translate them to json objects with i.e. Gson library. and store those serialized json objects. Making them serializable directly may be faster approach but sometimes keeping jsons makes more sense.
You can't and you shouldn't have to.
If you wan't to keep your data in static fields move them to extended Application class (make sure you point it in AndroidManifest.xml with specific xml parameter) and access it from there. You can get access to your Application class whenever you have Context via context.getApplicationContext() that you can cast to your custom class.
To tell Android to use your custom Application class use the following in AndroidManifest.xml:
<application
android:name=".YourAppClass"
...>
...
</application>
I am not sure if I get the 4th question right. Basically if you have multiple values you need to store your results in some collection i.e. ArrayList. Your whole questionare could be represented by a Map<Question,List<Answer>> then <- arbitrary class names (these could be enums too)

Proper Usage of Android Fragment

I have been reading up on the Android API and it seems like Fragments are meant to sort of modularize an Activity. So if an Activity has a ListView and DetailView then it should be split into two separate fragments and have the Activity act as the master controller.
In my previous project that I worked on we were using Fragments kind of like children of the Activity.
For example: Let's say there is a AutomobileActivity that is designed to save automobile input data to the cloud.
We have fragments like:
SedanFragment
TruckFragment
SportsUtilityFragment
These fragments take up the entire view of the Activity and only one is displayed at a time. While these fragments use methods in the Activity to call common webservices like saving automobile information, getting car information. They also do different things like the Truck may have an additional entry to set the "Bed Size" and SportsUtilityFragment may have "Tow Limit" etc.
So in a way we are leveraging a lot of re-use and modularizing, but it's not exactly what the Android API is detailing. Is this a bad way to use Fragments?
This is a very objective question and this will have a lot of different answers. In my opinion what you are doing is correct. The reason behind this is that they have a set of common webservices. If we go by the mvc approach they can all have the same controller(for calling webservices), a model class(Superclass- vehicle) with separate models which inherit from this vehicle model class. By doing this you can have an additional entry parameter which will be present in these models. Your view, the fragments can easily call the instance of these models. If you modularize in this manner, you will be making life very easy for yourselves.

Downloading and parsing JSON files to update ArrayAdapters on demand

Well I have an app set up, In way that there are, let's say, 3 ListViews in three different fragments.
Now a server provides 3 JSON files, that contain information, one for each ListView, which I have to parse into objects or lists of objects, and use them to instantiate my custom ArrayAdapters to display information on the list views.
The problem is that Downloading and parsing are operations that should happen outside the GUI thread.
So I am looking for the most effective way to update these list views on demand (when a fragment is inflated or OnResume etc)
What I've tried already was to download the needed json file using an IntentService then send the downloaded buffer to the GUI thread using a ResponseHandler and Intents, and then passing that to a manager class that was responsible for parsing the buffers into objects and populating the views. To do that, I had to keep the Views and the ArrayAdapters as properties to that class and provide on demand update methods.
Now my questions are:
1) Is it possible to have the service download the JSON files, parse them into collections and somehow send ArrayList objects to the GUI thread?
2) If I have to keep the adapters and update them in the GUI thread, what is the most effective (and maybe elegant way) to have a manager class keep and update the ListViews and their ArrayAdapters easily?(Do I have to get a new instance of the ArrayAdapter each time the information is updated, or can I update the inner ArrayList only?)
I think I won't include any code, since this is about the project structure and the preferred ways to do things.If it's needed for some parts though I can always edit the question later.

Apache Wicket Repeaters: an overview

Wicket has many implementations of AbstractRepeaters: ListView, DataView, GridView, Loop, PropertyListView etc.
Personally, I find it hard to determine which view would be ideal for which scenario. I usually stick to DataView but that's simply because I'm used to it. Maybe GridView would be better for scenario A, a PropertyListView for B, ....
Is anyone aware of a blog or any tutorial where the differences of the views are explained or anyone who can explain which view is best for which use case?
Wicket has a lot of additional, trivial classes, which is causing your confusion. Different components are better for different scenarios, but there are a lot of Wicket components for rare cases that don't add any real complexity.
For example, RequiredTextField is an entire class that is equivalent to:
TextField x = new TextField("text");
x.setRequired(true);
I presume this stems from an older version where setting required was more complicated, but it's still there to cause some confusion.
Many of your repeaters are similar. PropertyListView just wraps the model in a CompoundPropertyModel, making property expressions easier (see below). However, you could easily make this change yourself.
So, here is my quick summary as I have been unable to find an up-to-date blog post as you've described:
RepeatingView - very useful when you do not have a list or you are adding different types of components (and therefore different internal markup).
ListView - useful if you have a List and you're displaying the whole thing. Sadly, it does not work with other sorted collections.
DataView - useful if you are loading from a Database. Additional methods allow you to easily sort, page, and modify the data set.
PropertyListView - useful if you are simply displaying values via a property expression. Allows you to do
item.add(new Label("name"));
instead of
item.add(new Label("name", new PropertyModel<String>(item.getModel(), "name")))
Loop - useful if you want to repeat an Integer number of times instead of a set list of data. This would be equivalent to a ListView whose model object is a List<Integer> filled with integers from 0 to length
GridView - useful for taking a single list (e.g. 21 strings) and using two sets of markup (inner/outer) to display that list in groups (e.g. a 7x3 grid). It assumes, however, that your markup uses certain wicket:id's, which is not well documented. I think you would be better off with a pair of nested RepeatingView components, which accomplish the same thing.
Hope that helps!

Categories