android RecyclerView notifyDataSetChange方法导致所有项目在单击特定项目时发生更改

时间:2018-09-19 15:05:53

标签: android android-recyclerview notifydatasetchanged

我的项目中有一个RecyclerView,它显示票证消息列表。 我使用分页来部分显示消息。我认为notifyDataSetChange是我应该用来添加新添加的项目的方法。

以下是我如何将新项目添加到列表中的代码:

public void makeList(List<SingleTicketModel> ticketMessages) {

    for (int i = 0; i < ticketMessages.size(); i++) {
        ticket.add(
                new TicketItemModel(
                        ticketMessages.get(i).getContent(),
                        ticketMessages.get(i).getCreatedAt(),
                        ticketMessages.get(i).getDirection(),
                        ticketMessages.get(i).getAgentName(),
                        ticketMessages.get(i).getAttachment()
                )

        );
    }
    if (ticketAdaptor == null) {
        ticketAdaptor = new TicketAdaptor(getApplicationContext(), ticket, this);
        recyclerView.setAdapter(ticketAdaptor);
        linearLayoutManager = new LinearLayoutManager(getApplicationContext());
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(linearLayoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.setVisibility(View.VISIBLE);
        recyclerView.addOnScrollListener(new EndlessRecyclerOnScrollListener(linearLayoutManager) {
            @Override
            public void onLoadMore(int current_page) {
                loadMoreProgressBar.setVisibility(View.VISIBLE);
                getTickets(loginToken, current_page,ticketID);
            }
        });
        progressBar.setVisibility(View.GONE);


    } else {

        ticketAdaptor.notifyDataSetChanged();

    }

某些邮件中可能有附件,这是我的问题:

当用户单击附件按钮时,只要下载附件,该按钮就会转换为progressBar。

但是,如果用户单击附件图标,列表中的所有附件图标都会变成progressBar,这意味着setOnClickListener方法将在所有项目上执行!

重要的是,只有在调用notifyDataSetChange方法时才会发生这种情况。

我得出的结论是,如果消息数量少并且不需要加载更多信息,则不会发生这种情况。

此外,我认为与此问题有关的另一点是

如果用户单击附件按钮(在这种情况下imageButton图像在下载完成后发生更改),则似乎该项目将通过滚动列表来重建,并且附件按钮图像将返回到第一个状态。(在将新数据添加到列表后再次输入)

这是我的适配器文件:

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

private Context context;
private Activity activity;
private List<TicketItemModel> ticket;
View view;

public TicketAdaptor(Context context, List<TicketItemModel> ticket, Activity activity){

    this.context = context;
    this.ticket = ticket;
    this.activity = activity;

}


@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {



        this.view = LayoutInflater.from(this.context).inflate(R.layout.ticket_item_in, parent, false);
    return new ViewHolder(view);
}

@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
    holder.ticketDescription.setText(ticket.get(position).getContent());
    holder.ticketDate.setText(ticket.get(position).getCreatedAt());
    switch (holder.getItemViewType()){

        case 1 :
            holder.itemView.setBackgroundResource(R.drawable.radius_background_gray);
            holder.ticketDate.setBackgroundResource(R.drawable.radius_background_light_gray);
            holder.ticketStatus.setImageResource(R.drawable.ic_attachment_black_24dp);
            break;
        case 11 :
            holder.itemView.setBackgroundResource(R.drawable.radius_background_gray);
            holder.ticketDate.setBackgroundResource(R.drawable.radius_background_light_gray);
            break;
        case 3 :
            holder.ticketStatus.setImageResource(R.drawable.ic_attachment_black_24dp);
            break;
        default: break;

    }
    holder.ticketTitle.setText(ticket.get(position).getAgentName() + " said :");

    holder.ticketStatus.setOnClickListener(new View.OnClickListener() {
        boolean counter = false;
        @Override
        public void onClick(View v) {
            if (requestPermission() == true) {
                File attachmentFile = new File((Environment.getExternalStorageDirectory()
                        + "/"
                        + context.getResources().getString(R.string.app_name)
                        + "/"
                        + context.getResources().getString(R.string.ticket_directory)
                        + "/"
                        + ticket.get(position).getCreatedAt().replaceAll("\\s|:|-","") + ".jpeg" ));

                if( !counter && !attachmentFile.exists())
                {
                    holder.attachmentProgressBar.setVisibility(View.VISIBLE);
                    holder.ticketStatus.setVisibility(View.GONE);
                    downloadAttachment(ticket.get(position)
                                    .getAttachment(),
                            ticket
                                    .get(position)
                                    .getCreatedAt()
                                    .replaceAll("\\s|:|-","") + ".jpeg",
                            holder.ticketStatus,holder.attachmentProgressBar);
                         counter = true;
                }else{
                    Intent intent = new Intent();
                    intent.setAction(Intent.ACTION_VIEW);
                    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                    File file = new File((Environment.getExternalStorageDirectory()
                            + "/"
                            + context.getResources().getString(R.string.app_name)
                            + "/"
                            + context.getResources().getString(R.string.ticket_directory)),
                             ticket.get(position).getCreatedAt().replaceAll("\\s|:|-","")
                            + ".jpeg"
                    );
                    intent.setDataAndType(FileProvider.getUriForFile(context,
                            BuildConfig.APPLICATION_ID + ".provider",
                            file),"image/*");
                    activity.startActivity(intent);
                }
            }


        }
    });

}

@Override
public int getItemViewType(int position) {
    String Direction = ticket.get(position).getDirection();
    String Attachment = ticket.get(position).getAttachment();
    if(Direction.equals("out")){
        if (Attachment != null)
            return 1;
        else return 11;
    }else if(!(Direction.equals("out"))){
        if(Attachment != null)
            return 3;
    }
    return 0;
}

@Override
public int getItemCount() {
    return ticket.size();
}


class ViewHolder extends RecyclerView.ViewHolder{

    TextView ticketTitle;
    TextView ticketDescription;
    TextView ticketDate;
    ImageView ticketStatus;
    ProgressBar attachmentProgressBar;

    public ViewHolder(View itemView) {
        super(itemView);
        this.ticketTitle = itemView.findViewById(R.id.ticket_agent);
        this.ticketDescription = itemView.findViewById(R.id.ticket_description);
        this.ticketDate = itemView.findViewById(R.id.ticket_date);
        this.ticketStatus = itemView.findViewById(R.id.ticket_attachment);
        this.attachmentProgressBar = itemView.findViewById(R.id.attachment_progressbar);
        attachmentProgressBar.setVisibility(View.GONE);
    }

}

private void downloadAttachment(String url, final String imageName, final View attachmentIcon, final View attachmentProgressBar){

    APIInterface apiInterface = APIClient.getClient().create(APIInterface.class);
    Call<ResponseBody> call = apiInterface.getAttachment(url);
    call.enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
            saveAttachment saveAttachment = new saveAttachment(imageName,attachmentIcon, attachmentProgressBar);
            saveAttachment.execute(response.body().byteStream());
        }

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {

        }
    });


}

