RecyclerView行内的视图不可访问,始终返回空指针异常

时间:2018-08-04 14:14:50

标签: android android-layout android-recyclerview recycler-adapter

我在ViewHolder中分配了视图,但是当尝试访问 OnBindViewHolder 中的 Button 或尝试在 OnCreateViewHolder OnClickListerner 时>,应用程序崩溃并说“试图在空对象引用上调用虚拟方法” ...但是另一方面,当尝试在TextView上设置setText时,它会起作用

适配器类

public class DownloadManagerAdapter extends RecyclerView.Adapter<DownloadManagerAdapter.ViewHolder> {

    static String TAG = "rrDebug";

    private void AskForDelete(final ViewHolder viewHolder) {
        new AlertDialog.Builder(MyApplication.getInstance().getContext())
                //set message, title, and icon
                .setTitle("Delete video")
                .setMessage("Are you sure want to proceed ?")
                .setIcon(R.drawable.ic_delete)

                .setPositiveButton("Delete", new DialogInterface.OnClickListener() {

                    public void onClick(DialogInterface dialog, int whichButton) {
                        new File(DownloadManagerActivity.DownloadManager.getImpl().get(viewHolder.position).getPath()).delete();
                        viewHolder.updateNotDownloaded(FileDownloadStatus.INVALID_STATUS, 0, 0);
                        dialog.dismiss();
                    }

                })

                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {

                        dialog.dismiss();

                    }
                })
                .create();
    }

    private FileDownloadListener downloadItemListener = new FileDownloadSampleListener() {

        private ViewHolder checkCurrentHolder(final BaseDownloadTask task) {
            final ViewHolder tag = (ViewHolder) task.getTag();
            if (tag.id != task.getId()) {
                return null;
            }

            return tag;
        }

        @Override
        protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) {
            super.pending(task, soFarBytes, totalBytes);
            final ViewHolder tag = checkCurrentHolder(task);
            if (tag == null) {
                return;
            }

            tag.updateDownloading(FileDownloadStatus.pending, soFarBytes
                    , totalBytes);
            tag.downloadItemStatus.setText(R.string.dlmng_status_pending);
        }

        @Override
        protected void started(BaseDownloadTask task) {
            super.started(task);
            final ViewHolder tag = checkCurrentHolder(task);
            if (tag == null) {
                return;
            }

            tag.downloadItemStatus.setText(R.string.dlmng_status_started);
        }

        @Override
        protected void connected(BaseDownloadTask task, String etag, boolean isContinue, int soFarBytes, int totalBytes) {
            super.connected(task, etag, isContinue, soFarBytes, totalBytes);
            final ViewHolder tag = checkCurrentHolder(task);
            if (tag == null) {
                return;
            }

            tag.updateDownloading(FileDownloadStatus.connected, soFarBytes
                    , totalBytes);
            tag.downloadItemStatus.setText(R.string.dlmng_status_connected);
        }

        @Override
        protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
            super.progress(task, soFarBytes, totalBytes);
            final ViewHolder tag = checkCurrentHolder(task);
            if (tag == null) {
                return;
            }

            tag.updateDownloading(FileDownloadStatus.progress, soFarBytes
                    , totalBytes);
        }

        @Override
        protected void error(BaseDownloadTask task, Throwable e) {
            super.error(task, e);
            final ViewHolder tag = checkCurrentHolder(task);
            if (tag == null) {
                return;
            }

            tag.updateNotDownloaded(FileDownloadStatus.error, task.getLargeFileSoFarBytes()
                    , task.getLargeFileTotalBytes());
            DownloadManagerActivity.DownloadManager.getImpl().removeTaskForViewHolder(task.getId());
        }

        @Override
        protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) {
            super.paused(task, soFarBytes, totalBytes);
            final ViewHolder tag = checkCurrentHolder(task);
            if (tag == null) {
                return;
            }

            tag.updateNotDownloaded(FileDownloadStatus.paused, soFarBytes, totalBytes);
            tag.downloadItemStatus.setText(R.string.dlmng_status_paused);
            DownloadManagerActivity.DownloadManager.getImpl().removeTaskForViewHolder(task.getId());
        }

        @Override
        protected void completed(BaseDownloadTask task) {
            super.completed(task);
            final ViewHolder tag = checkCurrentHolder(task);
            if (tag == null) {
                return;
            }

            tag.updateDownloaded();
            DownloadManagerActivity.DownloadManager.getImpl().removeTaskForViewHolder(task.getId());
        }
    };

    private View.OnClickListener fancyButtonClickListeners = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (v.getTag() == null) {
                return;
            }

            ViewHolder holder = (ViewHolder) v.getTag();

            switch (v.getId()){
                case R.id.dlmng_item_download:
                    // to start
                    final DownloadManagerActivity.DownloadManagerModel model = DownloadManagerActivity.DownloadManager.getImpl().get(holder.position);
                    final BaseDownloadTask task = FileDownloader.getImpl().create(model.getUrl())
                            .setPath(model.getPath())
                            .setCallbackProgressTimes(100)
                            .setListener(downloadItemListener);

                    DownloadManagerActivity.DownloadManager.getImpl()
                            .addTaskForViewHolder(task);

                    DownloadManagerActivity.DownloadManager.getImpl()
                            .updateViewHolder(holder.id, holder);

                    task.start();
                    break;
                case R.id.dlmng_item_pause:
                    // to pause
                    FileDownloader.getImpl().pause(holder.id);
                    break;
                case R.id.dlmng_item_view:
                    Log.i(TAG, "No Player To Play File");
                    break;
                case R.id.dlmng_item_delete:
                    // to delete
                    AskForDelete(holder);
                    //new File(DownloadManagerActivity.DownloadManager.getImpl().get(holder.position).getPath()).delete();
                    //holder.updateNotDownloaded(FileDownloadStatus.INVALID_STATUS, 0, 0);
                    break;
            }

        }
    };

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.cell_download_manager, parent, false);
        ViewHolder viewHolder = new ViewHolder(v);

        // set onClickListener on FancyButtons
        Log.d(TAG, "setOnClickListener on FancyButtons");
        viewHolder.downloadItemDownloadBtn.setOnClickListener(fancyButtonClickListeners);
        viewHolder.downloadItemPauseBtn.setOnClickListener(fancyButtonClickListeners);
        viewHolder.downloadItemPlayBtn.setOnClickListener(fancyButtonClickListeners);
        viewHolder.downloadItemDeleteBtn.setOnClickListener(fancyButtonClickListeners);

        return viewHolder;
    }

    @Override
    public void onBindViewHolder(final ViewHolder viewHolder, int position) {
        final DownloadManagerActivity.DownloadManagerModel model = DownloadManagerActivity.DownloadManager.getImpl().get(position);

        viewHolder.update(model.getId(), position);
        viewHolder.downloadItemName.setText(model.getName());

        DownloadManagerActivity.DownloadManager.getImpl()
                .updateViewHolder(viewHolder.id, viewHolder);


        if (DownloadManagerActivity.DownloadManager.getImpl().isReady()) {
            final int status = DownloadManagerActivity.DownloadManager.getImpl().getStatus(model.getId(), model.getPath());
            if (status == FileDownloadStatus.pending || status == FileDownloadStatus.started ||
                    status == FileDownloadStatus.connected) {
                // start task, but file not created yet
                viewHolder.updateDownloading(status, DownloadManagerActivity.DownloadManager.getImpl().getSoFar(model.getId())
                        , DownloadManagerActivity.DownloadManager.getImpl().getTotal(model.getId()));
            } else if (!new File(model.getPath()).exists() &&
                    !new File(FileDownloadUtils.getTempPath(model.getPath())).exists()) {
                // not exist file
                viewHolder.updateNotDownloaded(status, 0, 0);
            } else if (DownloadManagerActivity.DownloadManager.getImpl().isDownloaded(status)) {
                // already downloaded and exist
                viewHolder.updateDownloaded();
            } else if (status == FileDownloadStatus.progress) {
                // downloading
                viewHolder.updateDownloading(status, DownloadManagerActivity.DownloadManager.getImpl().getSoFar(model.getId())
                        , DownloadManagerActivity.DownloadManager.getImpl().getTotal(model.getId()));
            } else {
                // not start
                viewHolder.updateNotDownloaded(status, DownloadManagerActivity.DownloadManager.getImpl().getSoFar(model.getId())
                        , DownloadManagerActivity.DownloadManager.getImpl().getTotal(model.getId()));
            }
        } else {
            viewHolder.downloadItemStatus.setText(R.string.dlmng_status_loading);
        }
    }

    @Override
    public int getItemCount() {
        return DownloadManagerActivity.DownloadManager.getImpl().getTaskCounts();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {

        private TextView downloadItemName;
        private TextView downloadItemStatus;
        private TextView downloadItemSize;
        private TextView downloadItemSpeed;
        private ProgressBar downloadItemProgressBar;
        private ImageButton downloadItemPlayBtn;
        private ImageButton downloadItemDownloadBtn;
        private ImageButton downloadItemPauseBtn;
        private ImageButton downloadItemDeleteBtn;

        public ViewHolder(View itemView) {
            super(itemView);
            downloadItemName = (TextView) itemView.findViewById(R.id.dlmng_download_Name);
            downloadItemStatus = (TextView) itemView.findViewById(R.id.dlmng_download_status);
            downloadItemSize = (TextView) itemView.findViewById(R.id.dlmng_download_size);
            downloadItemSpeed = (TextView) itemView.findViewById(R.id.dlmng_download_speed);
            downloadItemProgressBar = (ProgressBar) itemView.findViewById(R.id.dlmng_progress_bar);
            downloadItemPlayBtn = (ImageButton) itemView.findViewById(R.id.dlmng_item_view);
            downloadItemPlayBtn = (ImageButton) itemView.findViewById(R.id.dlmng_item_download);
            downloadItemPauseBtn = (ImageButton) itemView.findViewById(R.id.dlmng_item_pause);
            downloadItemDeleteBtn = (ImageButton) itemView.findViewById(R.id.dlmng_item_delete);
        }

        /**
         * viewHolder position
         */
        private int position;
        /**
         * download id
         */
        private int id;

        public void update(final int id, final int position) {
            this.id = id;
            this.position = position;
        }

        public void updateDownloaded() {
            downloadItemProgressBar.setMax(1);
            downloadItemProgressBar.setProgress(1);

            downloadItemStatus.setText(R.string.dlmng_status_completed);
            // Play Button Visible
            Log.d(TAG, "play button visible as item downloaded");
            downloadItemDownloadBtn.setVisibility(View.GONE);
            downloadItemPauseBtn.setVisibility(View.GONE);
            downloadItemPlayBtn.setVisibility(View.VISIBLE);
        }

        public void updateNotDownloaded(final int status, final long sofar, final long total) {
            if (sofar > 0 && total > 0) {
                final float percent = sofar
                        / (float) total;
                downloadItemProgressBar.setMax(100);
                downloadItemProgressBar.setProgress((int) (percent * 100));
            } else {
                downloadItemProgressBar.setMax(1);
                downloadItemProgressBar.setProgress(0);
            }

            switch (status) {
                case FileDownloadStatus.error:
                    downloadItemStatus.setText(R.string.dlmng_status_error);
                    break;
                case FileDownloadStatus.paused:
                    downloadItemStatus.setText(R.string.dlmng_status_paused);
                    break;
                default:
                    downloadItemStatus.setText(R.string.dlmng_status_not_downloaded);
                    break;
            }

            // Play Button Visible
            Log.d(TAG, "download button visible as item not downloaded");
            downloadItemDownloadBtn.setVisibility(View.VISIBLE);;
            downloadItemPauseBtn.setVisibility(View.GONE);
            downloadItemPlayBtn.setVisibility(View.GONE);
        }

        public void updateDownloading(final int status, final long sofar, final long total) {
            final float percent = sofar
                    / (float) total;
            downloadItemProgressBar.setMax(100);
            downloadItemProgressBar.setProgress((int) (percent * 100));

            switch (status) {
                case FileDownloadStatus.pending:
                    downloadItemStatus.setText(R.string.dlmng_status_pending);
                    break;
                case FileDownloadStatus.started:
                    downloadItemStatus.setText(R.string.dlmng_status_started);
                    break;
                case FileDownloadStatus.connected:
                    downloadItemStatus.setText(R.string.dlmng_status_connected);
                    break;
                case FileDownloadStatus.progress:
                    downloadItemStatus.setText(R.string.dlmng_status_progress);
                    break;
                default:
                    downloadItemStatus.setText(MyApplication.getInstance().getContext().getString(
                            R.string.dlmng_status_downloading, status));
                    break;
            }

            // Pause Button Visible
            Log.d(TAG, "pause button visible as item is currently downloading");
            downloadItemDownloadBtn.setVisibility(View.GONE);
            downloadItemPauseBtn.setVisibility(View.VISIBLE);
            downloadItemPlayBtn.setVisibility(View.GONE);
        }

    } }

