滚动位置错误时的列表视图

Listview when scroll is getting the wrong position

我有一个列表视图、一行、两个文本和一个删除按钮。我可以删除项目,但有时它会删除不同的项目,而不是点击。

我检查了列表中的 ID。我用的是Retrofit,点击删除按钮才响应,用的是notifyDataSetChanged();对于列表(setFavoriteMerchant())

public class FavoriteMerchantActivity extends AppCompatActivity implements IButtonCliclListener {

    FavoriteMerchantAdapter favoriteMerchantAdapter;

    @InjectView(R.id.ListFavoriteMerchant)
    ListView ListFavoriteMerchant;

    AlertDialogHelper alertDialogHelper;

    List<ItemsFavoriteMerchant> list;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_favorite_merchant);
        ButterKnife.inject(this);
        alertDialogHelper = new AlertDialogHelper(this);

        getFavoriteMerchant();
    }

    @Override
    public void onClick(View v) {
        int itemIndex = (int) v.getTag();
        setFavoriteMerchant(itemIndex);
        alertDialogHelper.showAlertSuccess("Removed from your favorites!");
    }

    void getFavoriteMerchant() {

        Call<FavoriteMerchant> call = ToolApi.getApi().getFavoriteMerchant(BaseService.TOKEN);
        call.enqueue(new Callback<FavoriteMerchant>() {
            @Override
            public void onResponse(Response<FavoriteMerchant> response, Retrofit retrofit) {

                if (response.body() != null) {
                    FavoriteMerchant favoriteMerchant = response.body();

                    Integer errorCode = favoriteMerchant.getStatus().getErrorCode();

                    if (errorCode == 0) {

                        list = favoriteMerchant.getItems();

                        favoriteMerchantAdapter = new FavoriteMerchantAdapter(FavoriteMerchantActivity.this, alertDialogHelper, favoriteMerchant, list, getApplicationContext());
                        ListFavoriteMerchant.setAdapter(favoriteMerchantAdapter);
                    }

                }
                else {
                    startActivity(getIntent());
                    alertDialogHelper.showAlertError("Connection error...");
                }
            }

            @Override
            public void onFailure(Throwable t) {
                startActivity(getIntent());
                alertDialogHelper.showAlertError("Connection error...");
            }
        });
    }

    void setFavoriteMerchant(final int index) {

        Call<SetFavoriteMerchant> call = ToolApi.getApi().setFavoriteMerchant(BaseService.TOKEN, index, true);
        call.enqueue(new Callback<SetFavoriteMerchant>() {
            @Override
            public void onResponse(Response<SetFavoriteMerchant> response, Retrofit retrofit) {

                for (ItemsFavoriteMerchant item : list) {
                    if (item.getID() == index) {
                        list.remove(item);
                        favoriteMerchantAdapter.notifyDataSetChanged();

                    }
                }
            }

            @Override
            public void onFailure(Throwable t) {
                alertDialogHelper.showAlertError("connection error...");
            }
        });
    }

public class FavoriteMerchantAdapter extends BaseAdapter implements View.OnClickListener {

    List<ItemsFavoriteMerchant> itemsFavoriteMerchant;
    FavoriteMerchant favoriteMerchant;
    Context context;
    AlertDialogHelper alertDialogHelper;
    private IButtonCliclListener iButtonCliclListener;

    public FavoriteMerchantAdapter(IButtonCliclListener iButtonCliclListener, AlertDialogHelper alertDialogHelper, FavoriteMerchant favoriteMerchant, List<ItemsFavoriteMerchant> itemsFavoriteMerchant, Context context) {
        this.favoriteMerchant = favoriteMerchant;
        this.context = context;
        this.itemsFavoriteMerchant = itemsFavoriteMerchant;
        this.alertDialogHelper = alertDialogHelper;
        this.iButtonCliclListener = iButtonCliclListener;
    }

