android: Identify individual items in row of ListView? - android

I have a ListView in a ListActivity populated by a database table. Each row of the ListView is a RelativeLayout with three TextViews named rowid, date, and name in that order. I am able to select individual rows programmatically using the .setSelection(int position) method of the ListView.
Here is what I'm trying to do: When I push a button on the interface, get the rowid from the currently selected list row, and perform a db query using the rowid. I can't figure out how to get the rowid from the list itself. rowid may not be the same as the ID or position on the list as it is the rowid in the database.
I suspect this will require working with an adapter, but I've been trying/searching the web for a week and haven't been able to figure this out. Thanks for the help anyone can provide.

You know the list position of the currently selected item, you have a button outside the ListView that should trigger some action on that item, and you're not just making the ListView rows (or some child view within each row) clickable. Right?
You can get information from the list's adapter. getItem(int position) returns the object that is represented by the list item at position, so you can retrieve the information you need directly if it's stored in the object. getView(int position) returns the view for the row, allowing you to use findViewById(int id) to retrieve your TextView.
If you don't already have the adapter, you can get it from the ListView using getAdapter().
// ListView myListView = the ListView in question
// int selectedRow = the currently selected row in the ListView
// Each row in the ListView is backed by an object of type MyCustomDataClass
int dbRowId;
Adapter adapter = myListView.getAdapter();
MyCustomDataClass data = (MyCustomDataClass) adapter.getItem(selectedRow);
dbRowId = data.getDatabaseRowId();
// OR
dbRowId = data.rowId;
// OR whatever method the object has for getting the ID.
// OR
View listViewRow = adapter.getView(selectedRow);
TextView dbRowView = (TextView) listViewRow.findViewById(R.id.rowid);
String dbRowAsString = dbRowView.getText().toString();
dbRowId = Integer.parseInt(dbRowAsString);
You might also consider whether it would be more natural for the user to just tap the ListView row, rather than selecting the row and then pressing another button. Reno's answer might work better.

I ended up using the last method with the following code.
int dbRowId;
Adapter adapter = myListView.getAdapter();
View listViewRow = adapter.getView(selectedRow);
TextView dbRowView = (TextView) listViewRow.findViewById(R.id.rowid, null, null);
String dbRowAsString = dbRowView.getText().toString();
dbRowId = Integer.parseInt(dbRowAsString);
The only change I had to make was adding null, null to the parameters in .findViewByID
TextView dbRowView = (TextView) listViewRow.findViewById(R.id.rowid, null, null);

Related

Accessing SQLite record from ListView item?

I display the user data from SQLite database using a custom CursorAdapter.
Each ListView item is actually a layout with many TextViews.
in the CursorAdapter.bindView() method I get database data from the Cursor, and display their modified, prettier versions to the user. Here's what I mean:
public void bindView(View view, Context context, Cursor cursor) {
//get listview items Views
TextView dayTextView = (TextView)view.findViewById(R.id.listview_item_day);
//...
//get data from cursor
int day = cursor.getInt(1);
//...
//display data nicely to the user
String sDay = "Day number " + String.valueOf(day) " was a very nice day";
dayTextView.setText(sDay);
}
I want that when the user long clicks an item (I'll use OnItemLongClickListener for that), the item will be deleted (easy peasy) but I also want to delete the day record from the database.
When the ListView item gets clicked, I have the next parameters supplied to me (in OnItemLongClickListener):
AdapterView<?> adapterView, View view, int position, long id
How do I get to the database record from all these parameters? I could use TextView.getText() and apply some string manipulation methods to the result (remember I added strings to the data before setting it in ListView), but I feel like there's another, more clever way.
You might use a List<Integer> days = new Arraylist<>(); to keep days you are modifying and so the index of the list alway will be same as position and you can get your day content by days.get(position) and get item from your database.
you should define your list out of bindView

Android - Add views to item in a ListView

What I want: I have a listview which lists all the entries of my sqlite database. The database contains all the items that a number of people have bought at a supermarket, so the listview displays all the items in the database. Now, an item can be shared by many users (infact the app is about to split the costs of a receipt) and I want that the names of who are going to shared that particular item must be displayed under that item in the listview.
Result using cursoradapter in a common way:
1) row1 item quantity price
2) row2 item quantity price
3) row3 item quantity price
4) ...
Resul I want:
1) row1 item quantity price name 1 name 2 2) row2 item quantity price name 4 name 7 3) row3 item quantity price name 2 4) ...
name rows are the textviews(http://pastebin.com/hzLPPV6B) I want do add
What I have tried to do:
bindView method of my CursorAdapter http://pastebin.com/4839LMq3
layout where the listview is http://pastebin.com/uVhy3GqN
layout of the single item in the listview http://pastebin.com/srsm7SRS
layout of the textviews(with the name) to add under the right item in the list view http://pastebin.com/hzLPPV6B
What the problem is: The problem is that the bindview method doesn't work as I expected and the app starts to display infinite(I think) number of person name textview(3rd pastebin link) under each item in the list(not only the persons names I wanted).
This is the that part of the code inside bindView which I am not sure about:
LinearLayout itemBuyersLinearLayout = (LinearLayout) view.findViewById(R.id.itemBuyersReceipt);
ArrayList<String> buyersName = dbManager.getBuyersNameOfItem(receiptId, cursorAdapter.getItemId(cursor.getPosition()));
for (int i=0;i<buyersName.size();i++) {
itemBuyersLinearLayout.addView(getLayoutInflater().inflate(R.layout.receipt_item_buyer_receipt, itemBuyersLinearLayout, false));
TextView buyerNameTextView = (TextView) itemBuyersLinearLayout.findViewById(R.id.itemBuyerReceipt);
buyerNameTextView.setText(buyersName.get(i));
}
I don't know what I have to do/where I need to add some code to add that extra information
When you are using CursorAdapter, the bindView method is used to bind data to a single row item and it does that for all rows. And what you are doing here is that you have a for loop that you use to bind all the data to a single row item.
I'm not sure how your database is set up, but you should bind it in a format like this:
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.YOUR_ROW_ITEM_XML, parent, false);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
TextView buyerNameTextView = (TextView) view.findViewById(R.id.itemBuyerReceipt);
String buyerName = cursor.getString(cursor.getColumnIndexOrThrow("YOUR_BUYER_NAME_COLUMN"));
buyerNameTextView.setText(buyerName);
}
Hope that can solve your problem. Good luck!

