我的项目中有一个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);
}
}
}
(我删除了一些与该主题无关的代码。)
答案 0 :(得分:0)
我不确定,但是由于职位不匹配,这可能是个问题,因为您要向列表中添加更多内容。我建议在ViewHolder构造函数上设置OnClickListener。 onBindViewHolder方法上的position参数不应被视为静态参数(在诸如侦听器之类的匿名类中使用时)。看看情况是否好转。
此外,您可以使用notifyItemChanged来更改点击的内容,例如:
SELECT * FROM root
WHERE (root[\"id\"] = "sample"
AND ARRAY_CONTAINS(root[\"innerDocuments\"], {\"type\":\"foo\"}, true))
在点击侦听器回调中。
因此,您的代码将更像这样:
notifyItemChanged(getAdapterPosition());