private class saveAttachment extends AsyncTask<InputStream,Void,Boolean>{

    private  String imageName;
    private View attachmentIcon;
    private View attachmentProgressBar;

    public saveAttachment(String imageName, View attachmentIcon, View attachmentProgressBar) {
        super();
        this.imageName = imageName;
        this.attachmentIcon = attachmentIcon;
        this.attachmentProgressBar = attachmentProgressBar;
    }

    @Override
    protected Boolean doInBackground(InputStream... inputStreams) {
        InputStream inputStream = inputStreams[0];
        final File directory = new File((Environment.getExternalStorageDirectory()
                + "/"
                + context.getResources().getString(R.string.app_name)
                + "/"
                + context.getResources().getString(R.string.ticket_directory)
        ));
        if (!directory.exists())
            directory.mkdirs();
        final File myImageFile = new File(directory, imageName);
        OutputStream outputStream = null;
        try {

            outputStream = new FileOutputStream(myImageFile);
            byte [] buffer = new byte[2048];
            int read;
            while ((read = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, read);
            }
            outputStream.flush();
            outputStream.close();
        }catch (IOException e){}
        return null;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected void onPostExecute(Boolean aBoolean) {
        super.onPostExecute(aBoolean);
        attachmentProgressBar.setVisibility(View.GONE);
        ((ImageView) attachmentIcon).setImageResource(R.drawable.ic_slow_motion_video_black_24dp);
        attachmentIcon.setVisibility(View.VISIBLE);

    }
}

}

(我删除了一些与该主题无关的代码。)

1 个答案:

答案 0 :(得分:0)

我不确定,但是由于职位不匹配,这可能是个问题,因为您要向列表中添加更多内容。我建议在ViewHolder构造函数上设置OnClickListener。 onBindViewHolder方法上的position参数不应被视为静态参数(在诸如侦听器之类的匿名类中使用时)。看看情况是否好转。

此外,您可以使用notifyItemChanged来更改点击的内容,例如:

SELECT * FROM root 
WHERE (root[\"id\"] = "sample" 
    AND ARRAY_CONTAINS(root[\"innerDocuments\"], {\"type\":\"foo\"}, true))

在点击侦听器回调中。

因此,您的代码将更像这样:

notifyItemChanged(getAdapterPosition());