ListView always deletes last row from CustomAdaptor

android listview custom adapter
android listview arrayadapter
custom listview with arrayadapter in android
android dynamic listview example
custom listview in android example
listview onitemclicklistener custom adapter
how to set data in listview in android
android listview adapter

I have a ListView in AlertDialog which contains more button on each row & it will popup a list with delete option. When I click on delete option, its deleting the last item. In CustomAdaptor I tried a notifyDataSetChanged() after deleting item from ArrayList. Here it always deletes the last item irrespective of item position.

CustomAdaptor Code

public class CustomAdapter extends BaseAdapter {
Context context;
List<String> lrowItems ;
ArrayList<String> listItems;
String className;
CalHelper calHelper;
Settings settings;
LayoutInflater inflter;
public CustomAdapter(Context applicationContext, ArrayList<String> listItems) {
    this.context = applicationContext;
    this.listItems = listItems;
    this.className = context.getClass().getSimpleName();
    this.calHelper  = new CalHelper(applicationContext);
    this.settings  = new Settings(applicationContext);
    inflter = (LayoutInflater.from(applicationContext));
}

@Override
public int getCount() {
    if(listItems != null) {
        return listItems.size();
    }else{
        return 0;
    }
}

@Override
public Object getItem(int position) {
    return listItems.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

//With following overrides Prevent listview item will not mix randomly
//and convertView provided is of the appropriate type.
@Override
public int getViewTypeCount() {
    if(getCount() > 0){ //for no records in returning view
        return getCount();
    }else{
        return super.getViewTypeCount();
    }
}

@Override
public int getItemViewType(int position) {
    return position;
}

/* private view holder class for holding calculation history*/
private class HistoryViewHolder {
    TextView more;
    TextView expression;
    TextView result;
    TextView shortNote;
    TextView expTime;
}

/* private view holder class for holding GST calculations history*/
private class GstHistoryViewHolder {
    TextView amount;
    TextView gst;
    TextView total;
    TextView expTime;
    ImageView share;
}

/* private view holder class */
private class BMIViewHolder {
    TextView bmiScore;
    TextView bmiDate;
    TextView bmiWeight;
}

@Override
public View getView(final int position, View convertView, ViewGroup viewGroup) {
    LayoutInflater mInflater = (LayoutInflater) context
            .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
    //final int pos = position;
    if(className.equals("MainActivity")) {
        final HistoryViewHolder holder = new HistoryViewHolder();
        final String expString = listItems.get(position);
        final String expre = expString.substring(0, expString.indexOf(":"));
        final String expreTime = expString.substring(expString.indexOf(":") + 1, expString.length());
        final String result = expre.substring(expre.indexOf("=")+1);
        String timePattern = calHelper.calHistoryTimePattern(expreTime);
        SimpleDateFormat localDateFormat = new SimpleDateFormat(timePattern);

        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.listview_row, null);
            holder.more = (TextView) convertView
                    .findViewById(R.id.more);
            holder.expression = (TextView) convertView.findViewById(R.id.expression);
            holder.result = (TextView) convertView.findViewById(R.id.result);
            holder.shortNote = (TextView) convertView.findViewById(R.id.shortNote);
            holder.expTime = (TextView) convertView.findViewById(R.id.expTime);
            holder.expression.setText(expre.substring(0, expre.indexOf("=")));
            holder.result.setText(result);
            String time = localDateFormat.format(new Date(expreTime));
            holder.expTime.setText(time);
            holder.shortNote.setText(settings.getHistoryNote(context,expString));

            convertView.setTag(holder);

            final TextView btnMore = (TextView) holder.more;
            btnMore.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    showPopup(v, position, expString, expre, expreTime, holder.shortNote);
                }
            });

        }
    }


    return convertView;
}


public void showPopup(View v, final int position, final String expString, final String expression, final String expTime, final TextView shortNote) {
    final PopupMenu popup = new PopupMenu(context, v);

    //truncate title with ellipsis for more characters
    final String noteTitle = expression.length()>10? expression.substring(0, 10) + "..." : expression;
    MenuInflater inflater = popup.getMenuInflater();
    inflater.inflate(R.menu.history_menu, popup.getMenu());
    //registering popup with OnMenuItemClickListener
    popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
        public boolean onMenuItemClick(MenuItem item) {
            Intent intent = new Intent(context, MainActivity.class);
            int itenId = item.getItemId();
            switch (itenId){
                case R.id.mnuInsertExpression:
                    //some code here
                break;
                case R.id.mnuHisNote:
                    //some code here                        
                    break;
                case  R.id.mnuCopyHisRecord:
                    calHelper.copyToClipboard(expression);
                    break;
                case R.id.mnuShareHisRecord:
                    calHelper.shareText(expression);
                    break;
                case  R.id.mnuDeleteHisRecord:  //This is where I am deleting item
                    System.out.println("Pos:"+position);
                      listItems.remove(position);
                      notifyDataSetChanged();
                    Collections.reverse(listItems); //sort descending by time again
                    settings.clearSharedPre(context,expString); //remove note attached to this expression from ShredPref
                    settings.saveArrayList(context, listItems, "EXP_HISTORY");
                    intent.putExtra("HISTORY_RECORD_DELETED", true);
                    Toast.makeText(context,"Record removed from history", Toast.LENGTH_SHORT).show();
                    context.startActivity(intent);
                    break;
            }
            return true;
        }
    });
    popup.show();
}

Any help is greatly appreciated.


