I'm making a ToDo list app, and while testing it, for some reason, a huge gap forms between the items whenever I try to scroll down. It always happens whenever I Drag and Drop the items, but I don't see any errors with my ItemTouchHelper adapter and callback class. It would be awesome if you can help me out.
Before:
After:
RecyclerAdapter.java
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.RecyclerVH> implements ItemTouchHelperAdapter{ private LayoutInflater layoutInflater; ArrayList<Info> data; Context context; public RecyclerAdapter(Context context) { layoutInflater = LayoutInflater.from(context); this.context = context; } public void setData(ArrayList<Info> data) { this.data = data; notifyDataSetChanged(); } @Override public RecyclerVH onCreateViewHolder(ViewGroup viewGroup, int position) { View view = layoutInflater.inflate(R.layout.custom_row, viewGroup, false); view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d("R.A onClick Owen", "onClick method triggered"); } }); RecyclerVH recyclerVH = new RecyclerVH(view); return recyclerVH; } @Override public void onBindViewHolder(RecyclerVH recyclerVH, int position) { Log.d("RecyclerView", "onBindVH called: " + position); final Info currentObject = data.get(position); // Current Info object retrieved for current RecyclerView item - USED FOR DELETE recyclerVH.listTitle.setText(currentObject.title); recyclerVH.listContent.setText(currentObject.content); /*recyclerVH.listTitle.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // Open new Activity containing note content Toast.makeText(this, "Opening: " + currentObject.title, Toast.LENGTH_LONG).show(); } });*/ } public void deleteItem(int position) { DBInfo dbInfo = new DBInfo(context); dbInfo.deleteNote(data.get(position)); // Deletes RV item/position's Info object data.remove(position); // Removes Info object at specified position notifyItemRemoved(position); // Notifies the RV that item has been removed } @Override public int getItemCount() { return data.size(); } // This is where the Swipe and Drag-And-Drog methods come into place @Override public boolean onItemMove(int fromPosition, int toPosition) { // Swapping positions // ATTEMPT TO UNDERSTAND WHAT IS GOING ON HERE Collections.swap(data, fromPosition, toPosition); notifyItemMoved(fromPosition, toPosition); return true; } @Override public void onItemDismiss(int position) { // Deleting item from RV and DB deleteItem(position); } class RecyclerVH extends RecyclerView.ViewHolder implements View.OnClickListener{ // OnClickListener is implemented here // Can also be added at onBindViewHolder above TextView listTitle, listContent; public RecyclerVH(View itemView) { super(itemView); listTitle = (TextView) itemView.findViewById(R.id.title); listContent = (TextView) itemView.findViewById(R.id.content); listTitle.setOnClickListener(this); } @Override public void onClick(View v) { Toast.makeText(context, "Opening: Note" + getLayoutPosition(), Toast.LENGTH_SHORT).show(); // PS NEVER ADD listTitle VARIABLE AS PUBLIC VARIABLE ABOVE WHICH IS GIVEN VALUE AT ONBINDVH // THIS IS BECAUSE THE VALUE WILL CHANGE IF ITEM IS ADDED OR DELETED } } }
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:fab="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" android:orientation="vertical" android:weightSum="1"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/rounded_corners" /> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerList" android:layout_width="match_parent" android:layout_height="wrap_content" /> <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent"> <com.melnykov.fab.FloatingActionButton android:id="@+id/fab_add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:layout_alignParentEnd="true" android:layout_marginBottom="16dp" android:layout_marginRight="16dp" android:layout_marginEnd="16dp" android:gravity="bottom|end" android:onClick="addNote" android:src="@drawable/fab_ic_add" fab:fab_colorNormal="@color/colorPrimary" fab:fab_colorPressed="@color/colorPrimaryDark" fab:fab_colorRipple="@color/colorPrimaryDark" /> </RelativeLayout> </FrameLayout> </LinearLayout>
custom_row.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/main" android:layout_width="wrap_content" android:layout_height="wrap_content"> <TextView android:id="@+id/title" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:padding="8dp" android:text="@string/test" android:textSize="18sp" android:textStyle="bold" /> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/main" android:paddingLeft="8dp"> <TextView android:id="@+id/content" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/test" android:textSize="15sp" /> </LinearLayout> </RelativeLayout>
Thank you so much to whoever can help me out. I am pulling my hair out as I type.
EDIT: I have confirmed that it is not my ItemTouchHelper class that's the problem. (Tried running without it being called, problem still occurs.) Also, it seems that when a dialog is shown and the keyboard brought up, the RecyclerView in the background resolves the problem by itself. After dialog is removed, the problem repeats (i.e. Scrolling puts massive space between items)
Try to use cardElevation=0dp. This should remove the extra spacing between recyclerview items.
Also, if you are using a recycler view inside the scroll view, make sure to set nested scrolling to false. Show activity on this post. Use a library as said by other comments in here. Also make sure you do not have Recyclerviews nested within a Scrollview.
To disable multi touch in recyclerview, you can use android:splitMotionEvents="false" in your recyclerview tag in layout file. By that attribute, you will not receive multi touch in recyclerview.
Luksprog's answer to Gabriele Mariotti's answer works.
According to the doc
With the release 2.3.0 there is an exciting new feature to the LayoutManager API: auto-measurement! This allows a RecyclerView to size itself based on the size of its contents. >This means that previously unavailable scenarios, such as using WRAP_CONTENT >for a dimension of the RecyclerView, are now possible. You’ll find all built in LayoutManagers now support auto-measurement.
Due to this change, make sure to double check the layout parameters of your item views: previously ignored layout parameters (such as MATCH_PARENT in the scroll direction) will now be fully respected.
In your item layout you have to change:
android:layout_height="match_parent"
with
android:layout_height="wrap_content"
change in Recycler view match_parent to wrap_content:
<android.support.v7.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="wrap_content"/>
Also change in item layout xml
Make parent layout height match_parent to wrap_content
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With