    @Override
    public int getCount() {
        return itemsFavoriteMerchant.size();
    }

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

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        FavoriteMerchantAdapter.ViewHolder viewHolder;
        String CDnPath = favoriteMerchant.getCDNPath();
        ItemsFavoriteMerchant item = itemsFavoriteMerchant.get(position);
        if (convertView == null) {
            LayoutInflater layoutInflater = LayoutInflater.from(context);
            viewHolder = new FavoriteMerchantAdapter.ViewHolder();
            convertView = layoutInflater.inflate(R.layout.item_favorite_merchant, null);

            viewHolder.FavoriteMerchantPlaceDesc = (TextViewGothamBook) convertView.findViewById(R.id.FavoriteMerchantPlaceDesc);
            viewHolder.FavoriteMerchantLocationDesc = (TextViewGothamMedium) convertView.findViewById(R.id.FavoriteMerchantLocationDesc);
            viewHolder.FavoriteMerchantCashDesc = (TextViewGothamMedium) convertView.findViewById(R.id.FavoriteMerchantCashDesc);
            viewHolder.FavoriteMerchantDesc = (TextViewGothamMedium) convertView.findViewById(R.id.FavoriteMerchantDesc);
            viewHolder.FavoriteMerchantLogo = (ImageView) convertView.findViewById(R.id.FavoriteMerchantLogo);
            viewHolder.FavoriteMerchantDeleteButton = (ImageButton) convertView.findViewById(R.id.im_btn_deletemerchant);
            viewHolder.FavoriteMerchantDeleteButton.setTag(item.getID());
            viewHolder.FavoriteMerchantDeleteButton.setOnClickListener(this);
            convertView.setTag(item.getID());
            //convertView.setTag(viewHolder);
        }
        else {

            viewHolder = (FavoriteMerchantAdapter.ViewHolder) convertView.getTag();
        }

        /*
            String CDnPath = favoriteMerchant.getCDNPath();
            ItemsFavoriteMerchant item = itemsFavoriteMerchants.get(position);
        */

        String ImageUrl = item.getCoverPageImageURL();
        if (ImageUrl != null && !ImageUrl.isEmpty())
            Picasso.with(context)
                    .load(CDnPath + ImageUrl)
                    .transform(new CircleTransform())
                    .into(viewHolder.FavoriteMerchantLogo);


        String MerchantPlaceDesc = item.getName();
        if (MerchantPlaceDesc != null && !MerchantPlaceDesc.isEmpty())
            viewHolder.FavoriteMerchantPlaceDesc.setText(MerchantPlaceDesc);

        String MerchantocationDesc = (String) item.getDistrict();
        if (MerchantocationDesc != null && !MerchantocationDesc.isEmpty())
            viewHolder.FavoriteMerchantLocationDesc.setText(MerchantocationDesc);

        String MerchantCashDesc = "";
        if (MerchantCashDesc != null && !MerchantCashDesc.isEmpty())
            viewHolder.FavoriteMerchantCashDesc.setText(MerchantCashDesc);

        return convertView;
    }

    @Override
    public void onClick(View v) {
        this.iButtonCliclListener.onClick(v);
    }

    public static class ViewHolder {

        ImageView FavoriteMerchantLogo;
        TextViewGothamBook FavoriteMerchantPlaceDesc;
        TextViewGothamMedium FavoriteMerchantLocationDesc;
        TextViewGothamMedium FavoriteMerchantCashDesc;
        TextViewGothamMedium FavoriteMerchantDesc;
        ImageButton FavoriteMerchantDeleteButton;
    }
}

使用:

