Просмотр списка Android файлов Drag and Drop - программирование

Просмотр списка Android файлов Drag and Drop

У меня есть список записей в списке, который я хочу, чтобы пользователь мог повторно сортировать, используя метод перетаскивания. Я видел, как это реализовано в других приложениях, но я не нашел для него учебника. Это должно быть то, что нужно другим. Может ли кто-нибудь указать мне код для этого?

4b9b3361

Ответ 1

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

Его использование очень похоже на TouchInterceptor (на котором основан код), хотя были сделаны значительные изменения в реализации.

DragSortListView имеет плавную и предсказуемую прокрутку при перетаскивании и перемещении элементов. Перетасовка элементов намного более согласована с положением элемента перетаскивания/плавания. Поддерживаются элементы списка разнородных высот. Drag-scrolling настраивается (я демонстрирую быстрое перетаскивание прокрутки по длинному списку - не то, что приложение приходит на ум). Верхние и нижние колонтитулы соблюдаются. и т.д.?? Посмотрите.

Ответ 2

Добавляю этот ответ для тех, кто говорит об этом.

В последнее время произошел эпизод DevBytes (Перетаскивание и преобразование ячеек ListView), в котором объясняется, как это сделать

Вы можете найти здесь здесь также доступен пример кода здесь.

Что этот код в основном делает, так это то, что он создает dynamic listview расширением listview, которое поддерживает перетаскивание и замену ячеек. Чтобы вы могли использовать DynamicListView вместо вашего основного listview и что вы внедрили ListView с перетаскиванием.

Ответ 3

Теперь это довольно легко реализовать для RecyclerView с ItemTouchHelper. Просто переопределите метод onMove из ItemTouchHelper.Callback:

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

Довольно хорошее руководство по этому вопросу можно найти на сайте medium.com: Перетаскивание и прокрутка с помощью RecyclerView

Ответ 4

Я нашел DragSortListView работал хорошо, хотя начать с него было проще. Вот краткий учебник по использованию его в Android Studio со списком в памяти:

  • Добавьте это в зависимости build.gradle для вашего приложения:

    compile 'asia.ivity.android:drag-sort-listview:1.0' // Corresponds to release 0.6.1
    
  • Создайте ресурс для идентификатора дескриптора перетаскивания, создав или добавив в values/ids.xml:

    <resources>
        ... possibly other resources ...
        <item type="id" name="drag_handle" />
    </resources>
    
  • Создайте макет для элемента списка, который содержит ваше любимое изображение с ручкой перетаскивания, и назначьте его ID ID, который вы создали на шаге 2 (например, drag_handle).

  • Создайте макет DragSortListView, примерно так:

    <com.mobeta.android.dslv.DragSortListView
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:dslv="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        dslv:drag_handle_id="@id/drag_handle"
        dslv:float_background_color="@android:color/background_light"/>
    
  • Задайте производную ArrayAdapter с переопределением getView, которое отобразит ваш элемент списка.

        final ArrayAdapter<MyItem> itemAdapter = new ArrayAdapter<MyItem>(this, R.layout.my_item, R.id.my_item_name, items) { // The third parameter works around ugly Android legacy. http://stackoverflow.com/a/18529511/145173
            @Override public View getView(int position, View convertView, ViewGroup parent) {
                View view = super.getView(position, convertView, parent);
                MyItem item = getItem(position);
                ((TextView) view.findViewById(R.id.my_item_name)).setText(item.getName());
                // ... Fill in other views ...
                return view;
            }
        };
    
        dragSortListView.setAdapter(itemAdapter);
    
  • Установите прослушиватель кавычек, который переупорядочивает элементы по мере их удаления.

        dragSortListView.setDropListener(new DragSortListView.DropListener() {
            @Override public void drop(int from, int to) {
                MyItem movedItem = items.get(from);
                items.remove(from);
                if (from > to) --from;
                items.add(to, movedItem);
                itemAdapter.notifyDataSetChanged();
            }
        });
    

Ответ 5

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

Вот как вы его используете:

1: сначала добавьте lib в gradle

  зависимости {   compile 'com.github.woxthebox: draglistview: 1.2.1'
}
Код>

2: Добавить список из xml

