我在我的应用程序中使用RecyclerView为用户创建一个论坛。
但是项目的位置有问题!有时项目会显示在错误的位置!有时项目播种两次,有些项目没有显示! 我在recyclerView中有不同的视图,因为我在其中使用了multiView。
这是我正在使用的recyclerView适配器:
using (_session.Use(1, 3)) // 3 is the Id of User1, who has no permissions
{
// Execute operator
switch (input.Operator.Type)
{
case "api":
executeApiResult = await ExecuteApi(input);
break;
case "procedure":
executeApiResult = await ExecuteProcedure(input);
break;
default:
return new ExecuteOperatorOutput
{
Result = new ExecuteOperatorResult { Status = false, Message = $"Wrong operator type: {input.Operator.Type}" },
WorkflowStatus = false
};
}
}
这是recyclerView的图像:
更新
我在public class chatAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final ArrayList<ChatModel> chatArray = new ArrayList<>();
private Context mContext;
FragmentForum fragmentForum;
public chatAdapter(ArrayList<ChatModel> chatArray, Context mContext, FragmentForum fragmentForum) {
this.chatArray.addAll(chatArray);
this.mContext = mContext;
this.fragmentForum = fragmentForum;
}
public static class ViewHolderNoFile extends RecyclerView.ViewHolder {
ImageView reply;
TextView qText;
TextView aText;
TextView aUserName;
TextView qUserName;
LinearLayout layoutAnswer;
public ViewHolderNoFile(View v) {
super(v);
reply = (ImageView) v.findViewById(R.id.imgReplay);
qText = (TextView) v.findViewById(R.id.txt_question);
aText = (TextView) v.findViewById(R.id.txt_answer);
aUserName = (TextView) v.findViewById(R.id.txt_a_user_name);
qUserName = (TextView) v.findViewById(R.id.txt_q_user_name);
layoutAnswer = (LinearLayout) v.findViewById(R.id.answer_box_item);
}
}
public static class ViewHolderQFile extends RecyclerView.ViewHolder {
ImageView qImage;
ImageView reply;
TextView qText;
TextView aText;
TextView aUserName;
TextView qUserName;
LinearLayout layoutAnswer;
public ViewHolderQFile(View v) {
super(v);
qImage = (ImageView) v.findViewById(R.id.img_question);
reply = (ImageView) v.findViewById(R.id.imgReplay);
qText = (TextView) v.findViewById(R.id.txt_question);
aText = (TextView) v.findViewById(R.id.txt_answer);
qUserName = (TextView) v.findViewById(R.id.txt_q_user_name);
aUserName = (TextView) v.findViewById(R.id.txt_a_user_name);
layoutAnswer = (LinearLayout) v.findViewById(R.id.answer_box_item);
}
}
public static class ViewHolderAFile extends RecyclerView.ViewHolder {
ImageView aImage;
ImageView reply;
TextView qText;
TextView aText;
TextView aUserName;
TextView qUserName;
LinearLayout layoutAnswer;
public ViewHolderAFile(View v) {
super(v);
aImage = (ImageView) v.findViewById(R.id.img_answer);
reply = (ImageView) v.findViewById(R.id.imgReplay);
qText = (TextView) v.findViewById(R.id.txt_question);
aText = (TextView) v.findViewById(R.id.txt_answer);
aUserName = (TextView) v.findViewById(R.id.txt_a_user_name);
qUserName = (TextView) v.findViewById(R.id.txt_q_user_name);
layoutAnswer = (LinearLayout) v.findViewById(R.id.answer_box_item);
}
}
public static class ViewHolderQAFile extends RecyclerView.ViewHolder {
ImageView qImage;
ImageView aImage;
ImageView reply;
TextView qText;
TextView aText;
TextView aUserName;
TextView qUserName;
LinearLayout layoutAnswer;
public ViewHolderQAFile(View v) {
super(v);
qImage = (ImageView) v.findViewById(R.id.img_question);
aImage = (ImageView) v.findViewById(R.id.img_answer);
reply = (ImageView) v.findViewById(R.id.imgReplay);
qText = (TextView) v.findViewById(R.id.txt_question);
aText = (TextView) v.findViewById(R.id.txt_answer);
aUserName = (TextView) v.findViewById(R.id.txt_a_user_name);
qUserName = (TextView) v.findViewById(R.id.txt_q_user_name);
layoutAnswer = (LinearLayout) v.findViewById(R.id.answer_box_item);
}
}
public static class ViewHolderUnsent extends RecyclerView.ViewHolder {
TextView unSentQuestion;
TextView unSentReplyText;
ImageView unSentImage;
public ViewHolderUnsent(View v) {
super(v);
unSentQuestion = (TextView) v.findViewById(R.id.txt_unSend_question);
unSentReplyText = (TextView) v.findViewById(R.id.txt_reply_unSend_question);
unSentImage = (ImageView) v.findViewById(R.id.img_unSend_question);
}
}
public static class ViewHolderReply extends RecyclerView.ViewHolder {
TextView replyPastQ;
TextView replyPastA;
TextView replyCurrentQ;
TextView replyCurrentA;
LinearLayout layoutAnswer;
ImageView imgReplay;
public ViewHolderReply(View v) {
super(v);
replyPastQ = (TextView) v.findViewById(R.id.reply_txt_past_question);
replyPastA = (TextView) v.findViewById(R.id.right_reply_txt_past_answer);
replyCurrentQ = (TextView) v.findViewById(R.id.reply_txt_current_question);
replyCurrentA = (TextView) v.findViewById(R.id.right_reply_txt_current_answer);
layoutAnswer = (LinearLayout) v.findViewById(R.id.answer_box_item);
imgReplay = (ImageView) v.findViewById(R.id.imgReplay);
}
}
@Override
public int getItemViewType(int position) {
/* *****************************Handling Inline Parents**************
* *
* 1 for item_message_no_file
* 2 for item_message_question_has_file
* 3 for item_message_answer_has_file
* 4 for item_message_q_a_has_file
* */
if (chatArray.get(position).isNoFile()) {
return 1;
} else if (chatArray.get(position).isMineUnSend()) {
//UnSend
return 2;
} else if (chatArray.get(position).isReply()) {
//Has Reply
return 3;
} else if (chatArray.get(position).isqHasFile()) {
//At this position q has file
return 4;
} else if (chatArray.get(position).isaHasFile()) {
//At this position a has file
return 5;
} else {
//At this position q and a have file
return 6;
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// Create a new View
//No File
final View item_message_no_file = LayoutInflater.from(mContext).inflate(R.layout.item_message_no_file, parent, false);
//Not Send
final View item_message_un_send = LayoutInflater.from(mContext).inflate(R.layout.item_message_un_sent, parent, false);
//Reply
final View item_message_reply = LayoutInflater.from(mContext).inflate(R.layout.item_message_reply, parent, false);
//Question has File
final View item_message_q_has_file = LayoutInflater.from(mContext).inflate(R.layout.item_message_question_has_file, parent, false);
//Answers has File
final View item_message_a_has_file = LayoutInflater.from(mContext).inflate(R.layout.item_message_answer_has_file, parent, false);
//Question and Answer have file
final View item_message_q_a_has_file = LayoutInflater.from(mContext).inflate(R.layout.item_message_q_a_has_file, parent, false);
if (viewType == 1) {
return new ViewHolderNoFile(item_message_no_file); //For item_message_no_file
} else if (viewType == 2) {
return new ViewHolderUnsent(item_message_un_send); //For item_message_un_send
} else if (viewType == 3) {
return new ViewHolderReply(item_message_reply); //For item_message_reply
} else if (viewType == 4) {
return new ViewHolderQFile(item_message_q_has_file); //For item_message_q_has_file
} else if (viewType == 5) {
return new ViewHolderAFile(item_message_a_has_file); //For item_message_a_has_file
} else {
return new ViewHolderQAFile(item_message_q_a_has_file); //For item_message_q_a_has_file
}
}
/**
* add sent message to adapter
*
* @ArrayList<ChatModel> chatArray of messages
*/
public void addItem(ChatModel newMessage) {
Log.i("CHAT_ADAPTER", "CHAT ARRAY SIZE: " + this.chatArray.size());
this.chatArray.add(newMessage);
//notifyItemInserted(this.chatArray.size()-1);
notifyDataSetChanged();
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
String question;
CourseForumModel cfm = chatArray.get(holder.getAdapterPosition()).getCourseForumModel();
switch (holder.getItemViewType()) {
case 1: //For item_message_no_file
ViewHolderNoFile vhNoFile = (ViewHolderNoFile) holder;
//Set userName of Answer
setUserName(vhNoFile.aUserName, cfm.getCourseForumAUserName());
//Set userName of Question
setUserName(vhNoFile.qUserName, cfm.getCourseForumQUserName());
//Set Question Text
setMessage(vhNoFile.qText, cfm.getCourseForumQuestion());
//Set Answer Text
setMessage(vhNoFile.aText, cfm.getCourseForumAnswer());
vhNoFile.reply.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
fragmentForum.onEvent(fragmentForum, chatArray.get(holder.getAdapterPosition()).getCourseForumModel().getCourseForumId());
}
});
// check if answer text is empty get answer layout gone
if (vhNoFile.aText.getText() == "") {
vhNoFile.layoutAnswer.setVisibility(View.INVISIBLE);
} else {
vhNoFile.layoutAnswer.setVisibility(View.VISIBLE);
}
break;
case 2: //For item_message_unSent
ViewHolderUnsent vhUnsent = (ViewHolderUnsent) holder;
SendChatModel unSendChat = chatArray.get(holder.getAdapterPosition()).getUnSendChats();
question = unSendChat.getCourseForum().getCourseForumQuestion();
int hasFile = unSendChat.getHasFile();
if (unSendChat.getCourseForum().getCourseForumQuestion() != null) {
vhUnsent.unSentQuestion.setText(question);
} else {
vhUnsent.unSentQuestion.setText("");
}
if (unSendChat.getCourseForum().getCourseForumReplyTo() > 0) {
vhUnsent.unSentReplyText.setText(unSendChat.getCourseForum().getReplyToSummary());
} else {
vhUnsent.unSentReplyText.setText("");
}
//This UnSend Message has a file
if (hasFile == 1) {
String filePath = chatArray.get(holder.getAdapterPosition()).getUnSendChats().getFilePath();
Picasso
.with(mContext)
.load(new File(filePath))
.resize(64, 64)
.into(vhUnsent.unSentImage);
} else {
vhUnsent.unSentImage.setImageResource(android.R.color.transparent);
}
break;
case 3: //For item_message_Reply
ViewHolderReply vRTReply = (ViewHolderReply) holder;
vRTReply.replyPastQ.setText(chatArray.get(holder.getAdapterPosition()).getReplayedMessage().getCourseForumQuestion());
vRTReply.replyPastA.setText(chatArray.get(holder.getAdapterPosition()).getReplayedMessage().getCourseForumAnswer());
vRTReply.replyCurrentQ.setText(chatArray.get(holder.getAdapterPosition()).getCourseForumModel().getCourseForumQuestion());
vRTReply.replyCurrentA.setText(chatArray.get(holder.getAdapterPosition()).getCourseForumModel().getCourseForumAnswer());
vRTReply.imgReplay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
fragmentForum.onEvent(fragmentForum, chatArray.get(holder.getAdapterPosition()).getCourseForumModel().getCourseForumId());
}
});
// check if answer text is empty get answer layout gone
if (chatArray.get(holder.getAdapterPosition()).getCourseForumModel().getCourseForumAnswer().equals("")) {
vRTReply.layoutAnswer.setVisibility(View.INVISIBLE);
} else {
vRTReply.layoutAnswer.setVisibility(View.VISIBLE);
}
break;
case 4: //For item_message_q_has_file
ViewHolderQFile vhQFile = (ViewHolderQFile) holder;
setUserName(vhQFile.qUserName, cfm.getCourseForumQUserName());
setUserName(vhQFile.aUserName, cfm.getCourseForumAUserName());
//Set Question Text
setMessage(vhQFile.qText, cfm.getCourseForumQuestion());
//Set Answer Text
setMessage(vhQFile.aText, cfm.getCourseForumAnswer());
loadImage(
vhQFile.qImage,
holder.getAdapterPosition(),
chatArray.get(holder.getAdapterPosition()).getCourseForumModel().getCourseForumQFile()
);
vhQFile.qImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showDialog(chatArray.get(holder.getAdapterPosition()).getCourseForumModel().getCourseForumQFile());
}
});
vhQFile.reply.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
fragmentForum.onEvent(fragmentForum, chatArray.get(holder.getAdapterPosition()).getCourseForumModel().getCourseForumId());
}
});
// check if answer text is empty get answer layout gone
if (vhQFile.aText.getText() == "") {
vhQFile.layoutAnswer.setVisibility(View.INVISIBLE);
} else {
vhQFile.layoutAnswer.setVisibility(View.VISIBLE);
}
break;
case 5: //For item_message_a_has_file
ViewHolderAFile vhAFile = (ViewHolderAFile) holder;
setUserName(vhAFile.qUserName, cfm.getCourseForumQUserName());
setUserName(vhAFile.aUserName, cfm.getCourseForumAUserName());
//Set Question Text
setMessage(vhAFile.qText, cfm.getCourseForumQuestion());
//Set Answer Text
setMessage(vhAFile.aText, cfm.getCourseForumAnswer());
loadImage(
vhAFile.aImage,
holder.getAdapterPosition(),
chatArray.get(holder.getAdapterPosition()).getCourseForumModel().getCourseForumAFile()
);
vhAFile.aImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showDialog(chatArray.get(holder.getAdapterPosition()).getCourseForumModel().getCourseForumAFile());
}
});
vhAFile.reply.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
fragmentForum.onEvent(fragmentForum, chatArray.get(holder.getAdapterPosition()).getCourseForumModel().getCourseForumId());
}
});
// check if answer text is empty get answer layout gone
if (vhAFile.aText.getText() == "") {
vhAFile.layoutAnswer.setVisibility(View.INVISIBLE);
} else {
vhAFile.layoutAnswer.setVisibility(View.VISIBLE);
}
break;
case 6: //For item_message_q_a_has_file
ViewHolderQAFile vhQAFile = (ViewHolderQAFile) holder;
setUserName(vhQAFile.qUserName, cfm.getCourseForumQUserName());
setUserName(vhQAFile.aUserName, cfm.getCourseForumAUserName());
//Set Question Text
setMessage(vhQAFile.qText, cfm.getCourseForumQuestion());
//Set Answer Text
setMessage(vhQAFile.aText, cfm.getCourseForumAnswer());
//Here Both Question and Answer have file
loadImage(
vhQAFile.qImage,
holder.getAdapterPosition(),
chatArray.get(holder.getAdapterPosition()).getCourseForumModel().getCourseForumQFile()
);
loadImage(
vhQAFile.aImage,
holder.getAdapterPosition(),
chatArray.get(holder.getAdapterPosition()).getCourseForumModel().getCourseForumAFile()
);
vhQAFile.qImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showDialog(chatArray.get(holder.getAdapterPosition()).getCourseForumModel().getCourseForumQFile());
}
});
vhQAFile.aImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showDialog(chatArray.get(holder.getAdapterPosition()).getCourseForumModel().getCourseForumAFile());
}
});
vhQAFile.reply.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
fragmentForum.onEvent(fragmentForum, chatArray.get(holder.getAdapterPosition()).getCourseForumModel().getCourseForumId());
}
});
// check if answer text is empty get answer layout gone
if (vhQAFile.aText.getText() == "") {
vhQAFile.layoutAnswer.setVisibility(View.INVISIBLE);
} else {
vhQAFile.layoutAnswer.setVisibility(View.VISIBLE);
}
break;
}
}
public void update(ArrayList<ChatModel> updatedArray) {
chatArray.clear();
chatArray.addAll(updatedArray);
notifyDataSetChanged();
}
@Override
public int getItemCount() {
return chatArray.size();
}
private void setUserName(TextView textView, String name) {
if (name.length() > 0) {
textView.setText(name);
}
}
private void setMessage(TextView textView, String text) {
if (text.length() > 0) {
textView.setText(text);
}
}
private void loadImage(final ImageView view, int position, final int fileId) {
FileModel fileModel = InternetService.getSingleFile(fileId);
String imageAddress = G.DIR_APP + fileModel.getFileName() + "." + fileModel.getFileExtension();
Picasso
.with(mContext)
.load(new File(imageAddress))
.resize(64, 64)
.into(view);
}
private void showDialog(int fileId) {
FileModel fileModel = InternetService.getSingleFile(fileId);
final Bitmap bitmap = BitmapFactory.decodeFile(G.DIR_APP + fileModel.getFileName() + "." + fileModel.getFileExtension());
final Dialog dialog = new Dialog(mContext, R.style.CustomDialog);
dialog.setContentView(R.layout.activity_image_view);
ImageView img = (ImageView) dialog.findViewById(R.id.imgShow);
img.setImageBitmap(bitmap);
Button dismissButton = (Button) dialog.findViewById(R.id.dissbtn);
dismissButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.show();
}
}
方法中获取了Log的位置Ans我从下往上滚动然后我在logCat中得到了这个项目0-1-2-3-4-5-6-12-13-14-15 -16-17!
项目7-8-9-1-11未登录!
这对我来说非常重要。 谢谢你的回答。
答案 0 :(得分:3)
RecyclerView重用现有视图以更好地执行。因此调用onBindViewHolder
并使用新的值和样式更新上一个视图。如果您不使用新值替换现有值,您仍会看到旧值。
来自RecyclerView文档。
如果用户滚动列表,Android支持库会将已准备好的视图持有者带入视图,并根据需要创建和绑定新视图。它不会立即摧毁已经滚出视线的视图持有者;如果用户向后滚动,它们将保持可用状态。但是,在创建了一定数量的视图持有者后,Android支持库不会创建新视图。相反,它通过为它们调用onBindViewHolder()来指定一个新位置,根据需要重新绑定现有的视图持有者。该方法更新了视图持有者的内容,但重新使用已为该视图持有者创建的视图。该方法不必执行昂贵的操作,如构建或膨胀新视图。
正如Amod Gokhale所说。在大多数情况下,由于缺少else的if语句,会出现错误的视图。
答案 1 :(得分:1)
对于position
中用于检索项目的所有onBindViewHolder
,您应使用holder.getAdapterPosition()
。
P.S。与您的问题无关。在onCreateViewHolder
中,您首先要对所有类型的View
进行充气,然后根据您的viewType
仅返回您需要的类型viewType
。您应首先检查View
,然后只对您需要的<script>
$(document).ready(function(){
tinymce.init({
selector : 'textarea',
//content_css : "css/tinymcecss.css",
setup : function(editor){
editor.on('init', function(event)
{
var iframeMce = $('#mce_0_ifr')[0];
rangy.init();
highlighter = rangy.createHighlighter(iframeMce);
highlighter.addClassApplier(rangy.createClassApplier("highlight", {
ignoreWhiteSpace: true,
tagNames: ["span", "a"]
}));
$('#sl-highlight').on('click', function(){
var selection = rangy.getSelection(iframeMce);
highlighter.highlightSelection('highlight', {
selection : selection,
exclusive : true
});
});
});
}
});
});
进行充气。
答案 2 :(得分:0)
最后我发现了问题。
我正在使用viewPager和3个片段。当我打开包含上述recyclerView的聊天片段并向上和向下滚动时,所有项目都将出现在错误的位置!所以我在onBindViewHolder()
中记录了项目位置,因为@Ahmadul Hoq对我说。然后我发现物品不会连续进入onBind!
最后我发现这个问题是关于fragment和viewPager的。然后我用这个方法再次设置我的recyclerView,当用户将它扫到看时。就像这样:
@Override
public void setUserVisibleHint(boolean isVisibleToUser){
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser){
//Setting up recycler view for Chats
LinearLayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
rvMain.setLayoutManager(mLayoutManager);
mAdapter = new chatAdapter(populateCourseChats(), getActivity() , this);
rvMain.setAdapter(mAdapter);
scrollRecyclerToBottom(); //Scroll recyclerView to bottom
}
}
现在一切都很好。
但我没有发现为什么会发生这种情况?! 如果你知道请告诉我。 谢谢。