if (convertView == null) {
    LayoutInflater layoutInflater = LayoutInflater.from(context);
    viewHolder = new FavoriteMerchantAdapter.ViewHolder();
    convertView = layoutInflater.inflate(R.layout.item_favorite_merchant, null);

    viewHolder.FavoriteMerchantPlaceDesc = (TextViewGothamBook) convertView.findViewById(R.id.FavoriteMerchantPlaceDesc);
    viewHolder.FavoriteMerchantLocationDesc = (TextViewGothamMedium) convertView.findViewById(R.id.FavoriteMerchantLocationDesc);
    viewHolder.FavoriteMerchantCashDesc = (TextViewGothamMedium) convertView.findViewById(R.id.FavoriteMerchantCashDesc);
    viewHolder.FavoriteMerchantDesc = (TextViewGothamMedium) convertView.findViewById(R.id.FavoriteMerchantDesc);
    viewHolder.FavoriteMerchantLogo = (ImageView) convertView.findViewById(R.id.FavoriteMerchantLogo);
    viewHolder.FavoriteMerchantDeleteButton = (ImageButton) convertView.findViewById(R.id.im_btn_deletemerchant);
    viewHolder.FavoriteMerchantDeleteButton.setTag(item.getID());
    viewHolder.FavoriteMerchantDeleteButton.setOnClickListener(this);
    convertView.setTag(item.getID());
    //convertView.setTag(viewHolder);
}

your setting tags only when convert view is null.

 convertView.setTag(item.getID()); // This call should be made to all getview calls.

解决方案(查看评论):

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    FavoriteMerchantAdapter.ViewHolder viewHolder;
    String CDnPath = favoriteMerchant.getCDNPath();
    ItemsFavoriteMerchant item = itemsFavoriteMerchant.get(position);
    if (convertView == null) {
        LayoutInflater layoutInflater = LayoutInflater.from(context);
        viewHolder = new FavoriteMerchantAdapter.ViewHolder();
        convertView = layoutInflater.inflate(R.layout.item_favorite_merchant, null);

        viewHolder.FavoriteMerchantPlaceDesc = (TextViewGothamBook) convertView.findViewById(R.id.FavoriteMerchantPlaceDesc);
        viewHolder.FavoriteMerchantLocationDesc = (TextViewGothamMedium) convertView.findViewById(R.id.FavoriteMerchantLocationDesc);
        viewHolder.FavoriteMerchantCashDesc = (TextViewGothamMedium) convertView.findViewById(R.id.FavoriteMerchantCashDesc);
        viewHolder.FavoriteMerchantDesc = (TextViewGothamMedium) convertView.findViewById(R.id.FavoriteMerchantDesc);
        viewHolder.FavoriteMerchantLogo = (ImageView) convertView.findViewById(R.id.FavoriteMerchantLogo);
        viewHolder.FavoriteMerchantDeleteButton = (ImageButton) convertView.findViewById(R.id.im_btn_deletemerchant);
        viewHolder.FavoriteMerchantDeleteButton.setTag(item.getID());
        viewHolder.FavoriteMerchantDeleteButton.setOnClickListener(this);
        //convertView.setTag(item.getID()); // Update
        convertView.setTag(viewHolder);
    }
    else {
        viewHolder = (FavoriteMerchantAdapter.ViewHolder) convertView.getTag();
    }

    /*
        String CDnPath = favoriteMerchant.getCDNPath();
        ItemsFavoriteMerchant item = itemsFavoriteMerchants.get(position);
    */

    String ImageUrl = item.getCoverPageImageURL();
    if (ImageUrl != null && !ImageUrl.isEmpty())
        Picasso.with(context)
                .load(CDnPath + ImageUrl)
                .transform(new CircleTransform())
                .into(viewHolder.FavoriteMerchantLogo);


    String MerchantPlaceDesc = item.getName();
    if (MerchantPlaceDesc != null && !MerchantPlaceDesc.isEmpty())
        viewHolder.FavoriteMerchantPlaceDesc.setText(MerchantPlaceDesc);

    String MerchantocationDesc = (String) item.getDistrict();
    if (MerchantocationDesc != null && !MerchantocationDesc.isEmpty())
        viewHolder.FavoriteMerchantLocationDesc.setText(MerchantocationDesc);

    String MerchantCashDesc = "";
    if (MerchantCashDesc != null && !MerchantCashDesc.isEmpty())
        viewHolder.FavoriteMerchantCashDesc.setText(MerchantCashDesc);
    viewHolder.FavoriteMerchantDeleteButton.setTag(item.getID()); // check update
    return convertView;
}