4

Я использую RecyclerView в DialogFragment (точно AlertDialog) с & сопротивления капли функциональности (ItemTouchHelper.Callback ->onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target)).RecyclerView в DialogFragment -> перетащить и падение (своп) анимация отстает

Проблема в том, что когда я перемещаюсь вверх или вниз, поднимается (перемещается), то анимация отстает. Я пробовал тот же RecyclerView с Fragment в Activity и он работает гладко. Я подозреваю, что проблема заключается в том, что Activity занимает весь экран и DialogFragment нет (в диалоговом окне отображается размытый фон). Я думаю, что некоторые дополнительные вычисления сделаны, перемещая элемент в AlertDialog.

Edited

Мой адаптер Класс:

public class ListAdapter extends RecyclerView.Adapter<ListAdapter.TabItemViewHolder> implements ItemTouchHelperAdapter { 

    private List<Tab> tabs; 

    public ListAdapter(List<Tab> tabs) { 
     this.tabs = tabs; 
    } 

    @Override 
    public TabItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list_tab_list, parent, false); 
     return new TabItemViewHolder(itemView); 
    } 


    @Override 
    public void onBindViewHolder(TabItemViewHolder holder, final int position) { 
     Tab tab = tabs.get(position); 
     holder.tvTabName.setText(tab.getTabCategory().toString()); 
    } 


    @Override 
    public int getItemCount() { 
     return tabs.size(); 
    } 

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

    @Override 
    public void onItemDismiss(int position) { 
     tabs.remove(position); 
     notifyItemRemoved(position); 
    } 

    public static class TabItemViewHolder extends RecyclerView.ViewHolder { 

     public TextView tvTabName; 

     public TabItemViewHolder(final View itemView) { 
      super(itemView); 

      tvTabName = (TextView) itemView.findViewById(R.id.cl__tv_tab_name); 


     } 
    } 
} 

Функции void onItemMove(int fromPosition, int toPosition) и void onItemDismiss(int position) вызываются из ItemTouchHelper.

DialogFragment класс:

public Dialog onCreateDialog(Bundle savedInstanceState) { 
    final RecyclerView recyclerView = (RecyclerView) getActivity().getLayoutInflater().inflate(R.layout.recycler_view, null); 

    ListAdapter listAdapter = new ListAdapter (tabs); 
    recyclerView.setAdapter(listAdapter); 
    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); 
    SimpleItemTouchHelperCallback simpleItemTouchHelperCallback = new SimpleItemTouchHelperCallback(listAdapter); 
    ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchHelperCallback); 
    itemTouchHelper.attachToRecyclerView(recyclerView); 

    return new AlertDialog.Builder(getActivity()) 
      .setTitle(R.string.title) 
      .setView(recyclerView) 
      .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) { 

       } 
      }) 
      .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) { 
       } 
      }).create(); 

} 
+2

Можете добавить код, который вы, возможно, пробовали? –

+0

@NileshSingh Это стандартный класс RecyclerView.Adapter, который реализует функции перемещения и увольнения элементов. Я уверен, что проблема в другом месте, потому что этот адаптер работает нормально в Fragment/Activity, но лагов при использовании в DialogFragment. – AppiDevo

+0

вы можете проверить этот пример -> [RecycleViewInDialogFragment] (https://github.com/CabezasGonzalezJavier/RecyclerViewInDialogFragment) – Cabezas

ответ

0

Проблема, кажется, в вашей реализации ItemTouchHelper.Callback. Попробуйте повторно реализовать функции перетаскивания с помощью следующего класса.

public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback { 

private final ItemTouchHelperAdapter mAdapter; 

public SimpleItemTouchHelperCallback(ItemTouchHelperAdapter adapter) { 
    mAdapter = adapter; 
} 

@Override 
public boolean isLongPressDragEnabled() { 
    return true; 
} 



@Override 
public boolean isItemViewSwipeEnabled() { 
    return true; 
} 

@Override 
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { 

     int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; 
     int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END; 
     return makeMovementFlags(dragFlags, swipeFlags); 

} 

@Override 
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, 
         RecyclerView.ViewHolder target) { 
    mAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition()); 
    return true; 
} 

@Override 
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { 
    mAdapter.onItemDismiss(viewHolder.getAdapterPosition()); 
} 

} 

Это Заказная реализация ItemTouchHelper.Callback позволит перетаскивать functionality.Your также будет необходимо реализовать интерфейс на адаптере для обновления статуса ваших данных.

public interface ItemTouchHelperAdapter { 


void onItemMove(int fromPosition, int toPosition); 

void onItemDismiss(int position); 

} 

/** * Интерфейс для прослушивания на ходу или события увольнения из {@link ItemTouchHelper.Callback}. * * @author Пол Берк (ipaulpro) */

реализация адаптера интерфейса также упоминается ниже.

@Override 
public int getItemCount() { 
    return data.size(); 
} 

@Override 
public void onItemMove(int fromPosition, int toPosition) { 

    if (fromPosition < toPosition) { 
     for (int i = fromPosition; i < toPosition; i++) { 
      Collections.swap(data, i, i + 1); 
     } 
    } else { 
     for (int i = fromPosition; i > toPosition; i--) { 
      Collections.swap(data, i, i - 1); 
     } 
    } 
    notifyItemMoved(fromPosition, toPosition); 

} 

@Override 
public void onItemDismiss(int position) { 
    data.remove(position); 
    notifyItemRemoved(position); 
} 

/**** Диалог Fragment ***/

@Nullable 
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    super.onCreateView(inflater, container, savedInstanceState); 
    View root = inflater.inflate(R.layout.dialog_fragment_layout,container,false); 
    list = (RecyclerView) root.findViewById(R.id.list); 
    data = getResources().getStringArray(R.array.list); 
    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity()); 
    linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); 
    list.setLayoutManager(linearLayoutManager); 
    ArrayList<String> listData = new ArrayList<>(); 
    listData.addAll(Arrays.asList(data)); 
    listAdapter = new ListAdapter(getActivity(),listData); 
    list.setAdapter(listAdapter); 
    SimpleItemTouchHelperCallback callback = new SimpleItemTouchHelperCallback(listAdapter); 
    ItemTouchHelper touchHelper = new ItemTouchHelper(callback); 
    touchHelper.attachToRecyclerView(list); 
    return root; 
} 
+0

Я уже использую реализацию Пола Берка ItemTouchHelper.Callback.Я уверен, что проблема не в моей реализации, потому что, как я уже сказал, мой адаптер отлично работает с полным списком активности/фрагмента активности. Я думаю, что решение будет основано на настройке некоторой дополнительной информации в DialogFragment (контейнере моего списка RecylerView). – AppiDevo

+0

Я так не думаю. Я создал простой старый фрагмент диалога и реализовал перетаскивание реализации paul burke. Просьба проверить мой код для фрагмента диалога выше. –

+0

Попробуйте использовать onCreateDialog (диалог с заголовком и кнопками) и AlertDialog.Builder setView (recylerView), и он будет отставать, поскольку мой код отстает. (1 ГГц - 2-х ядерное устройство, отлично работает на эмуляторах) – AppiDevo

0

я нашел, где проблема. Перетаскивание элемента отстает при создании диалога с помощью метода AlertDialog.Build. Мы должны использовать метод с пользовательским представлением - onCreateView(). Подробнее об этом в этом вопросе - DialogFragment - RecyclerView swap animation lags depending on the method used to create

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

  • Нет связанных вопросов^_^