Populating an ExpandableListView with data from database - java

I have a SQLite database that contains multiple tables. For each table, I am trying to represent all the data in an ExpandableListView using a custom CursorTreeAdapter. As far as I understand, the method getChildrenCursor returns a cursor that points to the data I needed to populate my child views. However, I do not have a concrete idea on how to retrieve the children cursor using the groupCursor parameter.
#Override
protected Cursor getChildrenCursor(Cursor groupCursor) {
String[] projection = { "columnNeeded" };
return context.getContentResolver()
.query(CONTENT_URI, projection, null, null, null);
}
the above method will return a cursor that returns all rows containing the column I need. Is this the right way to do this?
In the "columnNeeded" column for each row of the table, it contains a String representation of a jsonArray. I was trying to store an arrayList into each row of the table using JSONArray. Therefore, I am trying to retrieve this arrayList and populate the child views with this arrayList like so:
#Override
protected void bindChildView(View view, Context context, Cursor cursor, boolean isLastChild) {
TextView name = (TextView) view.findViewById(R.id.summary_child_name);
TextView bill = (TextView) view.findViewById(R.id.summary_child_bill);
String arrayListString = cursor
.getString(cursor.getColumnIndex("columnNeeded"));
JSONObject json = new JSONObject();
try {
json = new JSONObject(arrayListString);
} catch (JSONException e) {
Log.e(LOG_TAG, "Unable to retrieve list of items");
}
JSONArray jsonArray = json.optJSONArray(ReceiptContract.JSONARRAY_NAME);
// retrieveArrayList iterates through jsonArray and adds it to items
items = retrieveArrayList(jsonArray);
name.setText(What do I put here?);
bill.setText(What do I put here?);
}
As you can see I have managed to retrieve the entire array list as an ArrayList type object. However, I am stuck on displaying the array list in the child views. Any idea on how I can go about doing this?

Use HashMap to store your data as key value and populate your data into your ExpandableListView using BaseExpandableListAdapter

Related

Android get ArrayList from Room Database in adapter class

