Reputation: 5942
I have created recyclerView and it's adapter. In adapter depend on my class that i pass to it, row item generate automatically .
This is recycler view item `add_row_item:
<?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>
And this is a main layout :
<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>
This is Adapter:
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;
}
}
}
When i run applicatin and when data is enough to view in one single page every think is ok but data is more than is shown in one page means when i scroll the page the problem is appeared!!
The problem is when for first time i scroll to end of the recyclerview everything is ok but when i scroll to first page of the recyclerview the view's and data repeatedly repeat and recycler view is completely mess up like this image:
As you can see in my picture data and view's on top of the image repeated and exit of 2 columns shape. What is my mistake?
Upvotes: 0
Views: 241
Reputation: 5942
Ridcully is right and i could created 2 views and changed it by implementing getItemViewType() method. However in my scenario i changed onBindViewHolder
method to this:
@Override
public void onBindViewHolder(@NonNull GridHolder holder, int position) {
holder.parent.removeAllViews();
DataGridColumn column = this.column.get(position);
holder.setPosition(holder, position);
}
everything now is good. holder.parent.removeAllViews();
remove view's that created before.
Upvotes: 0
Reputation: 23665
You are using onCreateViewHolder()
and onBindViewHolder()
wrongly.
onCreateViewHolder should be used to create list items, onBindViewHolder should only be used to fill already created views with data. The reason is, that the views that are created by onCreateViewHolder are repeatedly used for showing different items' data (hence the name RecyclerView).
If you need to create different types of views for different types of data, you need to implement getItemViewType()
.
Then the flow is this:
At first, your getItemViewType() method is called and depending on given position you return the needed type. If there is already a view of that type, which can be reused, your onBindViewHolder() method is called directly with that view and the position. Otherwise, your onCreateViewHolder() method is called and creates a new instance of the view needed for that type. Afterwards, again onBindViewHolder() is called with the created view and the position.
So, to repeat myself - onCreateViewHolder() is there to create views, onBindViewHolder() is there to bind data (i.e. set text etc.) to an already created view.
Upvotes: 1