我的项目有不同的布局,有时我通过在布局中拖动项目在RecyclerView之上创建一个差距或间隙.当我回滚到RecyclerView的顶部时,一些项目被重新排序,并且它们的空白被填充.
行为被捕获在这里:
行为被捕获在这里:
填补空白是可以的.拖动时项目更改位置也可以.问题在于滚动到顶部.滚动结束时会重新排序 – 我没有触摸屏幕.
这是我如何创建回收记录和布局管理器
recyclerView = (RecyclerView)layout.findViewById(R.id.recycler_view); stagaggeredGridLayoutManager = new StaggeredGridLayoutManager( getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 3 : 2,StaggeredGridLayoutManager.VERTICAL); recyclerView.setLayoutManager(stagaggeredGridLayoutManager); stagaggeredList = getListItemData(); StatisticsGridViewAdapter rcAdapter = new StatisticsGridViewAdapter(this.getActivity(),stagaggeredList,recyclerView); ItemTouchHelper.Callback callback = new StatisticsTouchHelperCallback(rcAdapter); touchHelper = new ItemTouchHelper(callback); touchHelper.attachToRecyclerView(recyclerView); recyclerView.setAdapter(rcAdapter);
ItemTouchHelper类
public class StatisticsTouchHelperCallback extends ItemTouchHelper.Callback { private final ItemTouchHelperAdapter touchHelperAdapter; @Override public boolean isLongPressDragEnabled() { return true; } @Override public boolean isItemViewSwipeEnabled() { return false; } @Override public int getMovementFlags(RecyclerView recyclerView,RecyclerView.ViewHolder viewHolder) { int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT; int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END; return makeMovementFlags(dragFlags,swipeFlags); } @Override public boolean onMove(RecyclerView recyclerView,RecyclerView.ViewHolder viewHolder,RecyclerView.ViewHolder target) { touchHelperAdapter.onItemMove(viewHolder.getAdapterPosition(),target.getAdapterPosition()); return false; } @Override public void onSwiped(RecyclerView.ViewHolder viewHolder,int direction) { touchHelperAdapter.onItemDismiss(viewHolder.getAdapterPosition()); } public StatisticsTouchHelperCallback(ItemTouchHelperAdapter adapter) { touchHelperAdapter = adapter; } }
RecyclerView适配器
public class StatisticsGridViewAdapter extends RecyclerView.Adapter<StatisticsGridItemViewHolder> implements ItemTouchHelperAdapter { private List<Statistic> itemList; private Context context; @Override public StatisticsGridItemViewHolder onCreateViewHolder(ViewGroup parent,int viewType) { View layoutView = LayoutInflater.from(parent.getContext()).inflate(itemList.get(viewType).getStatisticType().getStringResourcesId(),null); StatisticsGridItemViewHolder rcv = new StatisticsGridItemViewHolder(layoutView,viewType); return rcv; } @Override public void onBindViewHolder(final StatisticsGridItemViewHolder holder,int position) { holder.getMenu().setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { PopupMenu popup = new PopupMenu(v.getContext(),holder.getMenu()); popup.getMenuInflater().inflate(R.menu.statistics__widget__popup_menu,popup.getMenu()); Menu menu = popup.getMenu(); MenuItem item = menu.add(R.string.statistics__widget__menu_item__pin_to_dashboard); //item.setOnMenuItemClickListener() popup.show(); } }); } @Override public int getItemCount() { return this.itemList.size(); } @Override public boolean onItemMove(int fromPosition,int toPosition) { if (fromPosition < toPosition) { for (int i = fromPosition; i < toPosition; i++) { Collections.swap(itemList,i,i + 1); } } else { for (int i = fromPosition; i > toPosition; i--) { Collections.swap(itemList,i - 1); } } notifyItemMoved(fromPosition,toPosition); return true; } @Override public void onItemDismiss(int position) { itemList.remove(position); notifyItemRemoved(position); } @Override public int getItemViewType(int position) {return itemList.get(position).getStatisticType().getPosition(); } public StatisticsGridViewAdapter(Context context,List<Statistic> itemList) { this.itemList = itemList; this.context = context; } } interface ItemTouchHelperAdapter { boolean onItemMove(int fromPosition,int toPosition); void onItemDismiss(int position); }
现在我使用12种不同的布局,结构相同.只有高度不同才能模拟最终的小部件.
项目布局示例
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" > <LinearLayout android:id="@+id/statistics__widget__main_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/order_tile_final" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_marginTop="2dp" android:layout_marginBottom="7dp" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="17dp" android:orientation="horizontal"> <TextView android:id="@+id/widget_title" android:layout_width="0dp" android:layout_height="wrap_content" android:text="@string/statistics__widget__forms_filled_title" style="@style/tablet_common_font__main_3" android:paddingTop="10dp" android:layout_weight="1"/> <ImageView android:id="@+id/widget_menu" android:layout_width="wrap_content" android:layout_height="23dp" android:layout_marginTop="7dp" android:paddingTop="5dp" android:layout_marginRight="8dp" android:src="@drawable/a_menu_dark"/> </LinearLayout> <TextView android:id="@+id/widget_value" android:layout_width="wrap_content" android:layout_height="wrap_content" style="@style/tablet_common_font__headline_2" android:layout_marginLeft="17dp" android:layout_marginBottom="6dp"/> </LinearLayout> </LinearLayout>
解决方法
我认为这是
StaggeredGridLayoutManager的常见行为:
When scroll state is changed to SCROLL_STATE_IDLE,StaggeredGrid will check if there are gaps in the because of full span items. If it finds,it will re-layout and move items to correct positions with animations.
您可以通过将战略改为GAP_HANDLING_NONE来阻止填补差距的行为:
stagaggeredGridLayoutManager.setGapStrategy( StaggeredGridLayoutManager.GAP_HANDLING_NONE);