I have a custom listview with three items. One of them is like "Add this to the DB" and when I click to it it inserts something to the DB.
What I want it to do is after doing the insert, change the text to "Delete this from the DB" and also the onClick method to call a method to delete that record instead a method to insert.
Is this possible?
Here is my code:
final String[] opcs = new String[]{"Resultados", "ClasificaciĆ³n", text_fav};
ArrayAdapter<String> aa = new ArrayAdapter<String>(this, R.layout.list_menutipo_item, opcs);
m_list.setAdapter(aa);
m_list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Intent newActivity = null;
switch( position )
{
case 0: ...
case 2: if (isConnected(m_context))
{
aƱadirFavorito();
}
break;
}
}
});
It's definitely possible. The view parameter to the onItemClick callback is the view on which you clicked, you can simply change that view's content. i.e. view.setText("Delete this from the DB").
Also you will want to distinguish whether the next click is "Add this to the DB" or "Delete this from the DB", doing a string comparison here like if("Delete this from the DB".equals(view.getText())) might not be of good practice, you can set a flag in the view like view.setTag(true) to indicate that the current view's content is "Delete this from the DB". and later you can use view.getTag() to get back the flag to do the comparison.
Boolean flag = (Boolean)view.getTag();
if(flag == null || !flag) {
view.setText("Delete this from the DB");
flag = true;
//... code to insert a record to DB
} else {
view.setText("Insert this to the DB");
flag = false;
//... code to delete a record from DB
}
view.setTag(flag);
Related
Hi i am created customlistview added one button first time i am insert value in 0.When i have to click that add button value is 1 changed in database.Getting column value result.
Note*Getting value result 1 means changed button or color.I am used in baseadapter*
here i have mention sample code also:
holder.btn_add.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
HashMap<String, String> hashMap = new HashMap<String, String>();
hashMap.put("product", arrListproduct_name
.get(position).toString().trim());
hashMap.put(
"price",
getDoublePrecision(arrListproductprice
.get(position).toString().trim()));
hashMap.put("productID", arrlistproduct_id
.get(position).toString().trim());
hashMap.put("quantity", datavalue);
hashMap.put("resturantID",
category.dinein_restaurant_id);
hashMap.put("value", Str_value);
arrListproductdatabase.add(hashMap);
if (dataBase.ProductExist(
DatabaseHelper.TABLErestaurant,
arrlistproduct_id.get(position).toString()
.trim())) {
Toast.makeText(VegNonVegClass.this,
"Update successfully", Toast.LENGTH_LONG)
.show();
for (int i = 0; i < GetAllitemDetailsItem.size(); i++) {
dataBase.updateData1(
GetAllitemDetailsItem.get(i).get("id"),
DatabaseHelper.TABLErestaurant, "1");
}
} else {
dataBase.insertData(DatabaseHelper.TABLErestaurant,
arrListproductdatabase);
arrListproductdatabase.clear();
Toast.makeText(VegNonVegClass.this,
"Add successfully", Toast.LENGTH_LONG)
.show();
// arrListproductdatabase.remove(position);
// notifyDataSetChanged();
ArrayList<String> selectedno = dataBase
.getselectedTrue();
for (String s : selectedno) {
if (s.equalsIgnoreCase("1")) {
holder.btn_add
.setBackgroundResource(R.drawable.checkout);
}
}
}
if (listener != null) {
listener.totalAmount(String.valueOf(Str_subtotal));
}
}
});
Issues Button is changed but listview refresh means automatically changed previous button Please give me solution
I'm not entirely sure I understand your issue, but I believe you're saying that the value of the button is changing, but its view in the list is not changing appropriately, correct?
If so, that's because of how the list view's adapter works. It's designed to be efficient by re-using inflated views that are already created, instead of recreating them every time.
First, try calling notifyDataSetChanged() on the adapter.
If that doesn't update your problem, it's probably because you're not actually changing the data in the adapter; just the value it represents.
Make sure you're overriding the adapter's getView() method appropriately as well:
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if(row == null)
{
row = (((Activity)mContext).getLayoutInflater()).inflate(layoutResourceId, parent, false);
}
try{
// Set what the view should show here
}
catch(Exception e){
e.printStackTrace();
}
return row;
}
I'm new to Android. I'm working on a listView-based app: you have a main menu, when you click an item, a new activity starts with another menu; when you click again, a new activity starts with the content you selected. Since I've quite a lot of menu items, I've to create a listener which handles all possible cases, so I've something similar:
#Override public void onItemClick(AdapterView<?> listAdapter, View v, int position, long id) {
String text = ((TextView)v).getText().toString();
//main menu
if (text.equals(K.getStringById(K.ID_MAIN_THEORY))) {
...
} else if (text.equals(K.getStringById(K.ID_MAIN_EXERCISE))) {
...
}
else if (text.equals(K.getStringById(K.ID_MAIN_TABLES))) {
...
}
//here other menus' items: lots of items
...
//back item
else if (text.equals(K.getStringById(K.ID_BACK))) {
activity.finish();
}
Intent i = new Intent(...);
startActivity(i);
}
* K is a class that holds ids' references
There's a way I can avoid hard-coding listener behavior?
** PS: the lists' TextViews don't render properly: text appears light grey, not black! O.o
It's more useful to use the position rather than the view to switch the action of the click event. Your ListView should be populated from some sort of List, therefore when the onClick fires, giving you the position, you can reference that position in the List to know what was clicked.
If you want to click on item and in result it goes to another activity, for example if you have three item and when you click on item A it will redirect you to activity A and if B then to B and so on,
lstview.setOnItemClickListener(new OnItemClickListener()
{
private String input;
public void onItemClick(AdapterView<?> v, View arg1, int index,long arg3)
{
if(index==1)
{
Intent intnt=new Intent(v.getContext(),A.class);
startActivity(intnt);
}
else if (index==2)
{
Intent intnt=new Intent(v.getContext(),B.class);
startActivity(intnt);
}
else
{
Intent intnt=new Intent(v.getContext(),C.class);
startActivity(intnt);
}
}
}
Here in this case you are going to different activities on selection the items in a list view, put your comments for further query.
I solved this way: I think it's pretty good.
//This in K class, where MAPPED_HIERARCHY is a static field
static void activity(android.app.Activity a) {
MAPPED_HIERARCHY = new HashMap<String, ArrayList<String>>();
MAPPED_HIERARCHY.put(a.getResources().getString(R.string.app_name), K.array2list(a.getResources().getStringArray(R.array.menu_main)));
MAPPED_HIERARCHY.put(a.getResources().getString(R.string.main_theory), K.array2list(a.getResources().getStringArray(R.array.menu_theory)));
MAPPED_HIERARCHY.put(a.getResources().getString(R.string.main_exercise), K.array2list(a.getResources().getStringArray(R.array.menu_exercise)));
....
}
static ArrayList<String> getArrayListByString(String string) {
ArrayList<String> copy = new ArrayList<String>(MAPPED_HIERARCHY.get(string).size());
for (String s : MAPPED_HIERARCHY.get(string))
copy.add(s);
return copy; //defensive copy
}
//This in my listener class
#Override public void onItemClick(AdapterView<?> listAdapter, View v, int position, long id) {
String text = ((TextView)v).getText().toString();
ArrayList<String> params = K.getArrayListByString(text);
Intent i = new Intent(...);
i.putExtra("params", params);
activity.startActivity(i);
}
I have a map which links an arraylist containing the menu items with the string wihich causes the menu to be displayed; on the click event, I simply retrieve the arraylist according with the selected item's text.
I have a activity which has a button and 2 autocomplete widget. for the button i am using
addProductButton.setOnClickListener(this);
and for the 2 autocomplete widget i am using
supplierTextView.setOnItemClickListener(this);
now when i select the first autocomplete it runs this code but does not go into the if loop also when i click a item in the 2nd autocomplete it runs the same code but without going into the else
#Override
public void onItemClick(AdapterView<?> adapter, View view, int pos, long rowId) {
// TODO -
String supName = supplierTextView.getText().toString();
String proName = productTextView.getText().toString();
System.out.println("Name selected "+ view.getId());
if(view == supplierTextView)
{
Log.d("Supplier Name selected", supName);
}
else if(view == productTextView)
{
Log.d("Product Name selected", proName);
}
loadProducts(supName);
handleProductSuccess(filteredProduct);
}
On this statement.
if(view == supplierTextView)
{
Log.d("Supplier Name selected", supName);
}
else if(view == productTextView)
{
Log.d("Product Name selected", proName);
}
the type of the view is TextView so nothing happened.
If you want to know which of the 2 AutoCompleteTextView is triggered.
call this statement
supplierTextView.setOnClickListener(listener);
and
productTextView.setOnClickListener(listener);
and in onClick()
public void onClick(View view)
{
if(view == supplierTextView)
{
Log.d("Supplier Name selected", supName);
}
else if(view == productTextView)
{
Log.d("Product Name selected", proName);
}
}
don't forget to implement View.OnClickListener
The OnItemClickListener is used to listen for clicks on autocomplete text field items.
That is, when you click an autocomplete suggestion, you will receive the View corresponding to that suggestion along with its index and not the AutocompleteTextView itself.
Use the OnClickListener on your AutocompleteTextViews if you want to be notified when the views themselves are clicked.
If you want to react to changes in text content of your text field you can use the TextWatched listener interface. See TextView API for more information on that.
If you want to give click event to auto complete view then change setOnItemClickListener to setOnClickListener. Put if else condition in onClick method. It will work
I'm still not getting exactly how a custom CursorAdapter should work, so after hard tries, here is the thing :
I implement a listener on a button inside my getView().
The listener launches a delete row event.
To get to it, I use a singleton database where I can perform request from all classes (The purpose of a singleton actually)
I usually update (insert and modify) from the activity class, so I just have to get the new database cursor and re-assign it to a new CursorAdapter, that I re-assign itself to the ListView.
Here it's different : I'm inside the CursorAdapter class in the ListView method, and I don't know how to update my adapter from the inside.
For people who don't want to read my boring explanations, here is the code of the getView :
#Override
public View getView(int position, View convertView, ViewGroup parent){
convertViewParam = convertView;
ViewHolder viewHolder = new ViewHolder();
if (convertViewParam == null) {
int type = getItemViewType(position);
switch (type) {
case TYPE_ADD_NOTE_TOP:
convertViewParam = inflater.inflate(R.layout.add_note_top, null);
viewHolder.contentNote = (EditText)convertViewParam.findViewById(R.id.add_note_top_id);
break;
case TYPE_ITEM:
convertViewParam = inflater.inflate(R.layout.row_note, null);
viewHolder.delete = (Button)convertViewParam.findViewById(R.id.delete);
if (deleteMode){
viewHolder.delete.setVisibility(View.VISIBLE);
}else{
viewHolder.delete.setVisibility(View.GONE);
}
viewHolder.contentNote = (TextView)convertViewParam.findViewById(R.id.note);
getCursor().moveToPosition(position - 1);
int currentPosition = getCursor().getPosition();
Cursor c = getCursor();
c.moveToPosition(currentPosition);
((TextView) viewHolder.contentNote).setText(c.getString(c.getColumnIndex("content_note")));
int rowId = c.getInt(c.getColumnIndex("_id"));
viewHolder.delete.setTag(new Integer(rowId));
viewHolder.contentNote.setTag(new Integer(rowId));
OnClickListener listener = new OnClickListener() {
#Override
public void onClick(View v) {
int thePosition = (Integer) v.getTag();
int posCurs = notesCursorAdapter.getCursor().getPosition();
NoteDataSource.getSingletonObject(context).deleteNote(thePosition, context);
notesCursorAdapter.changeCursor(NoteDataSource.getSingletonObject(context).getAllNotes());
notesCursorAdapter.notifyDataSetChanged();
}
};
viewHolder.delete.setOnClickListener(listener);
break;
case TYPE_ADD_NOTE_BOTTOM:
convertViewParam = inflater.inflate(R.layout.add_note_bottom, null);
LinearLayout linearLayout = (LinearLayout)convertViewParam.findViewById(R.id.bottomLayout);
linearLayout.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
}
});
break;
}
convertViewParam.setTag(viewHolder);
} else {
viewHolder = (ViewHolder)convertViewParam.getTag();
if (viewHolder.contentNote!=null){
if (viewHolder.contentNote.getTag() == convertViewParam.findViewById(R.id.note)){
int test = (Integer) viewHolder.delete.getTag();
System.out.println("current tag " + test);
String txt = getCursor().getString(getCursor().getColumnIndex("content_note"));
((TextView) viewHolder.contentNote).setText(txt);
}
}
}
return convertViewParam;
}
I get the following error when I launch the delete event:
03-28 17:51:32.996: E/AndroidRuntime(7115): android.database.CursorIndexOutOfBoundsException: Index 2 requested, with a size of 2
If you want more info ask.
I'm looking for a bug fix or an just explanation, thanks.
Thats a very well written problem statement. I have had this problem and broke my head over it. Try this.
In your Adapter make a listener, something like
public interface ItemDeletedListener(){
public void itemDeleted(int position);
}
create an instance of ItemDeletedListener in your adapter, m_listener.
Write a setter function, setItemDeletedListener( ItemDeletedListener listener){}
In your getView(), onClickListener, call m_listener and pass the position that needs to be deleted.
Now in your Activity, Do the following.
Implement the listener, that you created above.
In your implementation, do the deletion work and then do a changeCursor() there.
It would help to know on which line you get the exception. First of all one bad thing is that you delete a note from the database based on a position int and after that you fetch again all the data and move the position on that cursor on the previous deleted position.
If you have 3 notes(and you show them in the list) in the database and you want to delete the last one this will happen:
the thePosition will be 2
you delete the note
fetch again all the notes from the database (the cursor will have 2 rows now because you deleted one)
move the cursor to thePosition (value 2)
the cursor has only 2 rows(numbered from 0) and you ask for row with the number 2
exception
If you want to delete a note then pass as a tag the _id for that row and use that to delete the note:
Cursor c = getCursor();
c.moveToPosition(position);
long rowId = c.getLong(c.getColumnIndex("_id"));
viewHolder.delete.setTag(new Long(rowId));
Then in the onClick() method use that to delete the note and stop messing with the moveToPosition() on the cursor.
I am using simple_list_item_multiple_choice with list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); to create a list of check boxes populated from a database query. I am then using onListItemClick to handle the clicking of the list, again that is working fine. What I can find no way of doing (after 5 days) is writing an if statement based on whether or not the check box attached to the list item is checked. What I need is the equivalent of the example below which works perfectly for a check box where I can use the android:onClick element to fire the method below.
public void onCheckboxClicked(View v) {
// Perform action on clicks, depending on whether it's now checked
if (((CheckBox) v).isChecked()) {
Toast.makeText(this, "Selected", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Not selected", Toast.LENGTH_SHORT).show();
}
}
This is critical to my app so any advice would be greatly appreciated. Below is the simpleCusrorAdapter is am using:
Cursor cursor3 = db.rawQuery("SELECT _id, symname FROM tblsymptoms WHERE _id IN ("+sympresult+") ", null);
adapter = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_multiple_choice,
cursor3,
new String[] {"symname","_id"},
new int[] {android.R.id.text1});
setListAdapter(adapter);
ListView list=getListView();
list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
I have solved the problem after finding this very useful blog item
I changed my onListItemClick to the following and it works like a dream:
public void onListItemClick(ListView parent, View view, int position, long id) {
CheckedTextView check = (CheckedTextView)view;
check.setChecked(!check.isChecked());
boolean click = !check.isChecked();
check.setChecked(click);
if (click) {
Toast.makeText(this, "Not Selected", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Selected", Toast.LENGTH_SHORT).show();
}
}
If I understand correctly, each row in your list has a checkbox. When an item in the list is selected you want to be able to tell if the corresponding checkbox is checked?
Try to use the setTag(...) method on each list item View object. Then when onListItemClick() method is called you can call getTag(...) on the view (which will return your checkbox). I assume that you are using a custom Adapter to populate the list. While populating you want to call:
setTag( CHECKBOX_KEY, checkbox );
For example:
protected void onListItemClick(ListView l, View v, int position, long id) {
CheckBox cb = (CheckBox)v.getTag( CHECKBOX_KEY );
boolean isChecked = false;
if( null != cb ) {
isChecked = cb.isChecked();
}
// .. do whatever you have to here...
}
Hope this helps...