ListView在滚动超出屏幕可见部分时显示重复项

时间:2015-12-30 11:05:55

标签: android listview android-listview

我的问题真的很疯狂。我有一个ListView和一个自定义适配器。现在在自定义适配器中,我在ViewAnimator中有两组项目,第一组只包含一个按钮(三点"更多"按钮),而第二组包含" info" ,"删除"和"分享"纽扣。我把它们称为按钮,但它们实际上是可点击的ImageViews。 "更多"按钮是默认的visisbe项目。单击“更多”按钮时,视图动画师将显示第二个组。

现在发生的疯狂事情是,虽然第二组在特定列表项上可见,但如果向下滚动列表超出为该列表项显示第二组时可见的部分,则会显示一些随机列表项自动显示第二组。(而不是等待点击更多按钮) 请注意,这仅影响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;



}

}

3 个答案:

答案 0 :(得分:0)

让你的职位变量最终。

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

答案 1 :(得分:0)

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

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

你可以做些什么来避免它是设置所有行的起点,我不知道ViewAnimator但是getView()里面的finalHolder.moreAnimator.showPrevious();行。

答案 2 :(得分:0)

试试这个:

 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);
    }
}
中的

  @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;
}