There seems to be a problem when there are more than 5 records to
display on Manage Practice. For e.g. if there are 6 records to display on
Manage Practice. If I check the check box number 1, the check box number 6 also
gets checked. If there are 7 records, and if I check on 2nd record, then
the 7th record also gets automatically checked.I don't what's going on there I am very confusing, Please check my code let me know what's problem is there.
public class ManagePracticeLogAdapter extends BaseAdapter
{
//Variables to save class object.
Context context;
// variable to instantiates a layout XML file into its corresponding View objects.
LayoutInflater inflater;
MenuItem menu,addlog;
List<Integer> SelectedBox= new ArrayList<Integer>();;
// Variable to accept list data from Produce log activity
ArrayList<HashMap<String, String>> data;
ArrayList<HashMap<String, String>> temp_data;
HashMap<String, String> resultp = new HashMap<String, String>();
List<String> deleteData=new ArrayList<String>();
// Constructor to accept class instance and data.
public ManagePracticeLogAdapter(Context context,
ArrayList<HashMap<String, String>> arraylist,MenuItem mymenu,MenuItem myaddlog)
{
this.context = context;
data = arraylist;
//temp_data.addAll(data);
menu=mymenu;
addlog=myaddlog;
}
#Override
public int getCount()
{
return data.size();
}
#Override
public Object getItem(int position)
{
return null;
}
#Override
public long getItemId(int position)
{
return 0;
}
// Method to display data of Produce log Activity in list view
#Override
public View getView(final int position, View convertView, ViewGroup parent)
{
if(convertView==null)
{
inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView= inflater.inflate(R.layout.logitem1, parent, false);
}
TextView datetime;
TextView totminutes;
TextView skills;
TextView weather;
TextView day_night_icon;
final CheckBox chkdelete;
TextView approval_icon;
// Get the position
resultp = data.get(position);
// Locate the TextViews in listview_item.xml
datetime = (TextView) convertView.findViewById(R.id.id_datetime);
totminutes = (TextView) convertView.findViewById(R.id.totminutes);
skills= (TextView) convertView.findViewById(R.id.id_skills);
weather=(TextView)convertView.findViewById(R.id.id_weather);
day_night_icon=(TextView)convertView.findViewById(R.id.day_night_icon);
approval_icon=(TextView)convertView.findViewById(R.id.conditions);
chkdelete=(CheckBox)convertView.findViewById(R.id.id_chkDelete);
// Capture position and set results to the TextViews
datetime.setText(resultp.get("date_time"));
if(!resultp.get("Day_minutes").toString().equalsIgnoreCase("0"))
{
totminutes.setText(resultp.get("Day_minutes")+" min");
day_night_icon.setBackgroundResource(R.drawable.sun);
}else
{
totminutes.setText(resultp.get("Night_minutes")+" min");
day_night_icon.setBackgroundResource(R.drawable.moon);
}
skills.setText(resultp.get("Skill"));
weather.setText(resultp.get("weather"));
String supervisorText=resultp.get("super");
Log.w("SUPERVISOR", supervisorText);
if(supervisorText.equals("No supervisor"))
{
approval_icon.setBackgroundResource(R.drawable.pending);
}else
{
approval_icon.setBackgroundResource(R.drawable.approve);
}
String fontPath = "fonts/Roboto-Light.ttf";
Typeface tf = Typeface.createFromAsset(context.getAssets(), fontPath);
datetime.setTypeface(tf);
totminutes.setTypeface(tf);
skills.setTypeface(tf);
weather.setTypeface(tf);
// chkdelete.setTag(R.id.id_chkDelete);
chkdelete.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
// int checkBoxId = (Integer) buttonView.getTag();
if(SelectedBox.size()-1==0)
{
menu.setVisible(false);
addlog.setVisible(true);
}else
{
addlog.setVisible(false);
}
if(isChecked)
{
SelectedBox.add(position);
menu.setVisible(true);
addlog.setVisible(false);
}else /*if(!isChecked)*/
{
SelectedBox.remove(SelectedBox.indexOf(position));
}
}
});
menu.setOnMenuItemClickListener(new OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
// TODO Auto-generated method stub
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
// set title
alertDialogBuilder.setTitle("Student Driving Practice Log");
// set dialog message
alertDialogBuilder
.setMessage("Are you sure want to Delete Record!")
.setCancelable(false)
.setPositiveButton("Yes",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
try
{
NewNewDataHelper db=new NewNewDataHelper(context);
if(!SelectedBox.isEmpty())
{
for(int i=0;i<SelectedBox.size();i++)
{
resultp=data.get(SelectedBox.get(i));
String str[]=resultp.get("date_time").split(" ");
Log.d("Checked Element",str[0]+"\n"+str[1]+"\n"+resultp.get("Skill"));
db.DeleteSingleLog(resultp.get("Skill"),str[0],str[1]);
/*resultp=data.get(SelectedBox.get(i));
String str[]=resultp.get("date_time").split(" ");
db.DeleteSingleLog(resultp.get("Skill"),str[0],str[1]);*/
Toast.makeText(context,"Record Deleted", Toast.LENGTH_LONG).show();
}
Log.d("LISTSTSTSTST", SelectedBox.toString());
Intent intent = new Intent(context,ManagePracticeLogActivity.class);
intent.putExtra("s11", "delete");
context.startActivity(intent);
}
}catch(Exception e)
{
}
}
})
.setNegativeButton("No",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
// if this button is clicked, just close
// the dialog box and do nothing
dialog.cancel();
}
});
// create alert dialog
AlertDialog alertDialog = alertDialogBuilder.create();
// show it
alertDialog.show();
return false;
}
});
convertView.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View arg0)
{
resultp = data.get(position);
String str1 = null;
String str[]=resultp.get("date_time").toString().split(" ");
str1=str[0]+"~"+resultp.get("Skill")+"~"+str[1];
Log.d("PARTICULAR SKILLLLL", str1);
Intent intent = new Intent(context,LogEdit.class);
intent.putExtra("s11","Update Practice");
intent.putExtra("dataupdate",str1);
context.startActivity(intent);
}
});
return convertView;
}
private void deleteItems(List<Integer> list)
{
data.clear();
}
}
The problem is, view gets recycled due to recycling of ListView and the value of Checkbox(check or uncheck) is not maintained. You can check this link.
just have a look at this. This will explain the "problem" with checkboxes in listviews. There's also a link with a solution, if needed :)
When you load the view in getView, you need to set the check state for that particular item. I assume for each row you store this information somewhere? Just retrieve the correct state for the row (position) and set the correct state on the checkbox. The reason why you are seeing the behavior is because in a ListView rows are reused. The 6th row is in fact the 1st row. It is done this way to conserve memory and optimize a ListView for speed.
Inside your getView() add :
if(SelectedBox.contains(new Integer(position))) {
chkdelete.setChecked(true);
} else {
chkdelete.setChecked(false);
}
Related
Here is My Custom ListViewAdapter
public class ListViewAdapter extends BaseAdapter{
Viewholder holder;
public ArrayList<HashMap<?, ?>>list;
public ArrayList<Integer> add;
Activity activity;
boolean [] checkedItems;
String []ckboxTextAdd;
DbAdapter db;
/*
* Constructor Calling
*/
public ListViewAdapter(Activity activity,ArrayList<HashMap<? , ?>>list) {
// TODO Auto-generated constructor stub
super();
this.activity=activity;
this.list=list;
add=new ArrayList<Integer>(list.size());
db=new DbAdapter(activity);
db.open();
checkedItems= new boolean[list.size()];
ckboxTextAdd=new String[list.size()];
for(int i=0;i<list.size();i++)
{
checkedItems[i]=false;
ckboxTextAdd[i]="Add";
}
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
#Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
#Override
public View getView(final int position, View convertview, ViewGroup parent) {
// TODO Auto-generated method stub
LayoutInflater layoutInflater=activity.getLayoutInflater();
final HashMap<?, ?> map=list.get(position);
if(convertview==null)
{
convertview=layoutInflater.inflate(R.layout.l_view,parent,false);
holder = new Viewholder();
holder.title=(TextView) convertview.findViewById(R.id.serving_size_grams);
holder.servingsize=(TextView) convertview.findViewById(R.id.tvprotiendesclabel);
holder.Fiber=(TextView)convertview.findViewById(R.id.Fiberview);
holder.carbs=(TextView)convertview.findViewById(R.id.carbsview);
holder.sodium=(TextView)convertview.findViewById(R.id.sodiumview);
holder.proteins=(TextView)convertview.findViewById(R.id.Protienview);
holder.calories=(TextView)convertview.findViewById(R.id.caloriesview);
holder.img_serve_size=(ImageView)convertview.findViewById(R.id.image_serve_eqivalent);
holder.calories_val=(TextView)convertview.findViewById(R.id.cal_desc_val);
holder.Fiber_val=(TextView)convertview.findViewById(R.id.Fiber_desc_val);
holder.sodium_val=(TextView)convertview.findViewById(R.id.sodium_desc_val);
holder.proteins_val=(TextView)convertview.findViewById(R.id.prot_desc_val);
holder.carbs_val=(TextView)convertview.findViewById(R.id.carbs_desc_val);
holder.tvbrand=(TextView)convertview.findViewById(R.id.item_brand_name);
holder.ckbox=(CheckBox)convertview.findViewById(R.id.save_item_box);
holder.tvckboxText=(TextView)convertview.findViewById(R.id.ckboxAdd);
convertview.setTag(holder);
}
else
{
holder=(Viewholder)convertview.getTag();
}
holder.ckbox.setOnCheckedChangeListener(null);
holder.ckbox.setChecked(checkedItems[position]);
holder.tvckboxText.setText(ckboxTextAdd[position]);
holder.ckbox.setTag(R.id.save_item_box, position);
//On Check Box Check Events
holder.ckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(final CompoundButton buttonview, boolean isChecked) {
// TODO Auto-generated method stub
final int position = (Integer) buttonview
.getTag(R.id.save_item_box);
if (isChecked)
{
Log.i(String.valueOf(position), String.valueOf(isChecked));
checkedItems[position] = true;
ckboxTextAdd[position]="Added";
//holder.ckbox.setText(ckboxTextAdd[position]);
Log.i("value of Somple List", list.get(position).toString());
Log.i("value of listitr", list.get(position).toString());
Log.i("value of text box",ckboxTextAdd[position]);
final HashMap<?, ?> map=list.get(position);
map.get(Constants.NF_CALORIES);
String item_name =map.get(Constants.ITEM_NAME).toString().replace('\'', ' ');
String brand_name =map.get(Constants.BRAND_NAME).toString().replace('\'',' ');
Cursor cursor= db.fetch_data(item_name,brand_name);
if(cursor.getCount()>0)
{
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setMessage("Already Saved")
.setPositiveButton("Replace", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
checkedItems[position] = true;
ckboxTextAdd[position]="Added";
Log.i("value of text box trey",ckboxTextAdd[position]);
// holder.ckbox.setText(ckboxTextAdd[position]);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
checkedItems[position] = false;
ckboxTextAdd[position]="Add";
Log.i("value of text box false",ckboxTextAdd[position]);
//holder.ckbox.setText(ckboxTextAdd[position]);
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
}
else
{
Log.i("value of Calories",map.get(Constants.NF_CALORIES).toString());
db.createSave(
position
,brand_name
,item_name
,map.get("path").toString()
,map.get(Constants.NF_SERVING_SIZE_QTY).toString()
,map.get(Constants.NF_SERVING_SIZE_UNIT).toString()
,map.get(Constants.NF_CALORIES).toString()
,map.get(Constants.NF_PROTEINS).toString()
,map.get(Constants.NF_SODIUM).toString()
,map.get(Constants.NF_TOTAL_FAT).toString()
,map.get(Constants.NF_TOTAL_CARBOHYDRATES).toString()
,map.get(Constants.NF_SATURATED_FAT).toString()
,map.get(Constants.NF_CHOLESTEROL).toString()
,map.get(Constants.NF_VITAMIN_A).toString()
,map.get(Constants.NF_VITAMIN_C).toString()
,map.get(Constants.NF_IRON).toString()
,map.get(Constants.NF_CALCIUM).toString()
,map.get(Constants.NF_SERVING_WEIGHT_GRAMS).toString()
);
}
}
else
{
Log.i(String.valueOf(position), String.valueOf(isChecked));
//buttonview.setChecked(false);
//buttonview.setText("Save");
ckboxTextAdd[position]="Add";
Log.i("value of text box false",ckboxTextAdd[position]);
// holder.ckbox.setText(ckboxTextAdd[position]);
// holder.ckbox.setText("Save");
// holder.ckbox.setBackgroundColor(Color.rgb(198, 228, 225));
checkedItems[position] = false;
//holder.ckbox.setText(ckboxTextAdd[position]);
db.deleteUnChecked(position);
}
}
});
}
return convertview;
}
private class Viewholder extends Activity
{
TextView title;
TextView servingsize;
//TextView status;
TextView carbs;
TextView proteins;
TextView calories;
ImageView img_serve_size;
TextView sodium;
TextView Fiber;
TextView carbs_val;
TextView proteins_val;
TextView calories_val;
TextView sodium_val;
TextView Fiber_val;
CheckBox ckbox;
TextView tvbrand;
TextView tvckboxText;
}
Now what i wants to update my textview at the instant the checkbox is clicked in the listview
but till now it doest not do as desired but when i scroll down and take alook on the checked item then the textView is Updated
Please help me Thanks in advance
istesd use
holder.ckbox.setText(checkedItems[position]?"Added","Add");
and remove
holder.tvckboxText.setText(ckboxTextAdd[position]?"Added","Add"););
this because it might not support the landscape view
Problem:
When you're updating the values of array to map the status of checked or un-checked, you're not updating the TextView, as CheckBox's check or uncheck works out-of-box as implemented the api, but TextView's text need to be updated.
Solution:
You need to either manually update the TextView's text, or simply call notifyDataSetChanged() whenever you check or uncheck the item, this will let the getView() of Adapter called and will force to refresh the row based on updated value.
Suggestion/Improvement:
You can maintain single array of boolean only, no need to maintain the String array of Added or Add, while showing text, check if the boolean is true, set text as "Added", else "Add" like this:
holder.ckbox.setChecked(checkedItems[position]);
holder.tvckboxText.setText(checkedItems[position]?"Added":"Add");
Instead of implementing anonymous CompoundButton.OnCheckedChangeListener, implement it to class level and set as this, as of now you're creating multiple CompoundButton.OnCheckedChangeListener object every time when you scroll through the list.
Where are you closing the db? It doesn't matter though, but its good to have a closing point.
SQLController dbcon;
#Override
public View getChildView(int groupPosition, final int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
final String children = (String) getChild(groupPosition, childPosition);
TextView text;
if (convertView == null) {
convertView = inflater.inflate(R.layout.listrow_details, null);
}
text = (TextView) convertView.findViewById(R.id.textView1);
text.setText(children);
convertView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(activity, children,Toast.LENGTH_SHORT).show();
}
});
convertView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
AlertDialog.Builder Delete=new AlertDialog.Builder(activity);
Delete.setTitle("Show Linups Or Delete");
Delete.setMessage("Press Delete For Remove "+children+" or Press Show Lineups to get Lineups.");
Delete.setPositiveButton("Delete", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dbcon=new SQLController(activity);
dbcon.open();
Cursor c=dbcon.returnData();
if(c.moveToFirst())
{
do{
if(children.equals(c.getString(0))){
dbcon.deleteData(children);
notifyDataSetChanged();
Toast.makeText(activity,"Successfully Deleted",Toast.LENGTH_LONG).show();
break;
}
}while(c.moveToNext());
}
dbcon.close();
}
}).show();
return false;
}
});
return convertView;
}
This is my Group class with List in it,
public class Group {
public String string;
public final List<String> children = new ArrayList<String>();
public Group(String string) {
this.string = string;
}
}
This is my Expandable list adapter's getChildView Method, I am using Sqlite database and I store data to database and need to delete some items also so i use onLongClickListener for Deleting items, when I long click on the item I want to delete a popup appears having delete button, when I click on that button the item from database deleted but the item still appears on that activity until I reopen the application, what I want is when I click on delete button it should be disappear from that list also immediately,
Thanks in Advance,
You would have to remove the item from the list in this part of the code:
Cursor c=dbcon.returnData();
if(c.moveToFirst()){
do{
if(children.equals(c.getString(0))){
dbcon.deleteData(children);
removeItemFromList(c.getString(0);
notifyDataSetChanged();
Toast.makeText(activity,"Successfully Deleted",Toast.LENGTH_LONG).show();
break;
}
}while(c.moveToNext());
}
You just need to search for the string in your list and remove it.
private removeItemFromList(String object){
int index = children.indexOf(object);
if(index > -1){
children.remove(index);
}
}
Then when you call notifyDataSetChanged the list should update to reflect the change in data backing the ListView. Otherwise if you wanted to run this entirely off the SQLite you could use a cursor adapter instead but that would require converting the whole setup.
Edit
If you cannot use indexof just manually search for the string
int size = children.size();
int targetLocation = 0;
for(int i = 0; i < size; i++){
String indexString = children.get(i);
if(indexString.equals(object)){
targetLocation = i;
break;
}
}
children.remove(targetLocation);
Currently, I've been involved in an android app development related to online foodItem ordering. I've a listView with following schema:
itemName1 itemPrice1 checkBox
itemName2 itemPrice2 checkBox
itemName3 itemPrice3 checkBox
.
.
.
GetYourCart[Button]
My task is to keep track of each of the selected itemNames with price and total price when the user presses the button. I've used the SparseBooleanArray sbArray = myMenulist.getCheckedItemPositions(); but it's not showing any result.
How can I implement this? I've gone through several questions asked in stackoverflow and other online tutorials but can't get it.
Edited: Here is the code for selected items that I used to check the result:
btnyourCart.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
String selected = "";
int cntChoice = myMenulist.getCount();
SparseBooleanArray sbArray = myMenulist.getCheckedItemPositions();
for(int i=0;i<cntChoice;i++){
if(sbArray.get(i)) {
selected += myMenulist.getItemAtPosition(i).toString() + "\n";
}
}
Log.e("menu","Items "+selected);
Toast.makeText(getApplicationContext(), selected, Toast.LENGTH_SHORT).show();
}
});
Thanks in advance!
int total=0;
btnyourCart.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
String selected = "";
int cntChoice = myMenulist.getCount();
SparseBooleanArray sbArray = myMenulist.getCheckedItemPositions();
for(int i=0;i<cntChoice;i++){
if(sbArray.get(i)) {
selected += myMenulist.getItemAtPosition(i).toString() + "\n";
total+=myMenulist.get(i).price;
}
}
Log.e("menu","Items "+selected);
Toast.makeText(getApplicationContext(), selected, Toast.LENGTH_SHORT).show();
}
});
Now on button click event get total.
button.setOnClickListenernew View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(
this,
""+total,
Toast.LENGTH_LONG).show();
}
});
you need to do in your custom adapter in getView() method to keep checkbox value in list position and store that value in the array. This will keep checkbox value with its position.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
if(convertView == null){
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.list_layout, null);
final ViewHolder viewHolder = new ViewHolder();
viewHolder.checkBox = (CheckBox) view.findViewById(R.id.del_many_task_chk);
viewHolder.checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Model element = (Model) viewHolder.checkBox.getTag();
element.isChecked = buttonView.isChecked();
}
});
view.setTag(viewHolder);
viewHolder.checkBox.setTag(list.get(position));
}else{
view = convertView;
((ViewHolder)view.getTag()).checkBox.setTag(list.get(position));
}
ViewHolder holder = (ViewHolder) view.getTag();
holder.checkBox.setChecked(list.get(position).isChecked);
return view;
}
Now when need to know which check box are checked or not then you need to go through your list item using iterator. To get the checked and unchecked item based on checkbox value.
for(int i=0;i<list.size();i++){
if(all_task_list.get(i).isChecked){
// to do things for checked item
}else{
// to do things for uncheck item
}
}
I have an activity which extends ListActivity. It has many things but amongst them it shows the articles the user has purchased with an adapter. Well I have a method that the user can delete the items from the list. The problem is when there is only one item. If I try to delete the last one the app crashes. Here is a it of my code:
public class Ventas extends ListActivity {
......
lv = getListView();
......
protected void confirmRemoval(final int arg2) {
// TODO Auto-generated method stub
AlertDialog alertDialog = new AlertDialog.Builder(this).create();
alertDialog.setTitle(getResources().getString(R.string.ventas));
alertDialog.setMessage(getResources().getString(R.string.confirmacion2));
alertDialog.setButton("Si",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
if(adapter2.mEvents.size()>=1){
adapter2.mEvents.remove(arg2);
} else {
//doesn't work
/*adapter2=null;
adapter2.notifyDataSetInvalidated();
lv.setVisibility(View.GONE);*/
}
}
});
alertDialog.setButton2("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
dialog.dismiss();
}
});
alertDialog.show();
}
here is the adapter and wrapper:
private class EventAdapter2 extends BaseAdapter {
public ArrayList<Articulo> mEvents = null;
public EventAdapter2(Context c, ArrayList<Articulo> clientes) {
mContext = c;
mEvents = clientes;
}
public int getCount() {
return mEvents.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
EventEntryView2 btv;
if (convertView == null) {
btv = new EventEntryView2(mContext, mEvents.get(position));
} else {
btv = (EventEntryView2) convertView;
String title1 = mEvents.get(position).getCantidad() + "";
if (title1 != null) {
btv.setText1Title(title1);
}
String title2 = mEvents.get(position).getDescripcion();
if (title2 != null) {
btv.setText2Title(title2);
}
String title3 = mEvents.get(position).getpVenta() + "0";
if (title3 != null) {
btv.setText3Title(title3);
}
String title4 = (mEvents.get(position).getCantidad() * mEvents
.get(position).getpVenta()) + "0";
if (title4 != null) {
btv.setText4Title(title4);
}
}
return btv;
}
private Context mContext;
}
private class EventEntryView2 extends LinearLayout {
private TextView text1;
private TextView text2;
private TextView text3;
private TextView text4;
private View inflatedView;
public EventEntryView2(Context context, Articulo resp) {
super(context);
this.setOrientation(VERTICAL);
inflatedView = View.inflate(context, R.layout.results, null);
text1 = (TextView) inflatedView.findViewById(R.id.textView1);
text2 = (TextView) inflatedView.findViewById(R.id.textView2);
text3 = (TextView) inflatedView.findViewById(R.id.textView3);
text4 = (TextView) inflatedView.findViewById(R.id.textView4);
String t = resp.getCantidad() + "";
text1.setText(t);
String t1 = resp.getDescripcion();
text2.setText(t1);
String t2 = resp.getpVenta() + "0";
text3.setText(t2);
String t3 = (resp.getCantidad() * resp.getpVenta()) + "0";
text4.setText(t3);
addView(inflatedView, new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
}
public void setText4Title(String title4) {
text4.setText(title4);
}
public void setText3Title(String title3) {
text3.setText(title3);
}
public void setText2Title(String title2) {
text2.setText(title2);
}
public void setText1Title(String title1) {
text1.setText(title1);
}
}
as you can see when I have only one item left I have tried to set adapter to null or adapter.notifyDataSetInvaliadted or even making the listview invisible, nothing works. What happens is when I click ok nothing changes then when I click a second time it all crashes
What I would like is the listView to disappear when the adapter is empty but I am now out of ideas, is it even possible?
Any ideas?
EDIT:
Thank you all for the answers but the problem was I was modifying the list from inside an inner anonymous class. It is actually pretty simple, create a method and call it from inside the dialog, once the array is empty the list disappears automatically:
protected void removeFromList(int arg2) {
adapter2.mEvents.remove(arg2);
adapter2.notifyDataSetChanged();
}
remove item from the arraylist which you add into the adapter and then call this method.
youradapter.notifyDataSetChanged();
and whatever you do for single item that was
adapter2 = null;
adapter2.notifyDataSetInavlidated();
this will obviously crash it because adapter2 object was null so how null object notify its data
Try calling lv.invalidate() after the remove() and see whether that makes any difference.
You should check in your adapter class if it is null then you should not fetch value from it......that's the main reason why you are getting exception as you are fetching the value from null variable.Put check there.
For setVisibility to Work:
You create your main.xml
Add to it a ListView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/sherif.android.deedz"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView android:layout_width="match_parent"
android:layout_height="match_parent" android:id="#+id/myListView"
android:divider="#ffa500" android:dividerHeight="1px"
android:background="#drawable/somedrawable_xml"
android:choiceMode="singleChoice"></ListView>
</ListView>
Now you can make it GONE
If you want the whole details of this :
Check my answer
I am trying to implement ListView with Delete functionality to delete item from the listview. I am successful to delete but failed to refresh the listview after deletetion of an item from the database.
Actually, Click on listitem, i am displaying AlertBox for "Delete" and "Cancel" action, on clicking "Delete", item should be removed from the database and as well as from the listview and listview should be refreshed. I have also used notifyDataSetChanged() method.
lview = (ListView) findViewById(R.id.lview);
adapter = new ListView_CustomAdapter(this, listitemDisplay);
lview.setAdapter(adapter);
lview.setOnItemClickListener(new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> a, View v, int position, long id)
{
Show_Alert_box(v.getContext(),"Please select action.",position);
}
});
and the code for Show_Alert_box:
public void Show_Alert_box(Context context, String message,int position)
{
final int pos = position;
final AlertDialog alertDialog = new AlertDialog.Builder(context).create();
alertDialog.setTitle(getString(R.string.app_name_for_alert_Dialog));
alertDialog.setButton("Delete", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
try
{
db.open();
String[] whereArgs={String.valueOf(pkID)};
return db.delete(DATABASE_TABLE_4,"pk_pkID == ?",whereArgs);
adapter.notifyDataSetChanged();
db.close();
}
catch(Exception e)
{
}
} });
alertDialog.setButton2("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
alertDialog.dismiss();
} });
alertDialog.setMessage(message);
alertDialog.show();
}
Does it remove it from your list adapter?
If not that would be the reason the notifyDataSetChanged() won't do you much good.
Actually looking at your code again i can only find that you're removing it from your database and not the adapter itself.
edit (to answer comment):
Well that's hard to do without your ListView_CustomAdapter class.
The problem is, in this adapter there's a data set (the one you put in the constructor (listitemDisplay)) which needs to be updated as well. Only then the notifyDataSetChanged() will work.
Call that Activity once again Using Intent
I'm guessing that using
getActivity().recreate();
instead of restarting the activity via a new Intent is better because using a new Intent will only stop the current activity and not destroy it.
Anyway, it works.
if you have the cursor, call requery() before calling notifyDataChanged()
I did something like this in my adapter:
((Activity)cxt).finish();
Intent intent = new Intent(cxt, YourActivity.class);
cxt.startActivity(intent);
This ends the activity and then starts the same one again.
I think instead of calling the activity again, you should set the adapter to the listview on the alertBox delete option after getting the updated data from the database and putting into listitemDisplay list like this.
alertDialog.setButton("Delete", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
try
{
db.open();
String[] whereArgs={String.valueOf(pkID)};
return db.delete(DATABASE_TABLE_4,"pk_pkID == ?",whereArgs);
listitemDisplay = db.getItemFromDB();
adapter = new ListView_CustomAdapter(this, listitemDisplay);
lview.setAdapter(adapter);
db.close();
}
catch(Exception e)
{
}
} });
This will refresh the listView
I have the solution:
If you want to delete a row from a list view clicking on the DELETE button of each of that row do this. Here you have an example of a custom adapter class with a name and a delete button. Every time you press the button the row is deleted
public class UserCustomAdapter extends ArrayAdapter<User>{
Context context;
int layoutResourceId;
ArrayList<User> data = new ArrayList<User>();
public UserCustomAdapter(Context context, int layoutResourceId,ArrayList<User> data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View row = convertView;
UserHolder holder = null;
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new UserHolder();
holder.textName = (TextView) row.findViewById(R.id.textView1);
holder.btnDelete = (Button) row.findViewById(R.id.button2);
row.setTag(holder);
} else {
holder = (UserHolder) row.getTag();
}
User user = data.get(position);
holder.btnDelete.setTag(position);
holder.textName.setText(user.getName());
holder.btnDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String pos = v.getTag().toString();
int _posicion = Integer.parseInt(pos);
data.remove(_posicion);
notifyDataSetChanged();
}
});
return row;
}
static class UserHolder {
TextView textName;
Button btnDelete;
}
}
Try calling refreshDrawableState to tell the list to redraw.
Make a new function outside your onCreate block {something like... getdata()} and inside that insert and get all your data and set to the adapter.
Then call the function again in your onResume() block. So whenever you will delete the data from the list it will reflect immediately.