Try this getView():

        @Override
        public View getView(int position, View convertView, ViewGroup viewGroup) {
            HistoryViewHolder holder;
            if(className.equals("MainActivity")) {
                final String expString = listItems.get(position);
                final String expre = expString.substring(0, expString.indexOf(":"));
                final String expreTime = expString.substring(expString.indexOf(":") + 1, expString.length());
                final String result = expre.substring(expre.indexOf("=")+1);
                String timePattern = calHelper.calHistoryTimePattern(expreTime);
                SimpleDateFormat localDateFormat = new SimpleDateFormat(timePattern);

                if (convertView == null) {
                    LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
                    convertView = mInflater.inflate(R.layout.listview_row, null);
                    holder = new HistoryViewHolder();
                    holder.more = (TextView) convertView.findViewById(R.id.more);
                    holder.expression = (TextView) convertView.findViewById(R.id.expression);
                    holder.result = (TextView) convertView.findViewById(R.id.result);
                    holder.shortNote = (TextView) convertView.findViewById(R.id.shortNote);
                    holder.expTime = (TextView) convertView.findViewById(R.id.expTime);

                    holder.more.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            int pos = (int) v.getTag();
                            showPopup(v, pos, expString, expre, expreTime, holder.shortNote);
                        }
                    });
                }else{
                    holder = (HistoryViewHolder)convertView.getTag();
                }
                holder.expression.setText(expre.substring(0, expre.indexOf("=")));
                holder.result.setText(result);
                String time = localDateFormat.format(new Date(expreTime));
                holder.expTime.setText(time);
                holder.shortNote.setText(settings.getHistoryNote(context, expString));
                holder.more.setTag(position);
                convertView.setTag(holder);
            }
            return convertView;
        }

Hope that helps!

Using lists in Android wth ListView - Tutorial, The adapter would inflate the layout for each row in its getView() method and final ListView listview = (ListView) findViewById(R.id.listview); String[] values = new Frequently you extend ArrayAdapter to write a custom adapter, as this is android:layout_height="wrap_content" android:text="Deleted"  ListView always deletes last row from CustomAdaptor I have a ListView in AlertDialog which contains more button on each row & it will popup a list with delete option. When I click on delete option, its deleting the last item.


Its because you are using the position of the getView parameter, that will always be whatever the last index is at the time you go to use it.

Instead you need to add that position to the view, possibly in your convertView is what I usually do (the tag can be anything you want), do convertView.setTag(position) in your getView method as you are creating each items view, and then in your delete method within showpopup you can do (int)view.getTag() to get the position to remove from your dataset.

List view delete button, Listview delete item | Delete Row Item in ListView | Delete a row from list view on Sep 20, 2010 · Always show buttons in the bottom of screen after list (no user specified confirmation message. i created a custom adapter for a listview also i  procedure TForm1.Button2Click(Sender: TObject); begin ListView1.Columns.Delete(1); end; Result: The column is deleted, but the caption of the last column gets lost. This also happens, when adding more columns and deleting a column that is between others (or deleting the first column). The caption of the last column is always empty. I'm using XE3.


You should add the postion to the button using setTag() and get the position when passing it to showPopup() using getTag(). You can do the following.

 // ....
 final TextView btnMore = (TextView) holder.more;
 btnMore.setTag(position); // here add the position to the button using setTag().
 btnMore.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
         // here you can get position your button using v.getTag().
         int pos = (int) v.getTag();
         showPopup(v, pos, expString, expre, expreTime, holder.shortNote);
    }
});

Android ListView - Removing Items, In last week's post, we've covered how to add items to ListView. However, when we have such a feature, you almost always need to implement its complement. Highlight the selected row and display a delete menu icon; Once the We're going to track the selected items from our custom adapter class. 'Delete Selected Items For i As Integer = ListView1.SelectedItems.Count - 1 To 0 Step -1 ListView1.SelectedItems(i).Remove() Next 'Clear Previously selected Items ListView1.SelectedItems.Clear() 'Highlight only when there are items If ListView1.Items.Count > 0 Then 'get the index of last item Dim Index As Integer = ListView1.Items.Count - 1 'Select the last item ListView1.Items(ListView1.Items.Count - 1).Selected = True ListView1.EnsureVisible(Index) 'Put Fucus in Listview ListView1.Select


ListView Tutorial— Android #12, icons from icons8.com as always, the legends! Check out my latest blog: This is basically like a layout file for each row of the ListView, showing Add code to create an instance of the Custom Adapter and populate with your data arrays. Delete the default TextView that's in there and add a ListView:. Android ListView with custom layout using image (ImageView) Another interesting example is using an image for each row. To keep things simple and clear we supposed that the image is always the same but we could change it as the planet changes.


Android listview item height dynamic, We will see how to handle button's click listeners in every row item of listview. The last parameter faculties is our array name. window and then show it as drop down when the button was touched. first row is always visible, the second one In this Android Example creating a custom adapter to create a custom ListView. As a ListView is instantiated and the rows are populated such that the full height of the list is filled. After that no new row items are created in the memory. As the user scrolls through the list, items that leave the screen are kept in memory for later use and then every new row that enters the screen reuses an older row kept in the memory.


Delete button in customAdapter always removes last element, Delete button in customAdapter always removes last element - android. I have ListView with row as TextView and Switch. Now I want that When I click on First  Edit: well I could have sworn it deleted the correct line. No matter what number I put in for the row it always deletes the last row. Here is what is happening to the control exactly. At first it appears to delete the correct line, but does not refresh the control properly. Running the following code