<Предварительно > <код > < com.woxthebox.draglistview.DragListView   андроид: идентификатор = "@+ идентификатор /draglistview "   андроид: layout_width = "match_parent"   Android: layout_height = "match_parent" / > Код >

3: Установите прослушиватель перетаскивания

  mDragListView.setDragListListener(новый DragListView.DragListListener() {   @Override   public void onItemDragStarted (int position) {   }
   @Override   public void onItemDragEnded (int fromPosition, int toPosition) {   }
});
Код>

4: Создайте адаптер, переопределенный с помощью DragItemAdapter

  public class ItemAdapter расширяет DragItemAdapter < Pair < Long, String >, ItemAdapter.ViewHolder >   public ItemAdapter (ArrayList < Pair < Long, String > > список, int layoutId, int grabHandleId, boolean dragOnLongPress) {       супер (dragOnLongPress);       mLayoutId = layoutId;       mGrabHandleId = grabHandleId;       setHasStableIds (истинный);       setItemList (список);
}
Код>

5: Внедрите зрителя, который простирается от DragItemAdapter.ViewHolder

  открытый класс ViewHolder расширяет DragItemAdapter.ViewHolder {   public TextView mText;
   public ViewHolder (final View itemView) {       super (itemView, mGrabHandleId);       mText = (TextView) itemView.findViewById(R.id.text);   }
   @Override   public void onItemClicked (View view) {   }
   @Override   public boolean onItemLongClicked (Просмотреть представление) {       return true;   }
}
Код>

Для получения более подробной информации перейдите на страницу https://github.com/woxblom/DragListView

Ответ 6

Недавно я наткнулся на эту замечательную Gist, которая дает рабочую реализацию сортировки перетаскивания ListView, без каких-либо внешних зависимостей.


В основном это заключается в том, что ваш пользовательский адаптер расширяется ArrayAdapter как внутренний класс для активности, содержащей ваш ListView. На этом адаптере затем устанавливается onTouchListener на ваши элементы списка, которые будут сигнализировать о начале перетаскивания.

В этом Gist они устанавливают слушателя на определенную часть макета элемента списка ( "дескриптор" элемента), поэтому его нельзя случайно переместить, нажав любую его часть. Лично я предпочел пойти с onLongClickListener вместо этого, но это зависит от вас, чтобы решить. Вот выдержка из этой части:

public class MyArrayAdapter extends ArrayAdapter<String> {

    private ArrayList<String> mStrings = new ArrayList<String>();
    private LayoutInflater mInflater;
    private int mLayout;

    //constructor, clear, remove, add, insert...

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder holder;

        View view = convertView;
        //inflate, etc...

        final String string = mStrings.get(position);
        holder.title.setText(string);

        // Here the listener is set specifically to the handle of the layout
        holder.handle.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
                    startDrag(string);
                    return true;
                }
                return false;
            }
        });

        // change color on dragging item and other things...         

        return view;
    }
}

Это также связано с добавлением onTouchListener в ListView, который проверяет, перетаскивается ли элемент, обрабатывает подкачку и недействительность и останавливает состояние перетаскивания. Выдержка из этой части:

mListView.setOnTouchListener(new View.OnTouchListener() {
     @Override
     public boolean onTouch(View view, MotionEvent event) {
        if (!mSortable) { return false; }
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN: {
                break;
            }
            case MotionEvent.ACTION_MOVE: {
                // get positions
                int position = mListView.pointToPosition((int) event.getX(), 
                    (int) event.getY());
                if (position < 0) {
                    break;
                }
                // check if it time to swap
                if (position != mPosition) {
                    mPosition = position;
                    mAdapter.remove(mDragString);
                    mAdapter.insert(mDragString, mPosition);
                }
                return true;
            }
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_OUTSIDE: {
                //stop drag state
                stopDrag();
                return true;
            }
        }
        return false;
    }
});

Наконец, вот как выглядят методы stopDrag и startDrag, которые обрабатывают включение и отключение процесса перетаскивания:

public void startDrag(String string) {
    mPosition = -1;
    mSortable = true;
    mDragString = string;
    mAdapter.notifyDataSetChanged();
}

public void stopDrag() {
    mPosition = -1;
    mSortable = false;
    mDragString = null;
    mAdapter.notifyDataSetChanged();
}