Dynamic ListView with dynamic graphic user interface [duplicate]

This question already exists:
Closed 10 years ago.
Possible Duplicate:
Dynamic ListView with dynamic GUI
I have to fetch the data from sqlite database. Database will contain countryname , card name and card id and status, I have to display countryname then list of cards dynamically for example if USA has four card then in list view it will display USA then all then four cards then UK then cards of UK and so on it should be implemented with check box for each item and if user clicks on suppose a card which is displaying in USA category then I have to update its status in database for example if a card in USA is checked then in database we have to update "yes" similar function for other cards .. So how to achieve this?
I think you are asking about dynamic list view with check box in its list's cell.
First of all you need an adapter for filling your list...Like This..
ListView listView=(ListView)findViewById(R.id.listView);
listView.setAdapter(new MyListAdapter (<Your ArrayList>));
Now when ever we use check box or editbox in list.Then when we scroll list it call its getview method every time. So we need to manage value or status of components. Here to manage status of checkbox I had used Arraylist of boolean type.
Make an XMl file for your list's cell. Put listeners for list's cell components inside getview method.
public class MyListAdapter extends BaseAdapter
{
private ArrayList<HashMap<String, String>> data;
private ArrayList<Boolean> checks=new ArrayList<Boolean>();
public MyListAdapter ( ArrayList<HashMap<String, String>> d)
{
data=d;
inflater = (LayoutInflater)baseActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for (int i = 0; i < d.size(); i++)
{
checks.add(i, false);//as first no check box is checked. So fill it with false value
}
}
public int getCount()
{
return data.size();
}
public Object getItem(int position)
{
return position;
}
public long getItemId(int position)
{
return position;
}
public View getView(int position, View convertView, ViewGroup parent)
{
View vi=convertView;
if(convertView==null)
vi = inflater.inflate(R.layout.list_row, null);
name = (TextView)vi.findViewById(R.id.name);// name
checkBox=(CheckBox)vi.findViewById(R.id.check_box);
email_id = (TextView)vi.findViewById(R.id.e_mail_id); // email ID
mobile_no = (TextView)vi.findViewById(R.id.mobile_no); // mobile
checkBox.setTag(Integer.valueOf(position));
checkBox.setOnClickListener(this);
checkBox.setChecked(checks.get(position));
name.setText(<set name form any data source>);
email_id.setText(<set emailid form any data source>);
mobile_no.setText(<set mobile form any data source>);
return vi;
}
}
Hope this should help you.
Cheers...
So in your case you have to implement Multiselect Expandable listview..
Okay, so what you need first of all is to create an xml file for each row in your ListView to be inflated.
So you have some textview for your country name etc. But now to the tricky part to adding dynamically those "cards" depending on the amount:
In your xml for each row, add a LinearLayout where you want the specified cards to appear, and then in the getView() method inside the ArrayAdapter (the custom one you've created) you need to do something like this:
cardsLayout = (LinearLayout) v.findViewById(R.id.cards_layout);
cardsLayout.removeAllViews(); // rows are reused in listview, so this prevent them to be duplicated
ImageView image;
for(int i = 0; i < country.getCards(); i++){ // I assume you're using array for cards of each country
image = new ImageView(ActivityName.this);
layoutParams = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT, 1.0f);
image.setLayoutParams(layoutParams);
image.setImageBitmap(someBitmapImage);
imageLayout.addView(image);
{
I assume you know how to create your own adapter. And this snippet of code just dynamically creates ImageViews and sets there weight to 1, so they will be equal in size through the row. If you need checkboxes or whatever, you can use the same approach by changing the ImageView to something else.

accessing an item in listview

I have a list of players whos name are displayed listview. and each row of listview contains button, textview and imageview. How can I get the value of textview?
If you are using Custom Adapter class to populate the listview,then in your adapter,you can use HashMap for saving key-value pair,saving position of listitem with the data into that textview.and then you can easily retrieve it on OnItemClickListener of listview.
Depending on the specifics of your implementation, I would go with one of the following approaches.
Option A.
Use setOnItemClickListener to register a click listener with the list (or if you're using a ListActivity or ListFragment simply use [onListItemClick](http://developer.android.com/reference/android/app/ListActivity.html#onListItemClick%28android.widget.ListView, android.view.View, int, long%29)). onItemClick gets passed in the View that was clicked and can be used to retrieve nested views, e.g. the TextView you're looking for.
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView tv = (TextView) view.findViewById(R.id.textview);
String tvText = tv.getText();
}
}
Option B
Assuming you fill your list from some sort of data collection, you may be able to do something similar to above, but use the passed position parameter as an index to directly get the text from the objects in your collection; i.e.:
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
SomeObject so = myCollection.get(position);
String tvText = so.getTextViewText();
}
}
There are lots of more options though. I kind of like creating my own extension of ArrayAdapter to hold the models for the views of the items in the list. That way you could also call getItemAtPosition(int position) or getItem(int position) and cast the returned object to your data type.
Is it a static list or a dynamically generated one? If its a static one you can assign a different id to each textview in the xml itself, and then use FindViewById to access it. If it's not this is what you've got to do: you will obviously have one row and display it many times. So multiple textviews will have same ID. Use a for loop, inside which use FindViewById(Remember FindViewByID will only access the first element with mentioned Id, set its Id to something else, in the next iteration the next textview is selected, set its Id to something) then use these new ids to access them, thus you can access each textview

