将动态文本视图添加到 RecyclerView ViewHolder 会弄乱视图
Adding dynamically textviews to RecyclerView ViewHolder mess up the views
我试图在我的视图持有者中实现动态文本视图,在第一次滚动时一切顺利,卡片等每个属性都是如此,但是如果我再次向上滚动文本视图开始弹出它们的位置不应该。
我的自定义适配器:
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
public interface OnItemClickListener {
void onItemClick(MyProduct product);
}
int counter = 0;
private OnItemClickListener listener;
private Context context;
List<MyProduct> myProducts;
public CustomAdapter(OnItemClickListener listener, List<MyProduct> myProducts, Context context)
{
super();
this.listener = listener;
this.myProducts = myProducts;
this.context = context;
}
@Override
public CustomAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.product_list, parent, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
@Override
public void onBindViewHolder(CustomAdapter.ViewHolder holder, int position) {
if( myProducts != null) {
holder.bind(myProducts.get(position), listener);
counter++;
}
}
@Override
public int getItemCount() {
return myProducts.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
//Views
public ImageView imageView;
public TextView textViewProductTitle;
public TextView textViewProductDescription;
public TextView textViewProductSerialNumber;
public TextView textViewProductPrice;
List<TextView> textViews;
ViewGroup viewGroup;
//Initializing Views
public ViewHolder(View itemView) {
super(itemView);
viewGroup = (ViewGroup)itemView.findViewById(R.id.linearCatalog);
textViews = new LinkedList<>();
imageView = (ImageView) itemView.findViewById(R.id.thumbnail);
textViewProductTitle = (TextView) itemView.findViewById(R.id.textViewProductTitle);
textViewProductDescription = (TextView) itemView.findViewById(R.id.textViewProductDescription);
textViewProductSerialNumber = (TextView) itemView.findViewById(R.id.textViewProductSerialNumber);
textViewProductPrice = (TextView) itemView.findViewById(R.id.textViewProductPrice);
}
public void bind(final MyProduct item, final OnItemClickListener listener) {
Glide.with(context).load(item.getProductImage())
/*.asBitmap().format(DecodeFormat.PREFER_ARGB_8888).*/
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);
textViewProductTitle.setText(item.getProductTitle());
textViewProductDescription.setText(item.getProductDescription());
textViewProductSerialNumber.setText(item.getProductSn());
textViewProductPrice.setText(item.getProductPrice());
if(counter< myProducts.size())
{
for (int i = 0; i < item.getBranchCounter(); i++) {
TextView textView = new TextView(context);
textView.setText(item.getAddressList().get(i));
textViews.add(textView);
viewGroup.addView(textView);
}
}
itemView.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
listener.onItemClick(item);
}
});
}
}
任何建议都会有帮助,ty!
将视图动态添加到回收器视图中是个坏主意。回收器视图的要点是它在多个项目上回收相同的视图结构。因此,当它回收时,您突然将该视图添加到不需要它的新项目中。没有动态视图几乎是拥有回收站视图的先决条件。
更好的方法是使用可见性。将文本视图放在所有视图中,但让它消失。在您的绑定中,您可以将每个项目的文本视图的可见性设置为 GONE 或 VISIBLE。这将使您获得想要的效果。
另一种方法是在有和没有额外视图的情况下使用不同的视图类型,但这往往更复杂。
我完全同意@Gabe Sechan。但即使您有兴趣动态添加 textView。然后你可以在适配器 class 的顶部声明一个整数,比如
int repeat=0;
现在使用变量来计算您添加的每个文本视图。还要检查它是否超过了数组的大小。
if (repeat <= yourArray.size()) {
for (int i = 0; i < yourArray.size(); i++) {
repeat++;
TextView valueTV = new TextView(getApplicationContext());
valueTV.setText(yourArray[i]);
valueTV.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
linearlayout.addView(valueTV);
}
}
这将限制文本视图的重复。
添加线性布局,在线性布局中添加动态文本视图,然后在循环上方添加以下代码,
if (ll_layout.getChildCount() > 0)
{
ll_layout.removeAllViews();
}
我们通过添加此代码解决了问题
我试图在我的视图持有者中实现动态文本视图,在第一次滚动时一切顺利,卡片等每个属性都是如此,但是如果我再次向上滚动文本视图开始弹出它们的位置不应该。
我的自定义适配器:
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
public interface OnItemClickListener {
void onItemClick(MyProduct product);
}
int counter = 0;
private OnItemClickListener listener;
private Context context;
List<MyProduct> myProducts;
public CustomAdapter(OnItemClickListener listener, List<MyProduct> myProducts, Context context)
{
super();
this.listener = listener;
this.myProducts = myProducts;
this.context = context;
}
@Override
public CustomAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.product_list, parent, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
@Override
public void onBindViewHolder(CustomAdapter.ViewHolder holder, int position) {
if( myProducts != null) {
holder.bind(myProducts.get(position), listener);
counter++;
}
}
@Override
public int getItemCount() {
return myProducts.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
//Views
public ImageView imageView;
public TextView textViewProductTitle;
public TextView textViewProductDescription;
public TextView textViewProductSerialNumber;
public TextView textViewProductPrice;
List<TextView> textViews;
ViewGroup viewGroup;
//Initializing Views
public ViewHolder(View itemView) {
super(itemView);
viewGroup = (ViewGroup)itemView.findViewById(R.id.linearCatalog);
textViews = new LinkedList<>();
imageView = (ImageView) itemView.findViewById(R.id.thumbnail);
textViewProductTitle = (TextView) itemView.findViewById(R.id.textViewProductTitle);
textViewProductDescription = (TextView) itemView.findViewById(R.id.textViewProductDescription);
textViewProductSerialNumber = (TextView) itemView.findViewById(R.id.textViewProductSerialNumber);
textViewProductPrice = (TextView) itemView.findViewById(R.id.textViewProductPrice);
}
public void bind(final MyProduct item, final OnItemClickListener listener) {
Glide.with(context).load(item.getProductImage())
/*.asBitmap().format(DecodeFormat.PREFER_ARGB_8888).*/
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);
textViewProductTitle.setText(item.getProductTitle());
textViewProductDescription.setText(item.getProductDescription());
textViewProductSerialNumber.setText(item.getProductSn());
textViewProductPrice.setText(item.getProductPrice());
if(counter< myProducts.size())
{
for (int i = 0; i < item.getBranchCounter(); i++) {
TextView textView = new TextView(context);
textView.setText(item.getAddressList().get(i));
textViews.add(textView);
viewGroup.addView(textView);
}
}
itemView.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
listener.onItemClick(item);
}
});
}
}
任何建议都会有帮助,ty!
将视图动态添加到回收器视图中是个坏主意。回收器视图的要点是它在多个项目上回收相同的视图结构。因此,当它回收时,您突然将该视图添加到不需要它的新项目中。没有动态视图几乎是拥有回收站视图的先决条件。
更好的方法是使用可见性。将文本视图放在所有视图中,但让它消失。在您的绑定中,您可以将每个项目的文本视图的可见性设置为 GONE 或 VISIBLE。这将使您获得想要的效果。
另一种方法是在有和没有额外视图的情况下使用不同的视图类型,但这往往更复杂。
我完全同意@Gabe Sechan。但即使您有兴趣动态添加 textView。然后你可以在适配器 class 的顶部声明一个整数,比如
int repeat=0;
现在使用变量来计算您添加的每个文本视图。还要检查它是否超过了数组的大小。
if (repeat <= yourArray.size()) {
for (int i = 0; i < yourArray.size(); i++) {
repeat++;
TextView valueTV = new TextView(getApplicationContext());
valueTV.setText(yourArray[i]);
valueTV.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
linearlayout.addView(valueTV);
}
}
这将限制文本视图的重复。
添加线性布局,在线性布局中添加动态文本视图,然后在循环上方添加以下代码,
if (ll_layout.getChildCount() > 0)
{
ll_layout.removeAllViews();
}
我们通过添加此代码解决了问题