12

Мои элементы имеют разные макеты, и иногда я создаю пробел или пробелы поверх RecyclerView, перетаскивая элементы в макете. Когда я перехожу назад в начало RecyclerView, некоторые элементы переупорядочиваются, и пробелы заполняются ими. Поведение захватывается здесь:StaggeredGridLayoutManager переупорядочивает элементы

Auto reordering during scrolling to top

Заполнение пробелов в порядке. Это также нормально, когда элементы меняют положение во время перетаскивания. Проблема в том, когда дело доходит до прокрутки вверх. Переопределение происходит, когда прокрутка заканчивается - я не касаюсь экрана.

ЭТО КАК СОЗДАТЬ 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, 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> 
+0

@Nikola Anusev Просто улучшение удаления recyclerView.setHasFixedSize (истинное); Причина, по которой элементы рисуются на экране, имеют неравную ширину и высоту. –

+0

Пожалуйста, укажите расположение элементов. – WindRider

+0

Я добавил пример макета элемента –

ответ

0

Я думаю, что это общее поведение StaggeredGridLayoutManager:

Когда состояние прокрутки изменяется на SCROLL_STATE_IDLE, StaggeredGrid будет проверять, если есть пробелы в из-за элементов полного диапазона. Если он найдет, он будет повторно размещать и перемещать элементы для корректировки позиций с анимацией.

Вы можете остановить заполнение зазора поведения, изменяя стратегию GAP_HANDLING_NONE:

stagaggeredGridLayoutManager.setGapStrategy(
     StaggeredGridLayoutManager.GAP_HANDLING_NONE); 
+1

Благодарим за отзыв.Я знаю об этом параметре, но он не будет исправлять мою проблему. Ожидаемый сценарий был бы, если элементы были перемещены только вверх и вниз, чтобы заполнить пробелы. –

0

Я работал на Recyclerview раньше, если я понял ваш вопрос, я думаю, что ниже, что будет исправить эту проблему.

@Override 
public boolean onItemMove(int fromPosition, int toPosition) { 
    if (fromPosition < toPosition) { 
     for (int i = fromPosition; i < toPosition; i++) { 
      Collections.swap(itemList, i, i + 1); 
      notifyItemMoved(i, i+1); 
     } 
    } else { 
     for (int i = fromPosition; i > toPosition; i--) { 
      Collections.swap(itemList, i, i - 1); 
      notifyItemMoved(i, i-1); 
     } 
    } 

    return true; 
} 

Дайте мне знать, если возникнут какие-либо проблемы, или я ошибаюсь в понимании проблемы ур.

Лучшие Regds

+0

Это не устранило проблему. Элементы по-прежнему переупорядочиваются после прокрутки вверх. –

0

Вы должны расширить Recycler View, чтобы включить функцию переназначения.

Пожалуйста, следуйте по следующей ссылке: https://gist.github.com/mohlendo/68b7e2f89d0b1b354abe

И для полного примера используйте следующую ссылку: https://github.com/mohlendo/ReorderRecyclerView

+0

Пример не работает с элементами, которые имеют разные макеты. –

Смежные вопросы