我正在使用RecyclerView,我注意到一个奇怪的行为:每次onBindViewHolder()
被称为记录实际位置时,我都会放一个日志,有时位置不是从零开始的,你知道为什么吗?对我来说,这是一个问题,因为在位置0,我有不同的逻辑。
那是记录器:
2022-02-15 16:19:51.833 D/UpdateFragment: >>>ViewModel.GetAllCards()
2022-02-15 16:19:51.834 D/UpdateFragment: >>>ViewModel.GetAllTags()
2022-02-15 16:19:51.864 D/RecyclerViewAdapterUpdate: >>>Position:0
2022-02-15 16:19:52.110 D/RecyclerViewAdapterUpdate: >>>Position:1
2022-02-15 16:19:52.266 D/RecyclerViewAdapterUpdate: >>>Position:2
2022-02-15 16:19:52.331 D/RecyclerViewAdapterUpdate: >>>Position:3
2022-02-15 16:20:03.696 D/UpdateFragment: >>>ViewModel.GetAllCards()
2022-02-15 16:20:03.722 D/UpdateFragment: >>>ViewModel.GetAllCards()
2022-02-15 16:20:03.729 D/UpdateFragment: >>>ViewModel.GetAllCards()
2022-02-15 16:20:03.729 D/UpdateFragment: >>>ViewModel.GetAllCards()
2022-02-15 16:20:03.730 D/UpdateFragment: >>>ViewModel.GetAllCards()
2022-02-15 16:20:03.737 D/UpdateFragment: >>>ViewModel.GetAllCards()
2022-02-15 16:20:03.743 D/UpdateFragment: >>>ViewModel.GetAllCards()
2022-02-15 16:20:03.750 D/UpdateFragment: >>>ViewModel.GetAllCards()
2022-02-15 16:20:03.761 D/RecyclerViewAdapterUpdate: >>>Position:2
2022-02-15 16:20:03.830 D/RecyclerViewAdapterUpdate: >>>Position:3
2022-02-15 16:20:03.891 D/RecyclerViewAdapterUpdate: >>>Position:1
2022-02-15 16:20:04.042 D/RecyclerViewAdapterUpdate: >>>Position:0
好吧,我知道顺序并不总是一样的,但在我的应用程序中,当我更新数据时,我注意到两个ViewHolder的布局之间有一个神秘的交换,但在我的代码中,我从未为ViewHolder分配布局。正如您在日志中看到的,与位置相关联的布局id发生了变化。
2022-02-15 19:03:10.878 D/RecyclerViewAdapterUpdate: >>>Position[0]android.widget.LinearLayout{83f4271 G.E...... ......I. 0,0-0,0 #7f0800f5 app:id/layout_cards}
2022-02-15 19:03:11.593 D/RecyclerViewAdapterUpdate: >>>Position[1]android.widget.LinearLayout{e951d5e G.E...... ......I. 0,0-0,0 #7f0800f5 app:id/layout_cards}
2022-02-15 19:03:11.954 D/RecyclerViewAdapterUpdate: >>>Position[2]android.widget.LinearLayout{61b8127 G.E...... ......I. 0,0-0,0 #7f0800f5 app:id/layout_cards}
2022-02-15 19:03:18.326 D/RecyclerViewAdapterUpdate: >>>View android.widget.LinearLayout{61b8127 V.E...... ......I. 0,0-0,0 #7f0800f5 app:id/layout_cards}true
2022-02-15 19:03:18.953 D/RecyclerViewAdapterUpdate: >>>View androidx.constraintlayout.widget.ConstraintLayout{8510217 V.E...... ......I. 0,0-0,0 #7f08021e app:id/layout_update_card}true
2022-02-15 19:03:53.394 D/RecyclerViewAdapterUpdate: >>>Saved
2022-02-15 19:03:53.582 D/RecyclerViewAdapterUpdate: >>>Position[2]android.widget.LinearLayout{83f4271 G.E...... ......I. 0,0-0,0 #7f0800f5 app:id/layout_cards}
2022-02-15 19:03:53.729 D/RecyclerViewAdapterUpdate: >>>Position[1]android.widget.LinearLayout{e951d5e G.E...... ......I. 0,0-0,0 #7f0800f5 app:id/layout_cards}
2022-02-15 19:03:54.005 D/RecyclerViewAdapterUpdate: >>>Position[0]android.widget.LinearLayout{61b8127 V.E...... .......D 0,98-720,761 #7f0800f5 app:id/layout_cards}
2022-02-15 19:03:54.437 D/RecyclerViewAdapterUpdate: >>>Position[0]android.widget.LinearLayout{61b8127 V.E...... .......D 0,98-720,378 #7f0800f5 app:id/layout_cards}
2022-02-15 19:03:54.695 D/RecyclerViewAdapterUpdate: >>>Position[1]android.widget.LinearLayout{e951d5e G.E...... ......I. 0,0-0,0 #7f0800f5 app:id/layout_cards}
2022-02-15 19:03:54.879 D/RecyclerViewAdapterUpdate: >>>Position[2]android.widget.LinearLayout{83f4271 G.E...... ......I. 0,0-0,0 #7f0800f5 app:id/layout_cards}
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Log.d(TAG, ">>>Position["+position+"]" + holder.linearLayout);
if (position == 0) {
// All the cards
holder.numberOfItems.setText(String.valueOf(cardList.size()));
holder.tagName.setText(R.string.all_cards_tag);
holder.clearTag.setVisibility(View.GONE); // Can't delete all cards
holder.checkBox.setChecked(allCardIsChecked);
holder.checkBox.setOnClickListener(view -> {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt(Utilities.RECYCLER_CARD_POSITION, 0);
editor.putBoolean(Utilities.SHOULD_SHUFFLE, true);
if (holder.checkBox.isChecked()) {
MainActivity.recyclerTagList.clear();
editor.putStringSet(Utilities.SELECTED_TAGS, new HashSet<>());
Log.d(TAG, ">>Tags selected: " + MainActivity.recyclerTagList);
numberOfSelected = 1;
if (!allCardIsChecked) {
allCardIsChecked = true;
notifyDataSetChanged();
}
} else {
// Can't deselect all cards, at least one group chosen
holder.checkBox.setChecked(true);
Toast.makeText(context, R.string.min_one_tag, Toast.LENGTH_SHORT).show();
}
editor.commit();
});
initializeLayoutCards(cardList,null, holder, true);
} else {
// Single TAG after all cards
Tag tag = tagList.get(position - 1);
List<CardWithTags> listOfSingleTag = new ArrayList<>();
for (CardWithTags cwt: cardList) {
for (Tag t: cwt.getTagList()) {
if (t.getTag().equals(tag.getTag()))
listOfSingleTag.add(cwt);
}
}
initializeLayoutCards(listOfSingleTag, tag, holder, false);
holder.numberOfItems.setText(String.valueOf(listOfSingleTag.size()));
holder.tagName.setText(tag.getTag());
holder.clearTag.setVisibility(View.VISIBLE);
if (allCardIsChecked)
holder.checkBox.setChecked(false);
else {
holder.checkBox.setChecked(false);
for (String s: selectedTags) {
if (s.equalsIgnoreCase(tag.getTag()))
holder.checkBox.setChecked(true);
}
}
holder.checkBox.setOnClickListener(view -> {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt(Utilities.RECYCLER_CARD_POSITION, 0);
editor.putBoolean(Utilities.SHOULD_SHUFFLE, true);
if (holder.checkBox.isChecked()) {
MainActivity.recyclerTagList.add(tag);
selectedTags = sharedPreferences.getStringSet(Utilities.SELECTED_TAGS, new HashSet<>());
selectedTags.add(tag.getTag());
editor.putStringSet(Utilities.SELECTED_TAGS, selectedTags);
Log.d(TAG, ">>Tags selected: " + MainActivity.recyclerTagList);
if (allCardIsChecked) {
allCardIsChecked = false;
notifyDataSetChanged();
} else {
++numberOfSelected;
}
} else {
if (numberOfSelected == 1) {
Toast.makeText(context, R.string.min_one_tag, Toast.LENGTH_SHORT).show();
holder.checkBox.setChecked(true);
}
else {
--numberOfSelected;
MainActivity.recyclerTagList.removeIf(t -> t.getTag().equalsIgnoreCase(tag.getTag()));
selectedTags = sharedPreferences.getStringSet(Utilities.SELECTED_TAGS, new HashSet<>());
selectedTags.remove(tag.getTag());
editor.putStringSet(Utilities.SELECTED_TAGS, selectedTags);
Log.d(TAG, ">>Tags selected: " + MainActivity.recyclerTagList);
}
}
editor.commit();
});
View viewDialogTag = LayoutInflater.from(context).inflate(R.layout.dialog_modify_tag, (ViewGroup) null);
EditText tagNameEditText = viewDialogTag.findViewById(R.id.tag_name_dialog);
tagNameEditText.setText(tag.getTag());
// In this way the dialog is created only one time
AlertDialog dialogTag = getDialogUpdateTag(tag, viewDialogTag, tagNameEditText);
AlertDialog dialogDeleteTag = getDialogDeleteTag(tag);
holder.tagName.setOnLongClickListener( view -> {
// Change tag name only if closed
if (holder.linearLayout.getVisibility() == View.GONE)
dialogTag.show();
return true;
});
holder.clearTag.setOnClickListener( view -> dialogDeleteTag.show());
}
}
private void initializeLayoutCards(List<CardWithTags> cardList, Tag tag, ViewHolder holder, boolean isAllCards) {
// Or it will add already added cards
holder.linearLayout.removeAllViews();
for (CardWithTags cwt : cardList) {
Card card = cwt.getCard();
View cardView = LayoutInflater.from(context).inflate(R.layout.card_update, holder.linearLayout, false);
TextView textViewCardName = cardView.findViewById(R.id.card_name);
Button clearButton = cardView.findViewById(R.id.clear_card);
ConstraintLayout layoutCardUpdate = cardView.findViewById(R.id.layout_update_card);
EditText titleEditText = cardView.findViewById(R.id.update_title_edit_text);
EditText taboo1EditText = cardView.findViewById(R.id.update_taboo_1_edit_text);
EditText taboo2EditText = cardView.findViewById(R.id.update_taboo_2_edit_text);
EditText taboo3EditText = cardView.findViewById(R.id.update_taboo_3_edit_text);
EditText taboo4EditText = cardView.findViewById(R.id.update_taboo_4_edit_text);
EditText taboo5EditText = cardView.findViewById(R.id.update_taboo_5_edit_text);
Button saveButton = cardView.findViewById(R.id.save_button);
Button tagButton = cardView.findViewById(R.id.tag_button);
textViewCardName.setText(card.getTitle());
titleEditText.setText(card.getTitle());
taboo1EditText.setText(card.getTabooWord1());
taboo2EditText.setText(card.getTabooWord2());
taboo3EditText.setText(card.getTabooWord3());
taboo4EditText.setText(card.getTabooWord4());
taboo5EditText.setText(card.getTabooWord5());
saveButton.setOnClickListener(view -> {
Animations.doReduceIncreaseAnimation(view);
String title = titleEditText.getText().toString();
String taboo1 = taboo1EditText.getText().toString();
String taboo2 = taboo2EditText.getText().toString();
String taboo3 = taboo3EditText.getText().toString();
String taboo4 = taboo4EditText.getText().toString();
String taboo5 = taboo5EditText.getText().toString();
if (title.equalsIgnoreCase(card.getTitle()) &&
taboo1.equalsIgnoreCase(card.getTabooWord1()) &&
taboo2.equalsIgnoreCase(card.getTabooWord2()) &&
taboo3.equalsIgnoreCase(card.getTabooWord3()) &&
taboo4.equalsIgnoreCase(card.getTabooWord4()) &&
taboo5.equalsIgnoreCase(card.getTabooWord5())) {
Log.d(TAG, ">>Change something before saving card");
return;
}
Card newCard = new Card(title, taboo1, taboo2, taboo3, taboo4, taboo5);
newCard.setIdCard(card.getIdCard());
// Check if new title already exists
for (CardWithTags c: this.cardList) {
if (!c.getCard().getTitle().equalsIgnoreCase(card.getTitle()) && c.getCard().getTitle().equalsIgnoreCase(title)) {
Toast.makeText(context, R.string.title_already_exists, Toast.LENGTH_SHORT).show();
return;
}
}
cwt.setCard(newCard);
Log.d(TAG, ">>New cwt: " + cwt);
Log.d(TAG, ">>>Saved");
viewModelFragment.updateCWT(cwt);
Toast.makeText(context, R.string.card_updated, Toast.LENGTH_SHORT).show();
});
tagButton.setOnClickListener(view -> {
Animations.doReduceIncreaseAnimation(view);
});
textViewCardName.setOnClickListener(view -> {
openCloseView(layoutCardUpdate);
});
AlertDialog dialogDeleteCard;
if (!isAllCards)
dialogDeleteCard = getDialogDeleteCardOrTag(card, tag);
else
dialogDeleteCard = getDialogDeleteCard(card);
clearButton.setOnClickListener(view -> dialogDeleteCard.show());
// Set the click on both number of items and tag name
holder.tagName.setOnClickListener(view -> {
openCloseView(holder.linearLayout);
});
holder.numberOfItems.setOnClickListener(view -> {
openCloseView(holder.linearLayout);
});
holder.linearLayout.addView(cardView);
}
}
private void openCloseView(View view) {
if (view.getVisibility() == View.GONE) {
view.setVisibility(View.VISIBLE);
boolean isVisible = view.getVisibility() == View.VISIBLE? true : false;
Log.d(TAG, ">>>View " + view +isVisible);
AnimationSet animation = new AnimationSet(true);
Animation animationAlpha = new AlphaAnimation(0, 1);
animation.addAnimation(animationAlpha);
Animation animationTranslate = new TranslateAnimation(0, 0, -view.getHeight(), 0);
animation.addAnimation(animationTranslate);
Animation animationY = new ScaleAnimation(1, 1, 0, 1);
animationY.setInterpolator(new LinearInterpolator());
animation.addAnimation(animationY);
animation.setDuration(200);
view.startAnimation(animation);
} else {
AnimationSet animation = new AnimationSet(true);
Animation animationAlpha = new AlphaAnimation(1, 0);
animation.addAnimation(animationAlpha);
Animation animationTranslate = new TranslateAnimation(0, 0, 0, -view.getHeight());
animation.addAnimation(animationTranslate);
Animation animationY = new ScaleAnimation(1, 1, 1, 0);
animationY.setInterpolator(new LinearInterpolator());
animation.addAnimation(animationY);
animation.setDuration(200);
animation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
view.setVisibility(View.GONE);
boolean isVisible = view.getVisibility() == View.VISIBLE;
Log.d(TAG, ">>>View " + view +isVisible);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
view.startAnimation(animation);
}
}
只绑定屏幕上需要更新的项目。事实上,组件试图最小化onbind调用的数量,以防止额外的工作。电话没有预定订单。因此,只有在第一次加载时才能确保调用0,即使在这种情况下也不会调用(例如,如果进行反向填充并从底部开始)。如果您编写的代码假设它总是试图绑定0,那么您就误解了RecyclerView的工作原理,需要重新评估您的设计。
我正在将一个项目从Hibernate 4.2.6迁移到5.2.0。 persistence.xml文件如下所示 唯一的区别是setParameter中的0索引。 persistence.xml也非常相似
问题内容: 我正在查看Mozilla的代码,该代码向Array添加了一个过滤器方法,并且其中的一行代码使我感到困惑。 我从未见过>>>在JavaScript中使用过。 这是什么,它做什么? 问题答案: 它不仅将非数字转换为数字,还将其转换为可以表示为32位无符号整数的数字。 虽然JavaScript的数字是双精度浮点(*),位运算符(,,,和)在对32位整数运算的定义。进行按位运算会将数字转换为3
问题内容: 有谁知道为什么下面不等于0? 要么: 当我将其输入python时,它的值为1.22e-16。 问题答案: 该数字不能完全表示为浮点数。所以,不给你,它给你。 而其实类似。 那么,您如何处理呢? 您必须计算出或至少猜测出适当的绝对和/或相对误差范围,然后编写而不是: (这也意味着你要组织你的计算,使相对误差相对较大,而不是在你的情况,因为是恒定的,这是微不足道的,只是做了落后的。) Nu
准备好了吗? 准备来开始我们的旅程!如果你就是那种从不看说明书的人,我推荐你还是回头看一下简介的最后一节。那里面讲了这个教学中你需要用到的工具及基本用法。我们首先要做的就是进入 ghc 的交互模式,接着就可以写几个函数体验一下 Haskell 了。打开终端机,输入 ghci,你会看到下列欢迎消息: GHCi,version6.8.2:http://www.haskell.org/ghc/ :?fo
从零开始 欢迎您选择ILRuntime , 根据下面教程您可以快速的开始。 起步 在Unity2018以上版本中开始使用ILRuntime ILRuntime1.6版新增了Package Manager发布,使用Unity2018以上版本可以直接通过Package Manager安装,具体方法如下 如果你使用的是中国特别版Unity,那直接打开Package Manager即可找到ILRuntim
问题内容: 我在ColdFusion代码中碰巧遇到了这些值,但Google计算器似乎有相同的“错误”,但差不为零。 416582.2850-411476.8100-5105.475 = -2.36468622461E-011 http://www.google.com/search?hl=zh_CN&rlz=1C1GGLS_enUS340US340&q=416582.2850+-+411476.8