Once a view is inflated dynamically as a list with a button attached to each row. How do I pass a row id to each of these buttons?

I have a list, this list is basically TableRows in scrollview which I have inflated with layout inflater, i.e. it depends at runtime, how many rows are being added. Now I have a button also attached in each row. This button is either a delete button or an edit button. Before programming I was thinking that I will just get the row id and call my delete function for that row id. But now when I program I see that I do not find a way to get the row id, because the button is just the same button always and how will button come to know with what row exactly it is linked to. I am basically doing database programming where I have taken lots of user input and displayed it in a table row inside a scroll view. But I don't know how do I get those rows. As of now I am not using any array list or array adapter. Do I need to use them either to solve my this problem ?
Please help.
I am entering the my code here
if(dbExists)
{
myName = (TextView)findViewById(R.id.myName);
db.open();
Cursor c = db.getAllTitles();
long NoOfRows = c.getCount(); //here I am gettin 30 as entered in database
while(NoOfRows >= 1)
{
c.moveToFirst();
//.........Inflate here name and number........
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View inflated = inflater.inflate(R.layout.name, myTableLayout);
TextView userName = (TextView)findViewById(R.id.myName);
userName.setText(c.getString(1));//here I am settng the user entered name
Button delButton = (Button)rowView.findViewById(R.id.Delete_Name);
delButton.setTag(RowId--);
delButton.setOnClickListener(this);
c.moveToNext();
NoOfRows--;
}
db.close();
}
#Override
public void onClick(View v) {
Long rowId = (Long)v.getTag();
if (rowId != null)
{
Toast.makeText(this, "rows get Tag() " + rowId, Toast.LENGTH_LONG).show();
//db.deleteTitle(rowId);
}
}
You can use setTag/getTag on a View so set and get special information for that view.
Using this you would call button.setTag(rowId) and then retrieve it later using getTag in your onClick method.
Here is a detailed answer with a code example.

Categories

Resources