Android:我的 listView onClick 事件没有按预期工作(顺序混乱)

Android: My listView onClick events are not working as intended (order messes up)

我的程序应该显示应用列表及其数据使用情况。如果您单击该应用程序,它会启动一个新的 activity 页面并提供有关该应用程序的更多信息。在初始页面上一切正常,所有应用程序都显示准确的信息,但在我向下滚动后它搞砸了 - "more info" 页面显示的应用程序与我单击的应用程序不同。

我很确定问题出在没有绑定到 holder 的 onclick 事件上?但是我不知道该怎么做。应该注意的是,如果我摆脱 if(convertView == null)/else 条件,问题就解决了,但我知道这是不好的做法,因为我们不想继续重新生成以前的项目

这是我的 customAdapter 中的 getView 代码:

 public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    final DataUsageModel model;
    model = getItem(position);
    if (convertView == null) {
        holder = new ViewHolder();
        convertView = LayoutInflater.from(context).inflate(R.layout.customlayout, null);

        convertView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intentMoreInfo = new Intent(view.getContext(),MoreInfoActivity.class);
                intentMoreInfo.putExtra("wifiUsage",model.getWifiUsage());
                intentMoreInfo.putExtra("mobileUsage",model.getMobileUsage());
                intentMoreInfo.putExtra("appName",model.getName());
                intentMoreInfo.putExtra("pname",model.getPname());

                context.startActivity(intentMoreInfo);


            }
        });
        holder.nameText = (TextView) convertView.findViewById(R.id.textViewWord);
        holder.totalUsageText = (TextView) convertView.findViewById(R.id.textViewDescription);
        holder.imageView = (ImageView) convertView.findViewById(R.id.iconImageView);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }
    holder.nameText.setText(model.getName());

    long usageInMB = (model.getWifiUsage() + model.getMobileUsage())/(1024*1024);
    holder.totalUsageText.setText(String.valueOf(usageInMB) + " MB");

    holder.imageView.setImageDrawable(model.getImageRes());
    return convertView;
}

public class ViewHolder {
    TextView nameText;
    TextView totalUsageText;
    ImageView imageView;
}

这是我的新 activity 启动代码:

public class MoreInfoActivity extends AppCompatActivity {
    TextView wifiUsage;
    TextView mobileUsage;
    ImageView icon;
    TextView appName;
    Button backButton;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.more_info_layout);

    wifiUsage = findViewById(R.id.moreInfoWifi);
    mobileUsage = findViewById(R.id.moreInfoMobile);
    appName = findViewById(R.id.moreInfoAppName);
    icon = findViewById(R.id.moreInfoIcon);

    backButton = (Button)findViewById(R.id.moreInfoBack);
    backButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            finish();
        }
    });

    appName.setText(getIntent().getStringExtra("appName"));
    wifiUsage.setText("Wifi Usage: " + String.valueOf(getIntent().getLongExtra("wifiUsage",0)/(1024*1024)) + " MB");
    mobileUsage.setText("Mobile Usage: " + String.valueOf(getIntent().getLongExtra("mobileUsage",0)/(1024*1024)) + " MB");
    try {
        icon.setImageDrawable(getPackageManager().getApplicationIcon(getIntent().getStringExtra("pname")));
    }catch(PackageManager.NameNotFoundException e){
        e.printStackTrace();
    }

您应该为 getView 方法的每次迭代设置 OnClickListener,而不仅仅是在 convertView == null.

在您的情况下,当前数据位置未与每次 getView 迭代的当前视图(持有者)位置同步

此外,从适配器本身启动 activity 是一种非常糟糕的做法。 adapter的作用就是把view绑定到data上,仅此而已