【问题标题】:ListView Showing duplicate items when scrolled beyond visible part of screenListView 滚动超出屏幕可见部分时显示重复项
【发布时间】:2016-04-04 08:29:50
【问题描述】:

我的问题真的很疯狂。我有一个 ListView 和一个自定义适配器。现在在自定义适配器中,我在 ViewAnimator 中有两组项目,第一组仅包含一个按钮(一个三点“更多”按钮),而第二组包含“信息”、“删除”和“共享”按钮.我称它们为按钮,但它们实际上是可点击的 ImageView。 “更多”按钮是默认的可见项。单击“更多”按钮时,视图动画器显示第二组。

现在发生的疯狂事情是,虽然第二组在特定列表项上可见,但如果您向下滚动列表超出显示该列表项的第二组时可见的部分,一些随机列表项自动显示第二组。(而不是等待点击更多按钮) 请注意,这只影响 ViewAnimator 项目。列表中的文本视图都是正确的。 ViewAnimator 以某种方式自动激活。 非常感谢任何形式的帮助。

下面是我的自定义适配器类。

package model;

import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.ViewAnimator;

import com.app.myapp.R;

import java.util.ArrayList;



public class CustomListviewAdapter extends ArrayAdapter<UserItem> {

private int layoutResource;
private Activity activity;
private ArrayList<UserItem> userItemsList = new ArrayList<>();

public CustomListviewAdapter(Activity act, int resource, ArrayList<UserItem> data) {
    super(act, resource, data);
    layoutResource = resource;
    activity = act;
    userItemsList = data;
    notifyDataSetChanged();

}

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

@Override
public UserItem getItem(int position) {
    return userItemsList.get(position);
}

@Override
public int getPosition(UserItem item) {
    return super.getPosition(item);
}

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

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    View row = convertView;
    ViewHolder holder;

    if ( row == null || (row.getTag() == null)) {

        LayoutInflater inflater = LayoutInflater.from(activity);
        row = inflater.inflate(layoutResource, null);

        holder = new ViewHolder();

        holder.userNameText = (TextView) row.findViewById(R.id.userNameText);
        holder.userAddressText = (TextView) row.findViewById(R.id.userAddressText);
        holder.infoButton = (ImageView) row.findViewById(R.id.infoButton);
        holder.shareButton = (ImageView) row.findViewById(R.id.shareButton);
        holder.deleteButton = (ImageView) row.findViewById(R.id.deleteButton);
        holder.moreButton = (ImageView) row.findViewById(R.id.moreButton);
        holder.moreAnimator = (ViewAnimator) row.findViewById(R.id.moreAnimator);



        row.setTag(holder);

    }else {

        holder = (ViewHolder) row.getTag();


    }


    holder.userItem = getItem(position);

    holder.userNameText.setText(holder.userItem.getUserName());
    holder.userAddressText.setText(holder.userItem.getUserAddress());

    final ViewHolder finalHolder = holder;
    holder.moreButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            finalHolder.moreAnimator.showNext();


        }
    });

    holder.deleteButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

          //Do Something

        }
    });
    holder.shareButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

          //Do Something

        }
    });
    holder.infoButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

          //Do Something
        }
    });



    return row;

}

public class ViewHolder {
    UserItem userItem;
    TextView userNameText;
    TextView userAddressText;
    ImageView infoButton;
    ImageView deleteButton;
    ImageView shareButton;
    ImageView moreButton;
    ViewAnimator moreAnimator;



}

}

【问题讨论】:

  • 你的意思是你有两种类型的列表项...?

标签: android listview android-listview


【解决方案1】:

使你的位置变量最终。

@Override 
public View getView(final int position, View convertView, ViewGroup parent) {
......
}

【讨论】:

  • 谢谢,但这并不能解决问题。
【解决方案2】:

这是因为行回收视图以提高效率,因此一个常见问题是定义执行操作时会发生什么并假设起点始终相同(事实并非如此)。

因此,在您的情况下,一旦您单击视图并调用 finalHolder.moreAnimator.showNext();,当该行被重用时也会调用它。

您可以做的就是为所有行设置起点,我不知道 ViewAnimator,但在 getView() 中的 finalHolder.moreAnimator.showPrevious(); 行中。

【讨论】:

  • 我不知道如何实现这个。 finalHolder.moreAnimator 在 getView() 中不可见
  • 是的,您可以在 getView() 中使用 holder.moreAnimator,例如在设置 userName 和 userAddress 之后。尝试添加如下内容:
    if (holder.moreAnimator.getDisplayedChild() &gt; 0) { holder.moreAnimator.showPrevious(); }
【解决方案3】:

试试这个:

 static class ViewHolder {

    UserItem userItem;
    TextView userNameText;
    TextView userAddressText;
    ImageView infoButton;
    ImageView deleteButton;
    ImageView shareButton;
    ImageView moreButton;
    ViewAnimator moreAnimator;

    public ViewHolder(View row) {


        userNameText = (TextView) row.findViewById(R.id.userNameText);
        userAddressText = (TextView) row.findViewById(R.id.userAddressText);
        infoButton = (ImageView) row.findViewById(R.id.infoButton);
        shareButton = (ImageView) row.findViewById(R.id.shareButton);
        deleteButton = (ImageView) row.findViewById(R.id.deleteButton);
        moreButton = (ImageView) row.findViewById(R.id.moreButton);
        moreAnimator = (ViewAnimator) row.findViewById(R.id.moreAnimator);
    }
}

在getView中

  @Override
public View getView(final int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub

    LayoutInflater inflater = (LayoutInflater) mContext
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    if (convertView == null) {

        convertView = inflater.inflate(layoutResource, parent,
                false);
    }

    ViewHolder holder = new ViewHolder(convertView);

    return convertView;
}

【讨论】:

  • 感谢您的回答,但它也不起作用。它引入了很多错误。我试图理解并修复它们,但在某些时候我迷路了。
猜你喜欢
  • 2014-09-25
  • 1970-01-01
  • 2019-10-20
  • 1970-01-01
  • 1970-01-01
  • 2023-02-19
  • 2014-12-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多