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, има ли някаква разлика в нормалното функциониране на listview/адаптора. - 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