为什么 GridView 似乎混淆了不同的单元格?

Why is GridView seeming to mix up different cells?

我的 GridView 由具有下载按钮的视图组成。当您点击按钮并显示进度条时,该按钮会隐藏。进度条由按下下载按钮时启动的服务更新。

我遇到的问题是,如果我开始下载特定元素然后向下滚动,我会注意到进度条在不应下载的单元格中可见。我认为这可能是由 GridView 回收单元引起的,但我不完全确定。我已经 post 编辑了下面的一些代码。如果需要,我可以 post 更多。

getView - 在 GridView 适配器中

    public View getView(final int position, View convertView, ViewGroup parent) {
            final RelativeLayout card;
            if (convertView == null) {
                card = (RelativeLayout) getLayoutInflater().inflate(R.layout.book_cover, null);
            } else {
                card = (RelativeLayout) convertView;
            }
            TextView bookName = (TextView) card.findViewById(R.id.textView_bookName);
            TextView authorName = (TextView) card.findViewById(R.id.textView_bookAuthor);
            final MNBook currentBook = getItem(position);
                bookName.setText((String) currentBook.getTitle());
            authorName.setText((String) currentBook.getAuthor());
            final Button downloadBookButton = (Button) card.findViewById(R.id.button_download_book);
            final Button readBookButton = (Button) card.findViewById(R.id.button_read_book);
            final ProgressBar progressBar = (ProgressBar) card.findViewById(R.id.progressbar_book_download);
            readBookButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent();
                    intent.setAction(Intent.ACTION_VIEW);
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
                        intent.setDataAndType(Uri.fromFile(new File(getExternalFilesDir(null),
                                        currentBook.getFileName())),
                                "application/pdf");
                    }
                    startActivity(intent);
                }
            });
            downloadBookButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    downloadFile(currentBook, progressBar,
                            downloadBookButton, readBookButton);
                }
            });
            if (currentBook.isBooleanDownloaded()) {
                downloadBookButton.setVisibility(View.GONE);
                readBookButton.setVisibility(View.VISIBLE);
                progressBar.setVisibility(View.GONE);
            }

//                ImageView bgImage = (ImageView) card.findViewById(R.id.myImageView);
            Resources resources = getApplicationContext().getResources();
//                final int resourceId = resources.getIdentifier(mCategoryImages[position], "drawable",
//                        getApplicationContext().getPackageName());
//                bgImage.setImageResource(resourceId);
            return card;
        }

下载文件方法

private void downloadFile(MNBook book, final ProgressBar progressBar,
                              final Button downloadButton, final Button readButton) {
        final MNBook localBook = book;
        String fileName = book.getFileName();
        String url = book.getURL();
        Intent intent = new Intent(this, DownloadService.class);
        intent.putExtra("url", url);
        intent.putExtra("file_name", fileName);
        intent.putExtra("receiver", new ResultReceiver(new Handler()) {
            @Override
            protected void onReceiveResult(int resultCode, Bundle resultData) {
                super.onReceiveResult(resultCode, resultData);
                if (resultCode == DownloadService.UPDATE_PROGRESS) {
                    int progress = resultData.getInt("progress");
//                    mDetailFragment.setProgress(progress);
//                            mProgressDialog.setProgress(progress);
                    progressBar.setProgress(progress);
                    if (progress == 100) {
                        progressBar.setVisibility(View.GONE);
                        readButton.setVisibility(View.VISIBLE);
                        setDownloadedBookStatus(localBook);
                    }
                }
            }
        });
        downloadButton.setVisibility(View.GONE);
        progressBar.setVisibility(View.VISIBLE);
        startService(intent);

    }

您需要在每次 getView() 调用时更新小部件可见性,而不仅仅是其中一些。这与需要在每次 getView() 调用时在小部件上设置文本或图像没有什么不同。 AdapterViewRecyclerView 类 中的小部件,如 GridView,被回收。如果您在一次 getView() 调用中显示 ProgressBar,并且该小部件被回收并且您没有专门为回收的 getView() 调用隐藏它,则 ProgressBar 仍然可见.