代码之家  ›  专栏  ›  技术社区  ›  Shubham Agrawal

在recyclerview中为特定列表项添加处理程序

  •  0
  • Shubham Agrawal  · 技术社区  · 7 年前

    我只想在每个列表项加载程序和图像中添加一个延迟,并在recycler视图中完成进度后显示图像,添加3秒的延迟。

    这是我的 适配器

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View layoutView;
        switch (viewType) {
            case USER_HEADER:
                layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_user_header, parent, false);
                return new HeaderViewHolder(layoutView);
            default:
                layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_user_info, parent, false);
                return new AppListViewHolder(layoutView, onRecyclerItemClick);
    
        }
    }
    
    
    @Override
    public int getItemViewType(int position) {
        if (position == 0) {
            return USER_HEADER;
        }
        return USER_ITEM;
    }
    
    @Override
    public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, final int position) {
    
        if (holder.getItemViewType() == USER_HEADER) return;
    
        final AppListViewModel appListViewModel = appListViewModels.get(position - 1);
        final AppListViewHolder appListViewHolder = (AppListViewHolder) holder;
        if (!appListViewModel.isAppInstalled()) {
            appListViewHolder.textAppLink.setText(appListViewModel.getAppLink());
        } else {
            appListViewHolder.textAppLink.setText("");
        }
        appListViewHolder.textAppName.setText(appListViewModel.getAppName());
        appListViewHolder.itemView.setTag(appListViewModel);
    
        // TODO I want to add this progressbar and image after every 3 sec. Just like checking the installation after every 3 sec.
        appListViewHolder.progressBar.setVisibility(View.VISIBLE);
        appListViewHolder.imageStatus.setImageResource(appListViewModel.isAppInstalled() ? R.drawable.ic_check_green : R.drawable.cancel);
        setAdapterData(holder);
        loaderStatusListner.isLoadingComplete(true);
    
    }
    
    private void setAdapterData(RecyclerView.ViewHolder viewHolder){
        this.viewHolder = viewHolder;
    }
    public RecyclerView.ViewHolder getAdapterData(){
        return viewHolder;
    }
    
    @Override
    public int getItemCount() {
        return 1 + appListViewModels.size();
    }
    
    
    private static class HeaderViewHolder extends RecyclerView.ViewHolder {
    
        HeaderViewHolder(View itemView) {
            super(itemView);
        }
    }
    
    static class AppListViewHolder extends RecyclerView.ViewHolder {
        @BindView(R.id.image_app_status)
        public ImageView imageStatus;
        @BindView(R.id.text_app_name)
        TextView textAppName;
        @BindView(R.id.text_app_link)
        TextView textAppLink;
        @BindView(R.id.progress_bar)
        public ProgressBar progressBar;
    
    
        AppListViewHolder(View view, final OnRecyclerItemClick onRecyclerItemClick) {
            super(view);
            ButterKnife.bind(this, view);
    
            view.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    AppListViewModel commonTicketViewModel = (AppListViewModel) v.getTag();
                    onRecyclerItemClick.onItemClick(v, getAdapterPosition(), commonTicketViewModel);
                }
            });
    
        }
    }
    

    加载器应继续移动,在3秒延迟和图像更改后,其可见性将一个接一个地变为不可见。有关更多说明,请参见图 see image

    2 回复  |  直到 7 年前
        1
  •  0
  •   aminography    7 年前

    因为回收程序 RecyclerView 您不能仅在中使用处理程序来处理它 ViewHolder . 在本例中,通过滚动列表 itemView 已更改并指向新视图,通过完成处理程序的延迟,它可能会更新错误的视图。因此,您应该将更新时间作为字段保存在 AppListViewModel System.currentTimeInMillis() + (i + 1) * 3000 作为每行的更新时间。然后在view holder类中(您在其中编写 TODO )将当前时间与viewModel实例中的行的更新时间进行比较。如果时间已过,则更新视图。 最后,在你的 Fragment Activity )它初始化了 Adapter ,试着打电话 adapter.notifyDatasetChange()

    您可以使用以下类保持每秒触发一次:

    private class SchedulerHandler extends Handler {
    
        private static final long SCHEDULE_TIME = 1000;
        private static final int MSG_START = 1;
    
        private SchedulerHandler(Looper looper) {
            super(looper);
        }
    
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_START:
                    // call adapter.notifyDatasetChanged()
                    sendEmptyMessageDelayed(MSG_START, SCHEDULE_TIME);
                    break;
                default:
                    throw new IllegalArgumentException("Unknown what=" + msg.what);
            }
        }
    
        void startScheduling() {
            sendEmptyMessage(SchedulerHandler.MSG_START);
        }
    
        void stopScheduling() {
            removeMessages(SchedulerHandler.MSG_START);
        }
    
    }
    

    用法:

    SchedulerHandler schedulerHandler = new SchedulerHandler();
    schedulerHandler.startScheduling();
    

    在更新结束时:

    schedulerHandler.stopScheduling();
    
        2
  •  0
  •   Shubham Agrawal    7 年前

    handler 我的国家 progressabar image 在我的 ViewModel

    Message message = new Message();
    message.arg1 = 0;
    message.what = 0;
    handler.sendMessageDelayed(message, 2000);
    

    然后添加处理程序来处理该消息:

    private Handler handler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            int position = msg.arg1;
            appListViewModels.get(position).setProgressState("INACTIVE");
            appListViewModels.get(position).setImageState("ACTIVE");
            userListAdapter.notifyItemChanged(position + 1);
            if (position < userListAdapter.getItemCount() - 2) {
                appListViewModels.get(position + 1).setProgressState("ACTIVE");
                userListAdapter.notifyItemChanged(position + 2);
            }
    
            if (position < userListAdapter.getItemCount() - 2) {
                Message message = new Message();
                message.arg1 = position + 1;
                message.what = 0;
                handler.sendMessageDelayed(message, 2000);
            } else {
                if (totalActivatedApps == 5) {
                    buttonContinue.setEnabled(true);
    
                } else {
                    buttonContinue.setEnabled(false);
                }
            }
    
        }
    };