I did a query in a database and return it inside a list that i put on a custom adapter and then i put in a listview.
Works fine until i use the onItemClikListener. I want to get the column "_id" from the query and i don't know how to do it (i want to pass this id as parameter for another activity).
I tried getItemId from my custom adapter but it returns the position on the list, not the column "_id".
Ex.: my query select * where name = x; return rows with id 1 and 3...but the getItemId make it position 1="_id1" and 2="_id3"...and when i pass it no another activity the query returns the rows with the "_id" 1 and 2;
//Here i get the item position and pass to another activity
listagem.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1,int position, long id) {
String Column_id = String.valueOf(adapter.getItemId(position));
Intent mostraLetra = new Intent(musica.this.getActivity(), ExibeMusica.class);
mostraLetra.putExtra("id", Column_id);
startActivity(mostraLetra);
}
});
//Here i pass the Id when i click on a item on the list
public String[] exibeMusica(String idMusica){
String r = idMusica;
String[] resultado = {};
Cursor resul = bancodados.query(Tabela_musica, new String[] {"_id", "Musica","Cantor","letra_musica","cat_oracao","cat_missa"}, "_Id = " +r+"", null, null, null, null, null);
resul.moveToFirst();
resultado[0] = String.valueOf(resul.getString(resul.getColumnIndex("_id")));
resultado[1] = resul.getString(resul.getColumnIndex("Musica"));
resultado[2] = resul.getString(resul.getColumnIndex("Cantor"));
resultado[3] = resul.getString(resul.getColumnIndex("letra_musica"));
resultado[4] = resul.getString(resul.getColumnIndex("cat_oracao"));
resultado[5] = resul.getString(resul.getColumnIndex("cat_missa"));
resul.close();
return resultado;
}
//This is my custom adapter
public class CustomAdapter extends BaseAdapter{
LayoutInflater inflater;
List<musica.ItemLista> itens;
public CustomAdapter(Activity a, List<musica.ItemLista> itens) {
super();
this.itens = itens;
this.inflater = (LayoutInflater)a.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
// TODO Auto-generated method stub
return itens.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
musica.ItemLista item = itens.get(position);
View vi = convertView;
if(convertView==null){
vi = inflater.inflate(R.layout.linha_listview, null);
TextView id = (TextView)vi.findViewById(R.linhaLista.id);
TextView musica = (TextView)vi.findViewById(R.linhaLista.musica);
TextView artista = (TextView)vi.findViewById(R.linhaLista.cantor);
ImageView oracao = (ImageView)vi.findViewById(R.linhaLista.cat_oracao);
ImageView missa = (ImageView)vi.findViewById(R.linhaLista.cat_missa);
id.setText(String.valueOf(item.id));
musica.setText(item.musica);
artista.setText(item.cantor);
String imgOra = item.oracao;
String imgMissa = item.missa;
if (imgOra.equals(null)) {
oracao.setImageResource(R.drawable.blank);
}else if(imgOra.equals("louvor")) {
oracao.setImageResource(R.drawable.louvor);
}else if(imgOra.equals("adoracao")) {
oracao.setImageResource(R.drawable.adoracao);
}
if (imgMissa.equals(null)) {
missa.setImageResource(R.drawable.blank);
}else if(imgOra.equals("louvor")) {
missa.setImageResource(R.drawable.louvor);
}else if(imgOra.equals("adoracao")) {
missa.setImageResource(R.drawable.adoracao);
}
}return vi;
}
}
Anyone can help me to get the correct "_id" ?
Set tag to the row view in getView of the adapter like this
.........
}
vi.setTag(String.valueOf(item.id))
return vi;
.........
and then
public void onItemClick(AdapterView<?> arg0, View arg1,int position, long id) {
String Column_id = (String) arg1.getTag();
......
While setting the linha_listview.xml in your CustomAdapter, you try to add one more textview to the linha_listview.xml like below:
<TextView
android:id="#+id/pid"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone" />
As you set this visibility to gone, it is no more visible on the listview. Later you set this textview by pidtextview.setText(column_id) in your getView() method. So, while clicking on the list item, get this column_id by
String pid = ((TextView) view.findViewById(R.id.pid)).getText().toString();
in your list item listener. By this above code, you would get the pid, Pass this to the other activity through intent.putExtra(); In that activity retrieve the data from getIntent() and retrieve the data of that particular row which contains that column_id and display that particular row details on that activity. Hope this helps. If you still get any doubts, get back.
write this code in onItemClickListner
resul.moveToPosition (position)
String Column_id = resul.getString(resul.getColumnIndex("_id");
Related
I am trying to obtain the database row id from the listview item in onItemClickListener when using a custom adapter.
I have tried getting the id from the "long id" inside of the onItemClickListener but it seems to return just the row id of the item in the actual list, not the database row id.
Here is my onItemClickListener:
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
String selected = (String)
mListView.getItemAtPosition(position);
mTextView = findViewById(R.id.Words);
mNumberTextView = findViewById(R.id.Number);
mId = id;
mAdapterView = adapterView;
mPositionForRow = position;
mCopied =
mHeaderNameTextView.getText().toString();
mNumberCopied = Integer.toString(mSelected + 1);
mNumberCopied =
mNumberTextView.getText().toString();
mPosition = position + 1;
mCopiedListItem = mBookCopied + " " +
mNumberCopied + ":" + mPosition + "\n\n" + selected;
showMenu(view);
}
});
Here is my custom adapter:
public Adapter(Context context, int resource1, List<String> lines) {
super(context, resource1, lines);
this.mContext = context;
this.mResource1 = resource1;
this.mLines = lines;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull
ViewGroup parent) {
View listItem = convertView;
int pos = position + 1;
if (listItem == null) {
listItem = LayoutInflater.from(mContext).inflate(mResource1,
parent, false);
}
mNumberTextView = (TextView)
listItem.findViewById(R.id.Number);
mNumberTextView.setText(String.valueOf(pos) + " ");
mTextView = (TextView) listItem.findViewById(R.id.Words);
mTextView.setText(mLines.get(position));
}
return listItem;
}
}
When a list item is clicked on, a menu pops up. If the user selects "select item", it should get the actual database row id from the item click but it returns the list item number which is not what I need. I also convert the long to an int in the process. I just didn't see a need to include that method.
Here is that menu option:
case R.id.select_item:
Log.d("TAG", "mId =" + mId);
mRowPositionInt = (safeLongToInt(mId));
updateData(1, mRowPositionInt);
Log.d("TAG", "mRowPosition =" + mRowPositionInt);
mSharedPreferences.edit().putInt("RowPositionSqlite",
mRowPositionInt).apply();
Toast toast2 = Toast.makeText(getApplicationContext(),
"Select Item Button Clicked!", Toast.LENGTH_SHORT);
toast2.show();
}
There are no error messages it just does not return the actual database row id. Any advice would be helpful. I have been through other posts but not applied to my situation. I appreciate your help.
The long id you get back is the long you return from your adapter's getItemId().
If you want a database row id to be return rather than just the position, you need to:
Pass in the database row ids to your adapter
Have getItemId() return the correct id for the given position.
My code goes here.............! when there is a row deleted from the list-view. The indexes of the rows of the listview is changed but the primary key id in the database is not changed. now when i click the item and pass the position of the clicked item of the listview to the new activity. And try to retrieve the record with that ID it does not return me something or incorrect data is returned. now my question is how can I detect the row id of the clicked item of listview in the database.
Now what should be code inside the onItemclick method to retrieve the correct rows from the database.
Thanks in anticiaption......!
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myDb = new DBHelper(this);
titles = myDb.getAllNames();
times = myDb.getAllTimes();
ArrayAdapter<String> ad = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, titles);
lv = (ListView) findViewById(R.id.listView1);
lv.setAdapter(ad);
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3)
{
}
});
}
First of all you have to write a query and retrieve id in your database.You must return the id in a cursor.
Refer the below code snippet:
public Cursor fetchAllNames() {
Cursor mCursor = app.myDbHelper.MyDB().query("cardlist", new String[] {"cardid as _id","cardname","carddesc"},
null, null, null, null, null);
try{
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}catch(Exception e)
{
return mCursor;
}
}
Then in your java page:
Cursor cursor = myDB.fetchAllNames();
Then you can get the database id by:
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3)
{
if(cursor!=null){
System.out.println("position===>"+position);
if(cursor.moveToFirst()){
cursor.moveToPosition(position);
String cardid = cursor.getString(cursor.getColumnIndex("_id"));
}
}
}
});
you will get the database id in the string cardid. You must use _id if you are using SimpleCursorAdapter else you must replace _id with that of the column name that represents your id in the sqlite database.
There's an easy way to achieve so :
First, create an object to represent one line in your database. Since I don't know what your database contains, let's just call it "Title".
public class Title {
private long id;
private String title;
// Constructor, setters and getters
}
Then, create a custom adapter. It will store a collection of Title which will allow you to get it when an item is clicked.
public class TitlesAdapter extends ArrayAdapter<Title> {
private Context context;
private List<Title> items;
public TitlesAdapter(Context context, List<Title> items) {
super(context, R.layout.row_draweritem, items);
this.context = context;
this.items = items;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) { /* ... */ }
}
You can then set your adapter in your activity easily:
this.titlesAdapter = new TitlesAdapter(context, titles);
listView.setAdapter(this.titlesAdapter);
... and define your onItemClickListener so you can get back the row id in your database
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
long id = titlesAdapter.getItems().get(i).getId();
}
});
You can learn more about custom adapters in this article : http://www.vogella.com/tutorials/AndroidListView/article.html
I have a SimpleCursorAdapter class, it gets various data from DB and displays in ListView. It implements an onclicklistener that sends a messageGuid String to another activity. All this works fine.
In the row of the ListView i have added a CheckBox and set an onCheckChangeListener to it. At the moment when the checkbox is checked, the messageGuid is always the last one in the cursor.
I need to find a way to get the listview row id of the row which hold the checkbox that has been checked. I can then get the correct cursor row and then in turn the correct messageGuid.
I've commented what i would like within the onCheckedChanged method.
Thanks in advance Matt.
private class MyAdapter extends SimpleCursorAdapter implements OnItemClickListener {
Cursor c;
String messageGuid;
public MyAdapter(Context context, int layout, Cursor c, String[] from,
int[] to) {
super(context, layout, c, from, to);
}
#Override
public
View getView(int position, View convertView, ViewGroup parent) {
Log.e(TAG, "inside myadapter getview for messages");
View v = super.getView(position, convertView, parent);
if(v == null)
return null;
c = (Cursor)getItem(position);
Log.e(TAG, "(Cursor)getItem(position) = " + c + "position = " + position);
v.setTag(c);
//other code removed, not relevant
String messageSender = c.getString(c.getColumnIndex(LoginValidate.C_MESSAGE_SENDER));
String isRepliedTo = c.getString(c.getColumnIndex(LoginValidate.C_MESSAGE_REPLIED));
String isStandAlone = c.getString(c.getColumnIndex(LoginValidate.C_MESSAGE_IS_STANDALONE));
((TextView)v.findViewById(R.id.messagecreatedat)).setText(formattedMessCreatedAt );
((TextView)v.findViewById(R.id.messagetext)).setText(messageText);
((TextView)v.findViewById(R.id.messagesender)).setText(messageSender);
//#003F87 = blue
((TextView)v.findViewById(R.id.messagecreatedat)).setTextColor(Color.parseColor("#003F87"));
((TextView)v.findViewById(R.id.messagesender)).setTextColor(Color.parseColor("#003F87"));
((TextView)v.findViewById(R.id.messagetext)).setTextColor(Color.parseColor("#FF0000"));
CheckBox cb = ((CheckBox)v.findViewById(R.id.list_checkbox));
cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//i'd like to something like below where i can specify the row which contains
//the checkbox that has been check and map that to the row in the cursor.
// So if the checkbox in the 2nd row in the listview has been clicked then the messageGuid from the 2nd row in the cursor is found
//c.moveToPosition(the row position of the listview which holds the checkbox that has been clicked );
messageGuid = null;
messageGuid = c.getString(c.getColumnIndex(LoginValidate.C_MESSAGE_GUID));
if(isChecked == true){
Log.e(TAG, "checkBox true and guid = " + messageGuid);
}else{
Log.e(TAG, "checkBox false and guid = " + messageGuid);
}
}
});
return v;
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int pos,
long id) {
Cursor itemCursor = (Cursor) view.getTag();
String messageGuid = itemCursor.getString(itemCursor.getColumnIndex(LoginValidate.C_MESSAGE_GUID));
String messageText = itemCursor.getString(itemCursor.getColumnIndex(LoginValidate.C_MESSAGE_TEXT));
String messageCreatedAt = itemCursor.getString(itemCursor.getColumnIndex(LoginValidate.C_MESSAGE_CREATED_AT));
String messageSender = itemCursor.getString(itemCursor.getColumnIndex(LoginValidate.C_MESSAGE_SENDER));
String messageReplied = itemCursor.getString(itemCursor.getColumnIndex(LoginValidate.C_MESSAGE_REPLIED));
String messageSeen = itemCursor.getString(itemCursor.getColumnIndex(LoginValidate.C_MESSAGE_SEEN));
String isStandAlone = itemCursor.getString(itemCursor.getColumnIndex(LoginValidate.C_MESSAGE_IS_STANDALONE));
Intent i = new Intent(ViewMessagesActivity.this, ReplyToMessageActivity.class);
i.putExtra("guid", messageGuid);
i.putExtra("message", messageText);
i.putExtra("createdat", messageCreatedAt);
i.putExtra("sender", messageSender);
i.putExtra("messagereplied", messageReplied);
i.putExtra("messageseen", messageSeen);
i.putExtra("isstandalone", isStandAlone);
startActivity(i);
}
}// end of adapter
Make position final and use that on onCheckedChanged
or
make cb final
Add before cb.setOnCheckedChangeListener
cb.setTag(position);
And in public void onCheckedChanged you can retrieve the position
int pos = (Integer) cb.getTag();
I have a listview populated with items retrieved from database (mysql). all is working fine and data is showing as required. Now is the time for the last step: when an item on the table is clicked, it should load more details on that item in next page. This is simple enough I believe. If I can get the id of the element based on database table, then I can query on next screen and load data easily.
The problem is how can I get the id of the item as it is on the mysql table? below is my adapter and list code:
this is the adapterview method that does most of the work:
#Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
// TODO Auto-generated method stub
if(arg1==null)
arg1 = layoutInflator.inflate(R.layout.simplerow ,arg2, false);
TextView name = (TextView)arg1.findViewById(R.id.nameTxtView);
TextView rate = (TextView)arg1.findViewById(R.id.rateTxtView);
//name.setText(discountObjectArray[arg0].name + "---> " + discountObjectArray[arg0].location + "---> " +discountObjectArray[arg0].rate);
String tempName = discountObjectArray[arg0].name;
tempName = ellipsize(tempName, 6);
name.setText(tempName);
rate.setText(discountObjectArray[arg0].rate);
return arg1;
}
public static String ellipsize(String input, int maxLength) {
if (input == null || input.length() <= maxLength) {
return input;
}
return input.substring(0, maxLength-1) + "...";
}
}
and this is the list code displaying a simple toast:
discountListingListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
RelativeLayout tempParent = (RelativeLayout) view;
TextView t = (TextView) tempParent.findViewById(R.id.nameTxtView);
Toast.makeText(getBaseContext(), t.getText(), Toast.LENGTH_LONG).show();
}
});
I am pretty new to android and appreciate your support
Keep the database id as an attribute of discountObjectArray element. Then in your adapter override this method:
#Override
public long getItemId(int position) {
return discountObjectArray[position].id;
}
Now the database id will be available as an "id" argument of onItemClick method.
You should use to ArrayList or List on your ArrayAdapter.. This;
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
String Name = discountObjectArray[position].name;
Toast.makeText(getBaseContext(), Name, Toast.LENGTH_LONG).show();
}
});
ok so i have an array adapted listview (the array adapting is done in another class).. i just got the click listener working for the list but now i want set it up so that when i click an item it pulls the strings from the clicked item and piggybacks them on the intent to a new activity.. i figure im supposed to use intent.putextra however im not sure how to pull the correct strings corresponding to the item that i click on.. my code is below.. im simply lost to be honest
//Initialize the ListView
lstTest = (ListView)findViewById(R.id.lstText);
//Initialize the ArrayList
alrts = new ArrayList<Alerts>();
//Initialize the array adapter notice with the listitems.xml layout
arrayAdapter = new AlertsAdapter(this, R.layout.listitems,alrts);
//Set the above adapter as the adapter for the list
lstTest.setAdapter(arrayAdapter);
//Set the click listener for the list
lstTest.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView adapterView, View view, int item, long arg3) {
Intent intent = new Intent(
HomePageActivity.this,
PromotionActivity.class
);
finish();
startActivity(intent);
}
});
my alerts class..
public class Alerts {
public String cityid;
public String promoterid;
public String promoshortcontent;
public String promocontent;
public String promotitle;
public String locationid;
public String cover;
#Override
public String toString() {
return "City: " +cityid+ " Promoter: " +promoterid+ "Short Promotion: " +promoshortcontent+ "Promotion: " +promocontent+ "Title: " +promotitle+ "Location: " +locationid+ "Cover: " +cover+ "$";
}
}
anddddd my alertsadapter class..
public class AlertsAdapter extends ArrayAdapter<Alerts> {
int resource;
String response;
Context context;
//Initialize adapter
public AlertsAdapter(Context context, int resource, List<Alerts> items) {
super(context, resource, items);
this.resource=resource;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
LinearLayout alertView;
//Get the current alert object
Alerts al = getItem(position);
//Inflate the view
if(convertView==null)
{
alertView = new LinearLayout(getContext());
String inflater = Context.LAYOUT_INFLATER_SERVICE;
LayoutInflater vi;
vi = (LayoutInflater)getContext().getSystemService(inflater);
vi.inflate(resource, alertView, true);
}
else
{
alertView = (LinearLayout) convertView;
}
//Get the text boxes from the listitem.xml file
TextView textPromo =(TextView)alertView.findViewById(R.id.txtPromo);
TextView textPromoter =(TextView)alertView.findViewById(R.id.txtPromoter);
TextView textLocation =(TextView)alertView.findViewById(R.id.txtLocation);
//Assign the appropriate data from our alert object above
textPromo.setText(al.promocontent);
textPromoter.setText(al.promoterid);
textLocation.setText(al.locationid);
return alertView;
}
}
You need to use the onItemClick event's parameters
a full more readable param enum with param name is
(AdapterView<?> parent, View view, int pos, long id)
that means you have the pos param that indicated the position in the adapter.
What you have to do is:
jump to pos in the adapter
read out the values from the adapter
use putExtra to signup for the intent
had an epiphany over the weekend about how to fix this problem and i finally found a good work around for my app.. i know it isnt optimal because i hard coded the number 100 into it but for my uses as of now i know i wont ever have that many list items..
i added these 2 bits of code to my alertsadapter class
int startzero = 0;
public static String[][] promomatrix = new String[6][100];
and
promomatrix[0][startzero] = al.cityid;
promomatrix[1][startzero] = al.promoterid;
promomatrix[2][startzero] = al.promocontent;
promomatrix[3][startzero] = al.promotitle;
promomatrix[4][startzero] = al.locationid;
promomatrix[5][startzero] = al.cover;
startzero++;
then went to my homepageactivity class and added this to the click listener
Intent intent = new Intent(
HomePageActivity.this,PromotionActivity.class);
intent.putExtra("listitemcity", AlertsAdapter.promomatrix[0][pos]);
intent.putExtra("listitempromoter", AlertsAdapter.promomatrix[1][pos]);
intent.putExtra("listitemcontent", AlertsAdapter.promomatrix[2][pos]);
intent.putExtra("listitemtitle", AlertsAdapter.promomatrix[3][pos]);
intent.putExtra("listitemlocation", AlertsAdapter.promomatrix[4][pos]);
intent.putExtra("listitemcover", AlertsAdapter.promomatrix[5][pos]);
finish();
startActivity(intent);
and finally went to my promotionactivity (where i was trying to send the strings) and added this
Bundle extras = getIntent().getExtras();
if (extras == null){
return;
}
String listitemcity = extras.getString("listitemcity");
String listitempromoter = extras.getString("listitempromoter");
String listitemcontent = extras.getString("listitemcontent");
String listitemtitle = extras.getString("listitemtitle");
String listitemlocation = extras.getString("listitemlocation");
String listitemcover = extras.getString("listitemcover");
worked like a charm.. i hope this helps someone :)