드래그 앤 드롭 방법을 사용하여 사용자가 다시 정렬 할 수 있도록 목록보기에 레코드 목록이 있습니다. 다른 앱에서 구현 된 것을 보았지만 튜토리얼을 찾지 못했습니다. 다른 사람들도 필요로하는 것이어야합니다. 누구 든지이 작업을 수행하는 코드를 알려줄 수 있습니까?
드래그 앤 드롭 방법을 사용하여 사용자가 다시 정렬 할 수 있도록 목록보기에 레코드 목록이 있습니다. 다른 앱에서 구현 된 것을 보았지만 튜토리얼을 찾지 못했습니다. 다른 사람들도 필요로하는 것이어야합니다. 누구 든지이 작업을 수행하는 코드를 알려줄 수 있습니까?
답변:
나는 지금 얼마 동안이 일을 해왔다. 이해하기 힘들고, 내가 주장한다고 주장하지는 않지만 지금까지는 만족합니다. 내 코드와 몇 가지 데모는
코드의 기반이되는 TouchInterceptor와 매우 유사하지만 구현이 크게 변경되었습니다.
DragSortListView에는 항목을 드래그하고 섞는 동안 부드럽고 예측 가능한 스크롤이 있습니다. 항목 셔플은 드래그 / 플로팅 항목의 위치와 훨씬 더 일관됩니다. 이기종 높이 목록 항목이 지원됩니다. 드래그 스크롤은 사용자 정의가 가능합니다 (응용 프로그램이 아니라 긴 목록을 통해 빠른 드래그 스크롤을 보여줍니다). 머리글 / 바닥 글이 존중됩니다. 기타.?? 구경하다.
이제 ItemTouchHelper 로 구현하기 RecyclerView
가 매우 쉽습니다 . 에서 메소드를 재정의하십시오 .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로 드래그 앤 스 와이프
이것에 대해 구글 사람들을 위해이 답변을 추가하고 있습니다 ..
최근 에 DevBytes ( ListView 셀 드래그 앤 재 배열 ) 에피소드가 있었으며이 작업을 수행하는 방법이 설명되어 있습니다.
당신은 그것을 찾을 수 있습니다 여기에 또한 샘플 코드를 볼 수 있습니다 여기에 .
이 코드는 기본적으로 셀 드래그 및 스와핑을 지원 dynamic listview
하는 확장 기능 으로 코드를 만듭니다 listview
. 따라서 DynamicListView
기본 대신 사용할 수 ListView
있으며 드래그 앤 드롭으로 ListView를 구현했습니다.
DragListView lib는 고도 애니메이션과 같은 커스텀 애니메이션을 아주 잘 지원하여 깔끔하게 처리합니다. 또한 정기적으로 유지 관리 및 업데이트됩니다.
사용 방법은 다음과 같습니다.
1 : 먼저 gradle에 lib 추가
dependencies {
compile 'com.github.woxthebox:draglistview:1.2.1'
}
2 : XML에서 목록 추가
<com.woxthebox.draglistview.DragListView
android:id="@+id/draglistview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
3 : 드래그 리스너 설정
mDragListView.setDragListListener(new DragListView.DragListListener() {
@Override
public void onItemDragStarted(int position) {
}
@Override
public void onItemDragEnded(int fromPosition, int toPosition) {
}
});
4 : DragItemAdapter에서 대체 된 어댑터 작성
public class ItemAdapter extends DragItemAdapter<Pair<Long, String>, ItemAdapter.ViewHolder>
public ItemAdapter(ArrayList<Pair<Long, String>> list, int layoutId, int grabHandleId, boolean dragOnLongPress) {
super(dragOnLongPress);
mLayoutId = layoutId;
mGrabHandleId = grabHandleId;
setHasStableIds(true);
setItemList(list);
}
5 : DragItemAdapter.ViewHolder에서 확장되는 뷰 홀더를 구현하십시오.
public class ViewHolder extends 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(View view) {
return true;
}
}
DragSortListView가 잘 작동하지만 시작하는 것이 더 쉬울 수 있음을 알았습니다 . 다음은 인 메모리 목록과 함께 Android Studio에서 사용하는 방법에 대한 간단한 자습서입니다.
이것을 build.gradle
앱 의 종속성에 추가하십시오 .
compile 'asia.ivity.android:drag-sort-listview:1.0' // Corresponds to release 0.6.1
다음을 추가하거나 추가하여 드래그 핸들 ID에 대한 리소스를 만듭니다 values/ids.xml
.
<resources>
... possibly other resources ...
<item type="id" name="drag_handle" />
</resources>
즐겨 찾는 드래그 핸들 이미지가 포함 된 목록 항목의 레이아웃을 만들고 2 단계에서 만든 ID (예 :)에 해당 ID를 할당하십시오 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();
}
});
나는 최근에 외부 의존성이 필요없는 드래그 정렬의 작동 구현을 제공하는 이 위대한 요점 을 우연히 발견 ListView
했습니다.
기본적으로는를 ArrayAdapter
포함하는 활동의 내부 클래스로 확장되는 사용자 정의 어댑터를 작성하는 것으로 구성됩니다 ListView
. 그런 다음이 어댑터에서 onTouchListener
목록 항목 을 설정 하여 드래그 시작을 알립니다.
그 요지에서 그들은 리스너를 목록 항목 레이아웃의 특정 부분 (항목의 "손잡이")으로 설정 했으므로 어떤 부분을 눌러도 실수로 리스너가 움직이지 않습니다. 개인적으로, 나는 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's 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();
}