I have a listView which I populate from contentUri1 using loader1/adapter1.
What I now need to do is monitor contentUri2 with loader2 in order to update the items in the same listView with additional data.
So in order to do this, I am wondering if there any way I can select elements from listView by their underlying database table ID (as the database table IDs are common for contentUri1 and contentUri2)?
(A workaround I have considered is to create and use a single contentUri3 that consolidates the data from contentUri1 and contentUri2 but I would rather not have to take this approach if avoidable.)
Any other workarounds/suggestions also appreciated.
Yes you can create a Model class that contains the contentUri and the ids. Something like:
public class ListContents {
private Uri contentUri;
private int id;
public ListContents(Uri contentUri, int id) {
this.contentUri = contentUri;
this.id = id;
}
public Uri getContentUri() {
return this.uri:
}
public int getId() {
return this.id;
}
}
You can then create an ArrayList of this class and you will be able to retrieve ids associated with every contentUri. Hope this helps
You can use an invisible textView to store the value of the id.
ArrayList<HashMap<String, String>> hashExample = new ArrayList<>();
Integer id = 1 ;
String value = "value";
HashMap<Integer, String> map = new HashMap<>();
map.put("ID", "" + id);
map.put("VALUE", value);
hashExample.add(map);
String[] from = {"ID", "VALUE"};
int[] to = {R.id.txtID, R.id.txtValue};
adapter = new SimpleAdapter(getActivity(), hashExample,
R.layout.list_item_example, from, to);
ListView list = (ListView) getView().findViewById(R.id.listView);
list.setAdapter(adapter);
To retrieve the data, implement this in on onItemClickListener or something
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
Integer id = Integer.valueOf(((Map<String, String>) adapter.getItem(arg2)).get("ID"));
String value= ((Map<String, String>) adapter.getItem(arg2)).get("VALUE");
}
});
Hope it helps.
Wherever you are populating your listView add the tags to the individual items:
YourListItemView.setTag(YourTagKey, YourTagValue);
Then, when you need it, call getTag on the view to retrieve the tag:
String tagValue = YourListItemView.getTag(YourTagKey);
Related
Hi I have been working through several different tutorials on getting data from a sql database into a listview. I can add data, get data from database and populate the list view, and have a working onclick listener (will fire off a Toast message). However I can not get any data from the listview when clicked. I have tried different combinations of getitem and getItemAtPosition but they all return a empty string(blank toast). Would someone be kind enough to look at my code and tell me if what I am trying to do is possible. In my listview i have four items in each entry, I would like to either get the fourth item directly or get all the items (as string?) then I can pull out the data I need.
Thanks in advance for your time.
public class ListViewActivity extends Activity {
SQLiteHelper SQLITEHELPER;
SQLiteDatabase SQLITEDATABASE;
Cursor cursor;
SQLiteListAdapter ListAdapter ;
ArrayList<String> ID_ArrayList = new ArrayList<String>();
ArrayList<String> GENRE_ArrayList = new ArrayList<String>();
ArrayList<String> NAME_ArrayList = new ArrayList<String>();
ArrayList<String> URL_ArrayList = new ArrayList<String>();
ListView LISTVIEW;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_view);
LISTVIEW = (ListView) findViewById(R.id.listView1);
SQLITEHELPER = new SQLiteHelper(this);
}
#Override
protected void onResume() {
ShowSQLiteDBdata() ;
super.onResume();
}
private void ShowSQLiteDBdata() {
SQLITEDATABASE = SQLITEHELPER.getWritableDatabase();
cursor = SQLITEDATABASE.rawQuery("SELECT * FROM demoTable1", null);
ID_ArrayList.clear();
GENRE_ArrayList.clear();
NAME_ArrayList.clear();
URL_ArrayList.clear();
if (cursor.moveToFirst()) {
do {
ID_ArrayList.add(cursor.getString(cursor.getColumnIndex(SQLiteHelper.KEY_ID)));
GENRE_ArrayList.add(cursor.getString(cursor.getColumnIndex(SQLiteHelper.KEY_Genre)));
NAME_ArrayList.add(cursor.getString(cursor.getColumnIndex(SQLiteHelper.KEY_Name)));
URL_ArrayList.add(cursor.getString(cursor.getColumnIndex(SQLiteHelper.KEY_Url)));
} while (cursor.moveToNext());
}
ListAdapter = new SQLiteListAdapter(ListViewActivity.this,
ID_ArrayList,
GENRE_ArrayList,
NAME_ArrayList,
URL_ArrayList
);
LISTVIEW.setAdapter(ListAdapter);
LISTVIEW.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// String text = (String) LISTVIEW.getAdapter().getItem(position);
String text = (String) LISTVIEW.getItemAtPosition(position);
//String text = (String) lv.getItemAtPosition(0);
// Object item = (Object) LISTVIEW.getItemAtPosition(position);
Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
}
});
cursor.close();
}
}
LISTVIEW.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
String value1 = ID_ArrayList.get(position);
String value2 = GENRE_ArrayList.get(position);
String value3 = NAME_ArrayList.get(position);
String value4 = URL_ArrayList.get(position);
Toast.makeText(getApplicationContext(),value1+" "+value2+" "+value3+" "+value4, Toast.LENGTH_SHORT).show();
}
});
try to change the line
String text = (String) LISTVIEW.getItemAtPosition(position);
with
String text = (String) parent.getItemAtPosition(position);
this should be the way ListView works.
Also i suggest you to not use Capital Cases with variables, usually in Java is used a CamelCase convention. And also have a look at RecyclerView, that usually is implemented today much more than ListView, because allow a great level of customization
Pls use below code within listview setOnItemClickListener :-
String genreID = ID_ArrayList.get(position);
String genre = GENRE_ArrayList.get(position);
String genreName = NAME_ArrayList.get(position);
String genreUrl = URL_ArrayList.get(position);
Toast.makeText(getApplicationContext(), genreID+", "+genre+","+genreName+", "+genreUrl+", "+, Toast.LENGTH_SHORT).show();
its return render data of listview.
try this,
ShowSQLiteDBdata() in onCreate() instead of onResume() method
I'm using SQLite in my app. I have a listView which is populated with values from the database.
When I click on an item from the listview, I go to another page, and I would like ( with an intent), to transfer the ID FROM THE DATABASE. The problem is that I'm only transfering the ID from the position of my listView, which is wrong. For example, let's say I have :
ID Name
1 David
2 Joseph
My listView will display both names. But if I delete David, the ID i'm getting when i click in Joseph is 1 and not 2 . And that's the problem !
So : I want to retrieve the ID from my database and not from my listView when I click on an item
Here's my method in my helper : UPDATED !
public Cursor getAllCours()
{
String Query = ("select ID as _id, nom from " + TABLE_COURS);
Open();
Cursor cursor = db.rawQuery(Query, null);
return cursor;
}
And how I display it in my Activity :
Cursor cursor = dbhelper.getAllCours();
String[] from = { "nom" }; int[] to = { android.R.id.text1 };
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, cursor, from, to, 0);
lv.setAdapter(adapter);
And finally, my listviewClickListener :
lv.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
//I THINK THE ERROR IS HERE !
long itemid= lv.getItemIdAtPosition(i);
int id= (int)itemid;
String a =lv.getItemAtPosition(i).toString();
Intent b = new Intent(AffichageCours.this,AffichageNotes.class);
Bundle args = new Bundle();
args.putString("nom_cours",a);
args.putInt("id",id);
b.putExtras(args);
startActivity(b);
}
});
}
My TABLE_COURS columns:
private static final String TABLE_COURS = "cours";
private static final String COLONNE_IDCOURS = "ID";
private static final String COLONNE_COURS = "nom";
private static final String CREATE_COURS ="CREATE TABLE cours " +
"("+COLONNE_IDCOURS+" INTEGER PRIMARY KEY AUTOINCREMENT , "
+COLONNE_COURS+" TEXT NOT NULL)";
How i delete with my Context Menu :
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
switch(item.getItemId())
{
case R.id.supprimer:
dbhelper.deleteCours(lv.getItemAtPosition(info.position).toString());
adapter.remove(adapter.getItem(info.position)); //the error is here..
adapter.notifyDataSetChanged();
return true;
Thank you guys !
I think the problem is that you are asking for the Id of the row in the ListView not the actual data that row is holding up. In the onItemClick method change this:
long itemid= lv.getItemIdAtPosition(i);
For this:
String courId = adapter.getItem(i);
The key here is to try to get the data from the ArrayAdapter not directly from the ListView.
You should have use Java Objects so it will be easy for you.
Suppost you have stored Contacts in dataBase(contains fields: Name, Mobile and Address). So create a POJO for that:
class Contacts{
private String name;
private String mobile;
private String address;
//write getters and setters
}
Then, whenever you are accessing database fetch all contacts you want to show and store in ArrayList<Contacts> mContactList;
And then pass this list in your ListView's adapter to show data in listView.
CustomAdapter adapter = new CustomAdapter(context, layoutResource, mContactList);
Then you can retrieve the object on clicking a particular list item on the basis of position;
lv.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Contacts contact = mContactList.get(i);
// now you can do whatever you want;
}
});
Since you are not using a custom adapter, why dont you try this inside onItemClickListener
String idThatYouWant = listeCours.get(i).getId();
this is a succesor to this question
At first everything worked fine but after 2 deletes the misery starts. The database entries start with ID 1, then 2 and so on. Lets say I have three database entries. The listview IDs for these three entries are 2,1 and 0.
The database entries are 1,2 and 3. 1 and 2 will be deleted with the onitemclicklistener but since the listview doesn´t have an ID 3, the corresponding database entry will never ever be deleted.
So the question is, how can I "sync" those two IDs?
Listview-Class
public class anzeigen extends AppCompatActivity {
private static final String TAG = anlegen.class.getSimpleName();
private static final String FILENAME = TAG + ".kdf";
private List valueList = new ArrayList<String>();
final VorgangDataSource dataSource = new VorgangDataSource(this);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_anzeigen);
Log.d(TAG,"Die Datenquelle wird geöffnet!");
dataSource.open();
final List<vorgangsdaten> vorgangsdatenList = dataSource.getAllVorgangsDaten();
final ArrayAdapter<vorgangsdaten> VorgangArrayAdapter = new ArrayAdapter<>(
this,
R.layout.mylistlayout,
vorgangsdatenList
);
final ListView lv = (ListView)findViewById(R.id.listView);
lv.setAdapter(VorgangArrayAdapter);
lv.setItemsCanFocus(false);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String s_id = String.valueOf(id);
Log.d(s_id,"id_in_onitem");
String p_id = String.valueOf(position);
Log.d(p_id,"position_on_item");
int pos = position;
vorgangsdatenList.remove(pos);
dataSource.deleteRow(id);
VorgangArrayAdapter.notifyDataSetChanged();
}
});
//ActionBar Costumization
android.support.v7.app.ActionBar ab = getSupportActionBar();
ab.setIcon(R.drawable.search1);
ab.setDisplayShowHomeEnabled(true);
ab.setDisplayUseLogoEnabled(true);
}
#Override
protected void onDestroy() {
super.onDestroy();
dataSource.close();
}
}
deleteRow-Method:
public void deleteRow(long id){
String s_id;
s_id = String.valueOf(id);
Log.d(s_id,"id_value");
database.delete(VorgangDbHelper.TABLE_VORGAENGE_LIST,VorgangDbHelper.COLUMN_ID + " = ?", new String[] {s_id});
long deleteID = database.delete(VorgangDbHelper.TABLE_VORGAENGE_LIST,VorgangDbHelper.COLUMN_ID + " = ?", new String[] {s_id});
String s_del = String.valueOf(deleteID);
Log.d(s_del,"delete_row_value");
}
If you need more code just let me know :)
You have no synchronicity between your Database and the ListView items.
When selecting the data, select the ID from the table, and keep it in memory as well.
Since vorgangsdaten looks german or sweden, I am having trouble understanding the meaning of those words. The ListView has its own "id" for each item, to keep a list of them shown, and the rest "hidden". What you must do is have an Object with details that are syncronized with the database, and when a list item is clicked, the "list id" is used to query an Object and delete from the database.
An example would be:
ArrayList<MyObject> arrayListData = new ArrayList<>();
ArrayList<String> arrayListNames = new ArrayList<>();
MyObject stuffs = database.query(); // In here, fetch the data
/* I am simplifing the MyObject to [String name, String aValue, int aNumber] */
for(MyObject s: stuffs){
arrayListData.add(s);
arrayListNames.add(s.name);
}
arrayAdapter = new ArrayAdapter<String>(
this,
android.R.layout.simple_list_item_1,
arrayListNames
);
listView.setOnItemClickListener(
new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
MyObject thing = arrayListData.get(position);
database.delete(thing.aNumber);
}
}
);
listView.setAdapter(arrayAdapter);
After trying Bonattis answer and experimenting a little bit I found another answer.
deleteRow-Method
public void deleteRow(long id){
String s_id; //String for long id
s_id = String.valueOf(id); //assign String value of id
String s_rowId = null; //String for rowid
long rowId = 0;
long deleteId = 0;
String s_deleteId = null;
Log.d(s_id,"id_value");
Cursor cursor = database.query(VorgangDbHelper.TABLE_VORGAENGE_LIST,columns,null,null,null,null,null);
if(cursor.moveToFirst()) {
s_rowId = cursor.getString(cursor.getColumnIndex(VorgangDbHelper.COLUMN_ID));
rowId = Long.parseLong(s_rowId);
deleteId = rowId + id;
s_deleteId = String.valueOf(deleteId);
Log.d(s_rowId,"rowID");
Log.d(s_deleteId,"deleteID");
}
database.delete(VorgangDbHelper.TABLE_VORGAENGE_LIST,VorgangDbHelper.COLUMN_ID + " = ?", new String[] {s_deleteId});
}
How does it work now?
So the deleteRow-Method(dRM) gets the id of the first database entry (s_rowId) and converts it to long (rowId).
Now I take the long id passed from the listview and add it to rowId which is my deleteId. With this I have the correct database value to what I clicked in the listview and can pass it over to database.delete
I managed to show a list from sqllite, now I want that when the user click on the item, the item will be deleted. the problem is that the item's ID number from the sql is different from the listview's ID. so how can I delete the selected item?
I mean this id:
public void onItemClick(AdapterView parent, View view,int position, long id)
is different from the item's ID from the sqllite.
thank you for help
Cursor resultSet = db.rawQuery("Select * from list ORDER BY `ID` DESC",null);
resultSet.moveToFirst();
final ListView listview = (ListView) findViewById(R.id.listView1);
ArrayList<HashMap<String, String>> mylistData = new ArrayList<HashMap<String, String>>();
String[] columnames = new String[] {"C1", "C2", "C3"};
int[] columnsR = new int[] {R.id.column1, R.id.column2, R.id.column3};
int x=0;
while(resultSet.moveToNext()){
HashMap<String,String> map = new HashMap<String, String>();
String d_weight = resultSet.getString(resultSet.getColumnIndex("weight"));
String d_date = resultSet.getString(resultSet.getColumnIndex("date"));
String d_id = resultSet.getString(resultSet.getColumnIndex("ID"));
x=0;
map.put(columnames[x],d_weight);
x++;
map.put(columnames[x],d_date);
x++;
map.put(columnames[x],d_id);
mylistData.add(map);
}
SimpleAdapter arrayAdapter = new SimpleAdapter(this, mylistData, R.layout.row,columnames , columnsR);
listview.setAdapter(arrayAdapter);
listview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,int position, long id)
{
// how to delete? =[
}});
Would it not be easier to make an object that you fill with the data from your sql query for each entry? Then you just populate the listview with a list of these objects, which means that when one of the objects get clicked on the id will be stored inside the object. Then int position would have the same value as the position in your list of objects.
How does that sound?
I have a listView that displays the records from a database, and a setOnClickListener() for the items that pulls the text from the list and adds the String as an extra for an Intent.
This all works fine, my list displays records with Text such as, City, Town, Village, and when i add new items this also works fine. My issue lies with when i use a toast to display the string passed to the intent, some extra Chars are added
e.g. I click on the List item "town" and the toast displays "{pg=town}" how to i stop this from happening/ why is it happening?
The code for the Adapter and onClick is as Follows.
Thanks in advance.
public void listChange() {
Cursor c = database.rawQuery("select * from Towns", null);
c.moveToFirst();
primeTownlist = new ArrayList<HashMap<String, String>>();
while (!c.isAfterLast()) {
primeTownMap = new HashMap<String, String>();
primeTownMap.put("pg", c.getString(1));
primeTownlist.add(primeTownMap);
c.moveToNext();
}
c.close();
primeGoalAdapter = new SimpleAdapter(this, primeTownlist, R.layout.primeTowns,
new String[] { "pg" }, new int[] {R.id.bt_primeTown});
primeTowns.setAdapter(primeTownAdapter);
}
primeTowns.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> list, View view, int position, long id) {
String title = list.getItemAtPosition(position).toString();
Intent i = new Intent("com.example.towns.town");
i.putExtra("town", title);
startActivity(i);
Toast.makeText(getApplicationContext(),
(title), Toast.LENGTH_SHORT).show();
}
});
That because your list is a list of HashMap. Try
String title = ((HashMap<String,String>) list.getItemAtPosition(position)).get("pg");