RecyclerViewを使用してマークのリストを表示していますが、値の各マークはCardViewとして表示されます。ただし、下の2つのスクリーンショットに示すように、RecyclerViewを下にスクロールし、後ろにスクロールすると、カードの一部のコンテンツが失われます。赤い長方形の内容は、スクロール後に失われます。
スクロールする前;
スクロール後;
私はそれがRecyclerViewのバグであるかどうか疑問に思っており、それのためのグーグルの後、解決策を見つけることができません。
タイトルを除くすべてのビューは非表示であり、その表示はマークの値に依存します。
なぜこれが起こるのか誰にも分かりますか?
onBindHolderは、ビュータイプが変更された場合に新しいビューを使用しない限り、リサイクラーがビューを必要とするため、数回呼び出されました。そのため、子ビューで可視性を設定するたびに、他のビューの状態も変更されます。
上下にスクロールするたびに、これらのビューは誤った可視性オプションで再描画されます。
解決策:
SetValueメソッドを使用して値をチェックし、表示するように設定します。必要な場合は、別のメソッド「showView」を呼び出します。 elseステートメント(値は0またはnull)とhideViewを実装する必要があります...
void setValue(Object value, TextView textView, TableRow row, View seperator) {
if (value != null) {
if (!isEmpty(value.toString())) {
textView.setText(String.valueOf(value));
showViews(row, seperator);
}
} else
hideViews(row, seperator);
}
private void showViews(TableRow row, View seperator) {
row.setVisibility(View.VISIBLE);
seperator.setVisibility(View.VISIBLE);
}
private void hideViews(TableRow row, View seperator) {
row.setVisibility(View.INVISIBLE); // if there is a empty space change it with View.GONE
seperator.setVisibility(View.INVISIBLE);
}
この同じ問題と約24時間戦った後、私に合った解決策を見つけました。キーは_RecyclerView.ViewHolder
_クラスのsetIsRecyclable()
メソッドを使用していました。
ここに私のonBindViewHolder()
コードのセクションがあります。
_@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
final DataSource dataSource = dataSourceList.get(position);
holder.setIsRecyclable(false);
holder.name.setText(dataSource.getName());
holder.active.setChecked(dataSource.getActive());
String logoStr = dataSource.getLogo();
//Logo
/**
* Do all the logo insertion stunts here
*/
/**
* Register the changes to the Switch
*/
holder.active.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked){
dataSource.setActive(isChecked);
}
});
}
_
onBindHolderは、Recycler Viewが新しいビューでない限りビューを必要とするため、数回呼び出されました。そのため、子ビューで可視性を設定するたびに、他のビューの状態も変更されます。
上下にスクロールするたびに、これらのビューは誤った可視性オプションで再描画されるため、リサイクラビューがウィジェットの以前の状態/条件/値を認識しないため、常に両方の条件を指定します。
解決策:
Ifブロックで任意のAndroid widget.setVisibility(View.Gone)の可視性を設定した場合、elseブロックでvwith widget.setVisibility(View.Visible)の反対側の可視性を設定する必要があります上記の問題。
@Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
viewHolder.tvName.setText(ModelCategoryProducts.name.get(i));
viewHolder.tvPrice.setText("Rs."+String.format("%.2f", Float.parseFloat(ModelCategoryProducts.price.get(i))));
if(ModelCategoryProducts.special_price.get(i).equals("null")) {
viewHolder.tvSpecialPrice.setVisibility(View.GONE); // here visibility is gone and in else it's opposite visibility i set.
viewHolder.tvPrice.setTextColor(Color.parseColor("#ff0000"));
viewHolder.tvPrice.setPaintFlags(0);// here Paint flag is 0 and in else it's opposite flag that i want is set.
}else if(!ModelCategoryProducts.special_price.get(i).equals("null")){
viewHolder.tvPrice.setTextColor(Color.parseColor("#E0E0E0"));
viewHolder.tvSpecialPrice.setVisibility(View.VISIBLE);
viewHolder.tvSpecialPrice.setText("Rs." + String.format("%.2f", Float.parseFloat(ModelCategoryProducts.special_price.get(i))));
viewHolder.tvPrice.setPaintFlags(viewHolder.tvPrice.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
}
if (!ModelCategoryProducts.image_url.get(i).isEmpty()) {
Picasso.with(context)
.load(ModelCategoryProducts.image_url.get(i))
.into(viewHolder.ivProduct);
}
viewHolder.setClickListener(new ItemClickListener() {
@Override
public void onClick(View view, int position, boolean isLongClick) {
if (isLongClick) {
// Toast.makeText(context, "#" + position + " - " + ModelCategoryProducts.name.get(position) + " (Long click)", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "#" + position + " - " + ModelCategoryProducts.name.get(position), Toast.LENGTH_SHORT).show();
Intent i = new Intent(context, ProductDetail.class);
i.putExtra("position",position);
i.putExtra("flagHlvCheck", 5);
context.startActivity(i);
}
}
});
}
これは、スクロールが発生したときにビューが再利用されるためです。これを修正するには、他のセル(この例ではYUZME)で表示されているビューをリセットする必要があります。
SetValue(Object value、TextView textView、TableRow row、View seperator)内では、すべてのtxtVize *を再び非表示にします。
リサイクルビューは、3つのビューから始まります。
[0] FIZ104
[1] MAT102
[2] REK361
ビューが下にスクロールされると、[0]と[1]がリサイクルされます。トップビューにスクロールすると、[2]がFIZ104およびMAT102に含まれるデータを表示するために使用され、REK361に対して行われた変更はまだそこにあります。
Exの可視性の問題で問題に直面している場合。条件に基づいてビューの可視性を設定しているが、下にスクロールすると、ビューが更新され、リサイクラビューアイテム内のビューの可視性が変更され、条件に違反します。
これが解決策です:
1。最初に、可視性を維持したいビューにtagを割り当てます。
holder.myImageView.setTag(myTeamLists.get(position));
MyDTOClass checkWetherToShow=(MyDTOClass)holder.myImageView.getTag();
2。ここで条件を適用し、可視性を切り替えます
if (checkWetherToShow.getHasToShowImage()){
holder.myImageView.setVisibility(View.VISIBLE);
}else{
holder.myImageView.setVisibility(View.GONE);
}
ここでの答えの鍵はelseの部分を忘れないでくださいです。