I'm working on an app consists of
three Buttons to enter three different Fragments, each of them contains a List. when you press on the toggle Button next to any ListItem it is added to a SQLite database.
Button for Summary contains three lists to populate saved data from each Fragment.
My problem is (for example how can I retrieve saved data from fragment_one ONLY to the listView_one in the Summary activity) ?
N.B. all the data are of the same type (from the same model) and the saved ones got saved in the same database.
I've searched and found that I should use Fragment tag during FragmentTransaction..
What should I do after I set a tag for each Fragment?
When should I check the tag to populate the data correctly?
Sorry for that long question but i'm little overwhelmed and got stuck at this point.
If I understand correctly your problem, we have 2 ways to do this:
add a tag column in your db, then you can retrieve saved value from each fragment with your desired tag.
create a singleton manage each fragment saved data, etc:
public class DataManager {
// singleton implementation
...
private List mFragmentOneSavedData; // just save db row id to query later
...
}
Thanks.
Related
I will take an example to explain my problem : in a search screen, I need to search for a big list of movies.
I can bookmark each movie, so I need to notify my item in my recycler, here is my problem.
Do I need to put every movies searched in room database and it will be simple after for the notify with MVVM & DiffUtils?
Because, when I used MVP, I created a small database with MovieId and a boolean for bookmark, and when the user bookmark a movie, I run through in my items in adapter and notify the concerned item. But this solution is very ugly now with MVVM.
Thanks in advance
Just for the search screen you don't need to save data to local database. Instead of that you can just bind one list to RecyclerView and update it with another list from API using DiffUtils.
I have ListView that is populated like so:
ArrayList<MyFullDataClass> myFullDataClassList = Utilities.getDataFromSQLite(getActivity()); // populate list from SQLite
ArrayAdapter<MyFullDataClass> adapter = new ArrayAdapter<MyFullDataClass>(getActivity(), android.R.layout.simple_list_item_1, MyFullDataClassList);
setListAdapter(adapter);
MyFullDataClass contains many things: Name, address, phone, email, web site, etc. So as it is, each row of the list contains all of this information. It's a little busy. I would like to make it so that each row in the list contains only, say, name and email (and then touching the row would popup with all information in MyFullDataClass)
I could do this by creating a class, call it MyPartialDataClass, that contains fields for only name and email, then create an ArrayList<MyPartialDataClass> and copy data from myFullDataClassList to myPartialDataClassList and use this partial class for the adapter. (Then when a row is clicked, use myFullDataClassList.)
Not particularly elegant, but it would work.
Is there a better way?
I don't think there's a need to have two separate classes which ultimately hold the same information.
Having one class to hold necessary information is fine, unless you absolutely need minute efficiency gains of having two classes. What I would do is make your Adapter take a MyFullDataClass object list, but only populate the views with name and email.
From there, you can listen for an onClick event on your Adapter and pass the MyFullDataClass object associated with the clicked view to a fragment which will display the rest of the information associated with the MyFullDataClass object (i.e. the fragment will display address, phone, etc in addition to name and email).
You wouldn't make two separate tables in a database to hold parts of the same information. You would select what rows/properties from each entry that you need. The same concept applies here, IMO.
I have a Google's NavigationDrawer which adds/replaces fragments. One of fragments has a listView filled with custom BaseAdapter by network request (asyncTask, takes times). What i want is to save listView contents somewhere so if user navigates to another fragment through navigationDrawer and then or later navigates back to the fragment containing listView - i want a listView to be populated immediately with saved old content before asyncTask finished loading new content. Minimum API is 10.
What did i try.
onSaveInstanceState - serialize Parcelable ArrayList<CustomObject>. Somehow i didn't get it working. Also, that isn't solving my problem however, because onSaveInstaceState doesn't triggers on navigating through navigationDrawer.
Setting new fragment's InitialState(setInitialSavedState) then saving(saveFragmentInstanceSate)/loading it. That works for simple Views like EditTexts and TextView, but didn't get it working for the listView.
What is a best way to save listView contents? Please help me.
First get all items of list view.
CustomListViewAdapter listadapter = (CustomListViewAdapter) listview.getAdapter();
ArrayList<CustomObject> object=new ArrayList<CustomObject>();
for(int position=0;position<listadapter.getCount();position++)
object.add(videoadapter.getItem(position));
Now Use the object to store the items of the listview
Then use shared preferences to save the object.
Android ArrayList of custom objects - Save to SharedPreferences - Serializable?
The proper way to do this is to save your network query results in a database (sqlite), and use data from that db to display items in your list (CursorAdapter works best for this).
These tutorials nicely explain how to make your own Content Provider using Sqlite, and use a CursorAdapter to display your data on a list.
http://docs.xamarin.com/guides/android/user_interface/working_with_listviews_and_adapters/part_4_-_using_cursoradapters/
http://www.vogella.com/tutorials/AndroidSQLite/article.html
I found a good way.
String list_items = ""; // all your items are here, but separate it with a comma (,)
String[] list = list_items.separate(",");
And save the list_items in a shared preference. To retrieve just use getString() and use the code above
I am having 2 activities:
1st Activity contains 2 arrays which are filled up with the data by making call to a webservice. And both the arrays are used to display data in ListView. On clicking on any List Item, i am opening new activity Activity-2, here i am posting data related with that selected List-item.
But i am facing trouble when i return from Activity-2 to Activity-1 , it agains goes to fetch data from Webservice into Array(Instead of, It should go for fetching data if there is anything posted from 2nd activity otherwise it should get preserved arrays value). So my question is how do i preserve value of both the arrays so that i remains preserve the same value. so it does not have to go for fetching again and again.
(I think i need to use the "Save activity state" kind of concept, but i didnt have implemented such concept yet, so please if you know such then pls let me know for the same.)
Update:
I have added "(Instead of, It should go for fetching data if there is anything posted from 2nd activity otherwise it should get preserved arrays value)"
You can put them the values you retrieved in the Bundle passed to onSaveInstanceState:
#Override
protected void onSaveInstanceState(Bundle outState) {
// Put your values into outState
outState.putStringArray("my.project.str.array", stringArray);
outState.putStringArrayList("my.proj.str.array.list", strArrayList);
// read the documentation on Bundles to see complete
// list of values you can put in
super.onSaveInstanceState(outState);
}
And then you can retrieve them back via onRestoreInstanceState.
EDIT: You can put in more than one string array or string array list or whatever value, as long as the keys are different for each.
First off I'm really new to android (< 4 days).
I'm trying to wrap my head around how database data is linked to Views and widgets.
I've done a few tutorials and I've noticed that Adapters are used to link AdapterViews which are (as I understand it) Views which contain a bunch of identical subviews (eg lists, gallery, etc). So the Adapter is responsible for creating those subviews and populating the data for each one (correct me if I'm wrong).
Now let's say I have a list view which lists Hotels for example. Each row in the list has the Hotel's name and a basic rating (eg 5 star). Now when you tap on a hotel in the list a new activity shows up showing the details of that particular hotel. All the data is in a database. I understand that you have an adapter manage the data<->view link for the list, but what's the best way to then manage data for the hotel details view (which is not a list but just a couple of text views and an image for example)?
Is it best to just pass the ID in the intent and then have the details activity fetch the data from the DB on its own (in this case do I store the query in the details activity?)? Or do you get all the fields you need and put those in the intent directly? Do you need an adapter for a view which doesn't actually generate lots of similar subviews?
I guess a summary of my question is what do you use instead of an adapter when you're not dealing with adapterviews but just simple straightforward single views.
Thanks for any help you can provide.
Is it best to just pass the ID in the intent and then have the details activity fetch the data from the DB
on its own (in this case do I store the query in the details activity?)?
That is what I would recommend.
Do you need an adapter for a view which doesn't actually generate lots of similar subviews?
No. You only use an Adapter with an AdapterView (ListView, Spinner, etc.)
I guess a summary of my question is what do you use instead of an adapter when you're not dealing with
adapterviews but just simple straightforward single views.
Just the Cursor from the database. Get the fields from the (one) row in the Cursor, put them in the EditText widgets, and when the user makes changes, update the row.
#CommonsWare is bang on. As a code example, I was able to DRY things up by creating a helper method to dynamically set the TextViews a little cleaner.
In my onCreate() I have a number of the following lines:
bindTextView(hotel, "uid"); // `hotel` is the Hotel object with attributes.
And then I define bindTextView() below as follows:
protected void bindTextView( Hotel hotel, String attribute ) {
try {
// Get field for object dynamically.
Field field = hotel.getClass().getField(attribute);
// Invoke field "getter" method to get value.
String value = field.get(hotel).toString();
// Get resource id dynamically.
int resourceId = R.id.class.getField(attribute).getInt(null);
// Get element with resource id.
TextView element = (TextView) this.findViewById( resourceId );
// Finally, set the element's text value.
element.setText( value );
} catch (IllegalAccessException e) { e.printStackTrace();
} catch (NoSuchFieldException e) { e.printStackTrace(); }
}
I actually moved this helper method to a base Activity class since it's shared amongst a number of different activities.
I hope that helps some people keep their activities clean.
JP