ListView всегда удаляет последнюю строку из CustomAdaptor

У меня есть ListView в AlertDialog, который содержит больше кнопок в каждой строке, и он выводит список с опцией удаления. Когда я нажимаю на опцию удаления, он удаляет последний элемент. В CustomAdaptor я попробовал notifyDataSetChanged() после удаления элемента из ArrayList. Здесь он всегда удаляет последний элемент, независимо от его позиции.

Код пользовательского адаптера

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();
}

Любая помощь приветствуется.


person deepak kulkarni    schedule 08.10.2019    source источник


Ответы (3)


Попробуйте это 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;
        }

Надеюсь, это поможет!

person i_A_mok    schedule 11.10.2019
comment
Большой!! Оно работает. holder.more.setOnClickListene выдает синтаксическую ошибку, я заменил ее оригинальным btnMore.setOnClickListener, но все остальное так, как вы упомянули. Большое спасибо. - person deepak kulkarni; 12.10.2019

Это потому, что вы используете позицию параметра getView, это всегда будет последний индекс в то время, когда вы собираетесь его использовать.

Вместо этого вам нужно добавить эту позицию в представление, возможно, в вашем convertView это то, что я обычно делаю (тег может быть любым, что вы хотите), сделайте convertView.setTag(position) в своем методе getView, когда вы создаете представление каждого элемента, а затем в вашем методе удаления в showpopup вы можете сделать (int)view.getTag(), чтобы удалить позицию из вашего набора данных.

person Boardy    schedule 08.10.2019
comment
Нет эффекта при использовании setTag и getTag. Я получаю правильное положение просмотра, но удаляет только последний элемент. Я показываю ListView в AlertDalog, это как-то влияет на нормальное функционирование списка/адаптера. - person deepak kulkarni; 09.10.2019

Вы должны добавить postion к button, используя setTag(), и получить position при передаче его в showPopup(), используя getTag(). Вы можете сделать следующее.

 // ....
 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);
    }
});
person Jakir Hossain    schedule 08.10.2019
comment
Это снова удаление последнего элемента. - person deepak kulkarni; 09.10.2019