I have a Room Database table with multiple columns (PartsTable). I need to fetch only one column from the table that contains one word String and I'm using a subset of a table as per google docs (PartsTuple).
Now I need to create a function that will or something else that will return the ArrayList of fetched data, which I can access in my adapter class. I am able to return the data and see it in a console log (from the main fragment where I get data from ViewModel), but I just can't seem to make it work on a function that will return the said list of data which I could then access from a different class.
Code from DAO:
#Query("SELECT keyword FROM partsTable")
LiveData<List<PartsTuple>> getTuple();
Code from repo:
public LiveData<List<PartsTuple>> getPartsTuple() {
return partsKeyword;
}
Code from view model:
public LiveData<List<PartsTuple>> getPartsTuple() {
return partsKeyword;
}
Fragment class where I display data in a log:
mViewModel.getPartsTuple().observe(getViewLifecycleOwner(), new Observer<List<PartsTuple>>() {
#Override
public void onChanged(List<PartsTuple> partTuple) {
Log.d(TAG, "vraceno: " + partTuple.toString());
}
});
, and data from the log
D/PartsFragment: vraceno: [part1, parts3, part_2]
Code from adapter class where I compare strings and highlight them.
ArrayTEST arrayTEST = new ArrayTEST();
ArrayList<String> values = arrayTEST.getWordFromHardcodedList();
String text = note.getPartsSubtitle();
Spannable textSpannable = new SpannableString(text);
for (int j = 0; j < values.size(); j++) {
//word of list
String word = String.valueOf(values.get(j));
//find index of words
for (int i = -1; (i = text.indexOf(word, i + 1)) != -1; i++) {
//find the length of word for set color
int last = i + word.length();
textSpannable.setSpan(new BackgroundColorSpan(Color.parseColor("#1a0cab8f")),
i, last, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textSpannable.setSpan(new ForegroundColorSpan(Color.RED),
i, last, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
if (note.getPartsSubtitle().trim().isEmpty()) {
tvTEXT.setVisibility(View.GONE);
} else {
tvTEXT.setText(textSpannable);
}
The part that I'm having trouble with is this, where I need to get a list of data from database and not hardCoded like this
arrayTEST.getWordFromHardcodedList();
Now I need to access this list of data from my adapter class since if there is a match I wanna highlight the parts from the list of parts in my main recycler view where all the data is shown. I can do this when I type the list manually but it needs to be dynamic based on user input.
Thanks in advance
In your adapter class add a field for this list - I'll call it highlightedParts. Observe getPartsTuple() as you do, and set the data you get to highlightedParts. Then you need to create a custom setter for highlightedParts and every time it gets called, update elements of the RecyclerView to highlight the desired items. For updating, you can use notifyDataSetChanged() method. There are other, more optimized variations for only updating a specific item or item range, but you're going to have to update entire dataset.
Ended up using shared preferences with Gson.
In app gradle add
implementation 'com.google.code.gson:gson:2.8.6'
Save the data to SP in a fragment:
SharedPreferences sharedPreferences = requireActivity().getSharedPreferences("shared_preferences", MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
Gson gson = new Gson();
String json = gson.toJson(myListOfData);
editor.putString("partsKEY", json);
editor.apply();
Load the array in the adapter class:
SharedPreferences sharedPreferences = context.getSharedPreferences("shared_preferences", MODE_PRIVATE);
Gson gson = new Gson();
String json = sharedPreferences.getString("partsKEY", null);
Type type = new TypeToken<ArrayList<NoteTupleTest>>() {
}.getType();
partsArrayList= gson.fromJson(json, type);
if (partsArrayList== null) {
partsArrayList= new ArrayList<>();
}

How do I get String values on listview from the ArrayList<String[]>?

Hi I had asked before how do I update listview and got suggestion to make use of ArrayAdapter.I follow the thing now the issue is about it's updating listviews but not with expected values some object .
My code is like this:
Cursor cursor = db.rawQuery("SELECT count(*) FROM BOOKMARKS ", null);
//if any contact found moveToFirst of that contacts or points to 1st email
cursor.moveToFirst();
//checking columns exhist or not
if (cursor.getInt(0) > 0)
{
//get all the contacts from table 'BOOKMARKS'
c = db.rawQuery("SELECT * FROM BOOKMARKS", null);
//get the index of mentiond and required columns
ID = c.getColumnIndex("ID");
booktitl = c.getColumnIndex("Booktiltle");
audiotime=c.getColumnIndex("BookmarkTime");
// Check result.
c.moveToFirst();
if (c != null)
{
// Loop through all Results
do
{
cont = new String[3];
cont[0] = Integer.toString(c.getInt(ID));
cont[1] = c.getString(booktitl);
cont[2] = c.getString(audiotime);
audiobooks.add(cont);
}
while(c.moveToNext());
c.close();
db.close();//close db resources
ArrayAdapter<String[]> arrayAdapter1=new ArrayAdapter<String[]>(this, R.layout.row3, R.id.itemr1,audiobooks);
lv.setAdapter(arrayAdapter1);
How do i get the string value on listview?Actually the values fetching from database and storing into Arraylist.At present I am displaying some object value on listview but I want to display content that "audiobooks" holds. Please help me to solve it.
You can't give the ArrayAdapter the type String[], because you're giving it a List called audiobooks.
Also, I'm not sure if the standard ArrayAdapter can handle a datatype List<String[]>. It might not work. You would have to make your own implementation of the ArrayAdapter by extending it, if it shouldn't work.
If I understand correctly, you want to populate a ListView with data from each row from your database. You must create a new class of type Audiobook with the member variables corresponding with database row. Then create a layout in your res/layouts folder that must show your object's data. Create a new class extending ArrayAdapter class, in which you inflate views with created layout and populate listview with childs. Then in your main you set the new adapter to the list.
The ArrayAdapter should look like this:
public class AudiobookAdapter extends ArrayAdapter<Audiobook> {
// constructor
// here you populate each view and put it in listview
public View getView (int position, View convertView, ViewGroup parent)
{
}
}
This is a start line, you should read more about extending arrayadapters and custom ListViews.

Android: Multiple Dimensional array - java

I've got an array coming in from a cursor in a function from a sqlite database. I'd like to add multiple items to the array to make it easier to bring data in from other pages. I.e. I'd like to do mArray("ID"), mArray("Name") (i'll be populating a listview from an array of the function, and would like to have easy access to name from ID)
Here is my code at the moment which only saves the ID in the array:
public static Array GetRooms(String StationID) {
File dbfile = new File(Global.currentDBfull);
SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbfile, null);
Cursor c = db.rawQuery("select * from StationObjects where ObjectID = 0 and StationID = " + StationID , null);
c.moveToFirst();
Log.e("TomDebug", c.getString(c.getColumnIndex("SubGroupName")));
ArrayList<String> mArrayList = new ArrayList<String>();
c.moveToFirst();
while(!c.isAfterLast()) {
mArrayList.add(c.getString(c.getColumnIndex("SubGroupName")));
c.moveToNext();
}
return null;
}
Edit: To give a bit of clarity;
In psudocode i'd like to be able to do:
while(!c.isAfterLast()) {
mArrayList.name.add(c.getString(c.getColumnIndex("Name")));
mArrayList.type.add(c.getString(c.getColumnIndex("Type")));
mArrayList.ID.add(c.getString(c.getColumnIndex("ID")));
c.moveToNext();
}
So that anywhere in the code i can do
Array curRooms = GetRooms("1234")
String name = curRooms.Name
String type = curRooms.Type
(i know the mix between array and string wont work there, but just an example)
It sounds like you want an actual data structure instead of a string. There are a few ways of doing this, with ORMs and whatnot, but a basic example would be something like this, that you can fill the fields in from the database.
public class StationObject
{
public String name;
public String type;
public String id;
}
//pseudocode
for each result in resultset
fill temp StationObject with fields
add temp to list

Showing database in ListView

I am new to android and after going through many tutorials I still can't get things.
I have created a database and is now reading this database.
This database and 3 columns All three string type.
Now I want to show this database using ListView.I have this ListView
created with id "listDatabaseItems" in R.layout.viewDatabase
Currently my code is:
Cursor c = sqliteDatabase.query(MY_DATABASE_TABLE, null, null, null, null, null, null);
int firstNameColumn = c.getColumnIndex("name_column");
int protectedColumn = c.getColumnIndex("protected_id_column");
ArrayList<String> results = new ArrayList<String>();
int i = 0;
c.moveToFirst();
do {
i++;
String firstName = c.getString(firstNameColumn);
String protectedID = c.getString(protectedColumn);
results.add(firstName + protectedID); // NEED TO add here
} while (c.moveToNext());
sqliteDatabase.close();
Please tell me what changes I do and how can I show my database in ListView.
Best Regards.
Make a Adapter add your ListArray values to it, and then setAdapter to your listview simple,
After your code, add just two lines,
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, results);
mListView.setAdapter(adapter);
Also, your question sounds basic for android So just look at these links..
SimpleCursorAdapters and ListViews
Android SQLite Database and ContentProvider - Tutorial
Filling the Layout with Data
Since you're using a Cursor in the first place, I'd actually go with a SimpleCursorAdapter. A CursorAdapter allows you to avoid loading the whole data set into memory, making initial load times faster and avoiding huge allocations with large data sets.
To expand on the basic setup in this post (SimpleCursorAdapters and ListViews), You'll also want to set a view binder to customize the way data is bound to the view, ie. concatenate your two strings.
Something like this:
SimpleCursorAdapter.ViewBinder binder = new SimpleCursorAdapter.ViewBinder() {
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
//you're only using one view, so we can ignore columnIndex
TextView text = view.findViewById(R.id.list_item_text);
//the cursor is already in position for this list item
int firstNameColumn = c.getColumnIndex("name_column");
int protectedColumn = c.getColumnIndex("protected_id_column");
String firstName = c.getString(firstNameColumn);
String protectedID = c.getString(protectedColumn);
text.setText(firstName+protectedID);
return true; //we have handled binding the data
}
};
Then when you set up your adapter, you pass it a layout that can be used for each item. The layout should contain a TextView to hold the one text item you want to show. You may be able to use android.R.layout.simple_list_item_1 for this as user370305 suggested, but I'm not sure what the id of its TextView is -- it might be android.R.id.text1.
SimpleCursorAdapter adapter = new SimpleCursorAdapter(
context, //can be your Activity
R.layout.list_item, //xml layout containing textview with id 'list_item_text'
c, //the cursor
new String[] {"name_column"}, //the column to read (we'll do more in the binder)
new int[] {R.id.list_item_text}, //the view to hold the data
0 //no flags
);
adapter.setViewBinder(binder);
Add it to your ListView the same way:
ListView listView = //your ListView reference
listView.setAdapter(adapter);
//or in a ListActivity:
setListAdapter(adapter);

Android: replace values of a cursor/sql query

In my SQL database table there are colums _id, int dayofweek, String text ...
I now, do a SQL query on that table to get a cursor to the results.
The results then are shown in a listView:
private void showBlocks()
{
Cursor blocks = ttDB.getBlocks();
startManagingCursor(blocks);
int[] key = new int []{
android.R.id.text1,
android.R.id.text2
};
SimpleCursorAdapter blockAdapter = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_2,
blocks,
new String[] {
"day",
"text"
},
key);
lv1.setAdapter(blockAdapter);
}
How (and where) can I now replace the integer values of dayofweek by the corresponding strings? I thought about joining two tables while querying but then it will not be multilingual any more.
You can try using a ViewBinder via setViewBinder() on your SimpleCursorAdapter.
Or, extend SimpleCursorAdapter, override bindView() and do it yourself.
you can not directly replace values .you have to store first it in list and than you can replace it with ur desired fromat

Categories