cell_download_manager.xml

  

  

<LinearLayout
    ...
    android:background="@drawable/cell_download_manager"
    ... >

    <LinearLayout
        ... >

        <TextView
            android:id="@+id/dlmng_download_Name"
            ... />

        <TextView
            android:id="@+id/dlmng_download_status"
            ... />

        <LinearLayout
            ... >

            <TextView
                android:id="@+id/dlmng_download_size"
                ... />

            <TextView
                android:id="@+id/dlmng_download_speed"
                ... />

        </LinearLayout>

        <ProgressBar
            android:id="@+id/dlmng_progress_bar"
            ... />

    </LinearLayout>

    <ImageButton
        android:id="@+id/dlmng_item_download"
        ... />

    <ImageButton
        android:id="@+id/dlmng_item_pause"
        ... />

    <ImageButton
        android:id="@+id/dlmng_item_view"
       ... />

    <ImageButton
        android:id="@+id/dlmng_item_delete"
        ... />

</LinearLayout>
     

更新pastebin中的第1部分目录 https://pastebin.com/D4wLVAMT

更新第2部分-> DownloadManagerActivity.class https://pastebin.com/i3bZDcB3


  

对不起,对于PASTEBIN,但问题长度有限制


2 个答案:

答案 0 :(得分:0)

问题直截了当

您正在onCreateViewHolder内设置fancyButtonClickListeners

  1. onClickMethod中没有单击的项目引用

  2. 您没有与单击的项目相对应的数据

请将clickListener操作移至onBindViewHolder。这将解决问题。最好使用新的OnClickListener(){}代替fancyButtonClickListeners变量

答案 1 :(得分:0)

最后我得到了一个包含以下代码的解决方案.....分别分配了clickListener,然后在onBindViewHolder中使用它们

这就是我所做的

UserModule