I have a database with a table that stores int and string. The integer value is the primary key. I have created a function to just fetch the strings from the database and store them in a list which is then applied to the ListView using an ArrayAdapter as shown below.
List<String> list = db.getAllStringNotes();
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_activated_1, list);
listview.setAdapter(adapter);
listview.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
The trouble is deleting from this listview. Since the primary key is not present along with the string, I was deleting using the position of the item selected from the list view. But that obviously messes up things if I'm removing an entry from the middle of the list.
So was wondering if I could add the primary key i.e. an integer value to this list view along with the String but not display the integer value?
The simple thing is create two List,
1. String - Stored String notes
2. Integer - Stored all Primary Keys
So whenever user click on Listview user get its position, and based on that position get primary key value from second list and then perform your delete query.
There are many ways to do this: but as you are already using an ArrayList so i would suggest just make another arraylist while fetching from database:
So while deleting using the position :
Use the Primary Key from the PrimaryKeyArrayList
and delete values from both the ArrayList;
With this you will get exactly what you need;
Follow these Steps:
Create bean.java file that will have your db value
Create CustomAdapter.java to pupulate the items and handle the delete operation
Create delete method in your adapter and pass the selected bean object to delete from DB and ArrayList.
after deletion call notifyDatasetChanged method to reflect the change in list
EDIT:
Bean File:
public class MyDB_Bean{
public int id;
public String data;
MyDB_Bean(int id,String data){
this.id=id;
this.data=data;
}
}
Calling from Activity
ArrayList<MyDB_Bean> list = db.getAllStringNotes();
MyArrayAdapter adapter = new MyArrayAdapter<String>(this,list);
listview.setAdapter(adapter);
listview.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
For CustomAdapter follow these tutorials
http://www.ezzylearning.com/tutorial.aspx?tid=1763429
Custom Adapter for List View
http://www.vogella.com/tutorials/AndroidListView/article.html
http://learnandroideasily.blogspot.in/2013/06/listview-with-custom-adapter.html
Related
I have the following codes to add data from sqlite to the listView. (The code works) However, I want to have static data on the listView and also have the function on adding from sqlite. Meaning that, I want to do a listView with data "A", "B","C" as default. So when user clicks on the "add" function user is able to add the data into sqlite and display into the same listView where the "A","B","C" data is.
Please help.
step 1
declare one empty arraylist then add static data like in your case A,B,C and fill adapter with this data.
ArrayList<String> arrayList=new ArrayList<>();
arrayList.add("A");
arrayList.add("B");
arrayList.add("C");
MyAdapter myAdapter=new MyAdapter(this);
listview.setAdapter(myAdapter);
myAdapter.addItem(arrayList);
in Adapter add this function
public void addItem(ArrayList<String> arraylist){
this.arraylist = arraylist;
notifyDataSetChanged();
}
step 2
in your add item function do 2 things
1 add those data in your database.
2 add those data into arraylist that you have created in step 1, and add it to adapter like below code.
databaseHelper.addData("D");
arrayList.add("D");
myAdapter.addItem(arrayList);
step 3
check after this when you come second time in screen check whether database has data init if yes then modify step one like below
ArrayList<String> arrayList=new ArrayList<>();
arrayList.add("A");
arrayList.add("B");
arrayList.add("C");
MyAdapter myAdapter=new MyAdapter(this);
listview.setAdapter(myAdapter);
if(databaseHelper.getDataList()!=null &databaseHelper.getDataList().size()>0{
arrayList.addAll(databaseHelper.getDataList());
myAdapter.addItem(arrayList);
}else{
myAdapter.addItem(arrayList);
}
you used imageViewToByte() for change ImageView to byte, but R.mipmap.newsgd is not ImageView, it resource
All you do is :-
//get all data
Cursor cursor = MainActivity.sqLiteHelper.getData("SELECT * FROM FOOD");
list.clear();
while (cursor.moveToNext())
{
int id = cursor.getInt(0);
String name = cursor.getString(1);
String price = cursor.getString(2);
byte [] image = cursor.getBlob(3);
list.add(new Food(id,name,price,image));
}
// Adding your three items for the list
list.add(new food(your_id_for_A,your_name_for_A,your_price_for_A,your_image_for_A));
list.add(new food(your_id_for_B,your_name_for_B,your_price_for_B,your_image_for_B));
list.add(new food(your_id_for_C,your_name_for_C,your_price_for_C,your_image_for_C));
adapter.notifyDataSetChanged();
Noting that you may have to be a little careful with what id you provide and how you subsequently handle that id as you may have to distinguish between a row from the database as opposed to an added row.
Just add A, B, C after listView.setAdapter(adapter); -> list.add(A), list.add(B), list.add(C)
Ex:
list.add(new Food(someId, "Singapore","4.772",R.mipmap.newsgd, ...));
Hope this help!
After going through many posts I am posting my query. Not able to get proper resolution for my problem.
I am using sqlite and inserting some data (name, info etc..)
Now I get the all rows and show in list view.
Now user selects a one list entry for deletion, I have to call db.delete with id which is rowid of that particular record.
How will get the record id?
When user selects from list view I have position number which is index to the list. But not the database row id where that entry resides.
Do i have to save all ids returned when I call db.insert(table, data) when rows are created?
all examples show the implementation like
public void deleteRow(long id) {
db.delete(TABLE_NAME,KEY_ID + " = ?",
new String[] { String.valueOf(id) });
}
where should i get id from?
For setup a list view you have create an Adapter, right?
The adapter hold your entries and create the views.
Ask your adapter which item is on position x.
The BaseAdapter implement a getItemId method.
public long getItemId(int position) {
// Example for List<Object>
return mItems.get(position).getId();
}
You can simple call adapter.getItemId(x); or use OnItemClickListener that give the ID.
For more informations loot at the android developer pages.
SimpleAdapter:
http://developer.android.com/reference/android/widget/SimpleAdapter.html
ArrayAdapter:
http://developer.android.com/reference/android/widget/ArrayAdapter.html
BaseAdapter:
http://developer.android.com/reference/android/widget/BaseAdapter.html
I hope it helps.
Updated:
Use getItemId(int) instead of getItem(int), thanks to #pskink
I am using listview in my app.I am adding items to list with this line:
conversationsAdapter.add(user);
and this initializes list
conversationsAdapter=new ArrayAdapter<JsonObject>(this,0) {
#Override
public View getView(int c_position,View c_convertView,ViewGroup c_parent) {
if (c_convertView == null) {
c_convertView=getLayoutInflater().inflate(R.layout.random_bars,null);
}
JsonObject user=getItem(c_position);
String name=user.get("name").getAsString();
String image_url="http://domain.com/photos/profile/thumb/"+user.get("photo").getAsString();
TextView nameView=(TextView)c_convertView.findViewById(R.id.tweet);
nameView.setText(name);
ImageView imageView=(ImageView)c_convertView.findViewById(R.id.image);
Ion.with(imageView)
.placeholder(R.drawable.twitter)
.load(image_url);
return c_convertView;
}
};
ListView conversationsListView = (ListView)findViewById(R.id.conversationList);
conversationsListView.setAdapter(conversationsAdapter);
conversationsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
startChat(conversationsAdapter.getItem(position));
}
});
My list view is looking like this:
I want to update an item in the list.How can I do this ?
Example:We can write a method like: changeName when this method calls,method sets name "Tolgay Toklar" to "Tolgay Toklar Test" so I want to update custom listview item attributes.
I totally disagree with tyczj. You never want to externally modify an ArrayAdapter's list and yes it's possible to update just an individual item. Lets start with updating an individual item.
You can just invoke getItem() and directly modify the object and call notifyDataSetChanged(). Example:
JSONObject object = conversationAdapter.getItem(position);
object.put("name", data);
conversationAdapter.notifyDataSetChanged();
Why does this work? Because the adapter will feed you the same object reference used internally, allowing you to modify it and update the adapter. No problem. Of course, I'd recommend instead building your own custom adapter to perform this directly on the adapter's internal list. As an alternative, I highly recommend using the ArrayBaseAdapter instead. It already provides that ability for you while fixing some other major bugs with Android's ArrayAdapter.
So why is tyczj wrong about modifying the external list? Simple. There's no guarantee that your external list is the same as the adapters. Once you perform a filter on the ArrayAdapter, your external list and the adapters are no longer the same. You can get into a dangerous scenario where (for example) index 5 no longer represents position 5 in the adapter because you later added an item to the adapter. I suggest reading Problems with ArrayAdapter's Constructors for a little more insight.
Update: How External List Fails
Lets say you create a List of objects to pass into an ArrayAdapter. Eg:
List<Data> mList = new ArrayList<Data>();
//...Load list with data
ArrayAdapter<Data> adapter = new ArrayAdapter<Data>(context, resource, mList);
mListView.setAdapter(adapter);
So far so good. You have your external list, you have an adapter instantiated with it and assigned to listview. Now lets say at some later point, the adapter is filtered and cleared.
adapter.filter("test");
//...later cleared
adapter.filter("");
Now at this point mList is NOT the same as the adapter. So if the adapter is modified:
adapter.add(newDataObject);
You'll find that mList does not contain that new data object. Hence why external lists like this can be dangerous as the filter creates a NEW ArrayList instance. It won't continue to use your mList referenced one. You could even try adding items to mList at this point and it won't be reflected in the adapter.
If you change the data in your list you need to call notifyDatasetCanged on the adapter to notify the list that the underlying data has changed needs to be updated and.
Example
List<MyData> data = new ArrayList<MyData>();
private void changeUserName(String name){
//find the one you need to change from the list here
.
.
.
data.set(myUpdatedData);
notifyDatasetChanged()
}
Hi I'm working on an Android application. I have a form with 2 spinners (CarMake & CarModel) that allows a user to select a specific car from my mySQL database. I want to load the CarMake spinner with all the entries in the make column of my car database, and from there I want the carModel spinner to only contain models of that make in the database. What would be the easiest way to implement this?
Assign unique ID's to your CarMake table items, like a primary key. So suppose for Tata you assign ID= 1 Then assign the same ID to all of its model in the CarModel table like a foreign key and then using this ID you can fetch all the models easily. (Hoping you have a different tables for them)
The approach you need is to have a populate method per spinner, so you would have something like this
public void populateCarMake()
{...
// query car make
// update adapter 1
}
public void populateCarModel( int makeID )
{...
// query car model where make_id == makeID
// update adapter 2
}
and in onitemselect() of the first spinner call populateCarModel( makeID );
based on the selection of the spinner item just set the adapter using your new list
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, list);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner2.setAdapter(dataAdapter);
I have a problem on Android Spinner.In my application I created two Spinner on main layout. 'State' Spinner and 'District' Spinner. All the data on Spinner are stored in SQLite database. I want do display list of 'District' on second spinner depending on selection of particular 'State' in the first spinner.
Example: Suppose when I select Karnataka in the first spinner then application first retrieve all the district from SQLite database related to karnataka state and then it display on second Spinner.
For this I do all the database activity correctly means creating two table 'state' and 'district' in which one column in district table is foreign key which is refereed to one of the primary key of 'state table'
db.execSQL("create table "+STATE_TABLE+" ("+
STATE_ID+" integer primary key autoincrement not null, "+
STATE_NAME+" text"+")");
db.execSQL("create table "+DISTRICT_TABLE+" ("+DISTRICT_ID+
" integer primary key autoincrement not null,"+DISTRICT_NAME
+" text,"+STATE_ID+" integer, FOREIGN KEY("
+STATE_ID+") REFERENCES "+STATE_TABLE
+"("+STATE_ID+")"+")");
Now in the Activity Class:
spinnerState = (Spinner)findViewById(R.id.spinner1);
spinnerDistrict = (Spinner)findViewById(R.id.spinner2);
stateList = new ArrayList<String>();
districtList = new ArrayList<String>();
Suppose all the data are all ready stored in database.
Now I need to retrieve all the 'State' data from database and add it in the statelist which is ArrayList.
Cursor stateCursor = database.query(STATE_TABLE, new String[]{STATE_ID, STATE_NAME},
null, null, null, null, STATE_NAME);
stateCursor.moveToFirst();
if(! stateCursor.isAfterLast()){
do{
int id = stateCursor.getInt(0);
String stateName = stateCursor.getString(1);
stateList.add(stateName);
}while(stateCursor.moveToNext());
}
stateCursor.close();
after this I create one ArrayAdapter and put this state list into this.
spinnerState.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, stateList));
Next i put the following code in the activity class:
spinnerState.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View v,
int pos, long id) {
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
Now My problem is here:
How I get the StateId for executing the select query for taking all the district related to particular state in database.
How the adapter will generate for District.
where I put all these code.
Here what I need creating the districtList after getting the value from state Spinner.
Similar Question which asked earlier in this website, what they do:
they already create two adapter for two spinner and then apply setOnItemSelectedListener.
Please Help me because here my mind totally stop working.
I refer lot of book and website but not they even mention these type of problem.
I see a couple of solutions here:
Option 1:
Instead of declaring stateList as an ArrayList<String>, create a custom POJO StateInfo and designate stateList as ArrayList<StateInfo>
public class StateList {
private int id;
private String stateName;
//Constructors, getters and setters
}
Then,
if(! stateCursor.isAfterLast()){
do{
int id = stateCursor.getInt(0);
String stateName = stateCursor.getString(1);
stateList.add(new StateInfo(id, stateName));
}while(stateCursor.moveToNext());
}
Now, you can do this:
public void onItemSelected(AdapterView<?> parent, View v,
int pos, long id) {
int id = stateList.get(pos).getId();
//Use This ID to construct your next SQLite query; and populate the district spinner.
}
If you do this, you will have to create a custom ArrayAdapter and implement the getView() method. Look at the Android docs for how to do this.
Option 2:
Why do you even need the stateID? I suppose you can write a Query to get the districts list given a state Name only. In that case, you can retain the stateList as an ArrayList<String> and you don't even need the StateInfo class at all. Just do this:
public void onItemSelected(AdapterView<?> parent, View v,
int pos, long id) {
String stateName = stateList.get(pos);
//Use this name to construct your next SQLite query; and populate the district spinner.
}
For problem 1:
You just need to keep track of which state user selects into the spinner and according to its position,you have to find its related id.then you can query for district accordingly.obviously you will have to use onItemSelectedListener of that spinner to get position of state selected.
For problem 2:
You need to make a method in helper class which accepts stateId(which you would compute as i said above) and return you according district names in a String array.So in your main activity,in onItemSelectedListener of a state spinner,you will have to grab that string array and prepare a adapter for the same. There,you will have to set adapter to your district spinner.
This will always give you your district spinner updated with what user selects in state array.
For problem 3:
Almost all code would be in onItemSelectedListener of your state spinner only.Just a method to fetch related district names would be in your helper class.