代码之家  ›  专栏  ›  技术社区  ›  Cyrus the Great

当以编程方式生成recyclerview项时,重复查看视图和数据

  •  0
  • Cyrus the Great  · 技术社区  · 7 年前

    我已经创建了recyclerView和它的适配器。在适配器依赖于我传递给它的类中,行项自动生成。

    这是recycler视图项“添加行”项:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="4dp"
        android:orientation="horizontal">
    
    </LinearLayout>
    

    这是一个主要布局:

    <layout xmlns:android="http://schemas.android.com/apk/res/android">
    
        <data>
    
        </data>
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center_horizontal"
            android:background="@color/md_indigo_50">
    
            <android.support.v7.widget.RecyclerView
                android:id="@+id/recycler_view_item"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:scrollbars="vertical">
    
            </android.support.v7.widget.RecyclerView>
    
            <Button
                android:id="@+id/save_to_grid"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@+id/recycler_view_item"
                android:layout_centerHorizontal="true"
                android:layout_margin="10dp"
                android:background="@drawable/bg_round"
                android:padding="5dp"
                android:text="ذخیره"
                android:textColor="#424242"
                android:visibility="visible" />
    
        </RelativeLayout>
    
    </layout>
    

    这是适配器:

    public class RevisitGridAdapter extends RecyclerView.Adapter<RevisitGridAdapter.GridHolder> {
    
        private List<DataGridColumn> column;
    
        public RevisitGridAdapter(List<DataGridColumn> column) {
            this.column = column;
        }
    
        public int dip2pix(@NonNull Context context, int dip) {
            return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip,
                    context.getResources().getDisplayMetrics());
        }
    
        @NonNull
        @Override
        public GridHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) {
            Context context = parent.getContext();
            View root = LayoutInflater.from(context).inflate(R.layout.add_row_item, parent, false);
            return new GridHolder(root);
        }
    
        @Override
        public void onBindViewHolder(@NonNull GridHolder holder, int position) {
            holder.setPosition(holder, position);
        }
    
        @Override
        public int getItemCount() {
            return column.size();
        }
    
        @Override
        public long getItemId(int position) {
            return position;
        }
    
        @Override
        public int getItemViewType(int position) {
            return position;
        }
        class GridHolder extends RecyclerView.ViewHolder {
    
            private TextView tv;
            private LinearLayout parent;
    
            public GridHolder(@NonNull View itemView) {
                super(itemView);
                parent = (LinearLayout) itemView;
            }
    
            public void setPosition(GridHolder holder, int position) {
                if (!column.get(position).getName().startsWith("CI")) { // todo add EUM
                    EditText edt = createEditText();
                    holder.parent.addView(edt);
                    tv = createTextView();
                    tv.setText(column.get(position).getHeader());
                    holder.parent.addView(tv);
                } else {
                    holder.parent.addView(createSpinner());
                    tv = createTextView();
                    tv.setText(column.get(position).getHeader());
                    holder.parent.addView(tv);
                }
            }
    
            private Spinner createSpinner() {
                final Spinner sp = new Spinner(itemView.getContext());
                int padding = (int) itemView.getContext().getResources().getDimension(R.dimen.elevation_header);
                final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(0,
                        LinearLayout.LayoutParams.WRAP_CONTENT, 1.0f);
    //            layoutParams.setMargins(padding, padding, padding, padding);
                sp.setPadding(padding, padding, padding, padding);
                sp.setLayoutParams(layoutParams);
                return sp;
    
            }
    
    
            private TextView createTextView() {
                final LinearLayout.LayoutParams lparams = new LinearLayout.LayoutParams(dip2pix(itemView.getContext(), 120), LinearLayout.LayoutParams.WRAP_CONTENT);
                final TextView textView = new TextView(itemView.getContext());
                textView.setLayoutParams(lparams);
                return textView;
            }
    
            private EditText createEditText() {
                final LinearLayout.LayoutParams lparams = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1.0f);
                final EditText editText = new EditText(itemView.getContext());
                editText.setLayoutParams(lparams);
                ViewCompat.setBackground(editText,
                        ContextCompat.getDrawable(itemView.getContext(), com.safarayaneh.map.R.drawable.bg_round));
                editText.getBackground().setColorFilter(ContextCompat.getColor(itemView.getContext(),
                        com.safarayaneh.map.R.color.md_indigo_100), PorterDuff.Mode.SRC_ATOP);
                return editText;
            }
        }
    }
    

    当我运行应用程序时,当数据足够在一个页面中查看时,每个人都认为是可以的,但数据超过了一个页面中显示的数据,这意味着当我滚动页面时,问题就出现了!!

    问题是,当我第一次滚动到recyclerview的末尾时,一切正常,但当我滚动到recyclerview的第一页时,视图和数据重复出现,recycler视图完全混乱,如下图所示:

    enter image description here

    正如你可以在我的图片中看到的,数据和视图在图片顶部重复出现,并退出2列形状。 我犯了什么错?

    0 回复  |  直到 7 年前
        1
  •  1
  •   Ridcully    7 年前

    你正在使用 onCreateViewHolder() 和 onBindViewHolder() 错了。 onCreateViewHolder应用于创建列表项,onBindViewHolder应仅用于用数据填充已创建的视图。原因是,onCreateViewHolder创建的视图被反复用于显示不同项目的数据(因此命名为RecyclerView)。 如果需要为不同类型的数据创建不同类型的视图,则需要实现 getItemViewType() . 那么流程是这样的:

    首先,会调用getItemViewType()方法,并根据给定的位置返回所需的类型。 如果已经存在该类型的视图,并且该视图可以重用,那么将直接使用该视图和位置调用onBindViewHolder()方法。 否则,将调用onCreateViewHolder()方法并创建该类型所需的视图的新实例。之后,再次调用onBindViewHolder(),并使用创建的视图和位置。

    所以,重复我的话——onCreateViewHolder()用于创建视图,onBindViewHolder()用于将数据(即设置文本等)绑定到已创建的视图。

        2
  •  0
  •   Cyrus the Great    7 年前

    里德卡利 是正确的,我可以创建两个视图,并通过实现getItemViewType()方法对其进行更改。然而,在我的场景中,我改变了 onBindViewHolder 解决此问题的方法:

    @Override
    public void onBindViewHolder(@NonNull GridHolder holder, int position) {
        holder.parent.removeAllViews();
        DataGridColumn column = this.column.get(position);
        holder.setPosition(holder, position);
    }
    

    现在一切都很好。 holder.parent.removeAllViews(); 删除以前创建的视图。