일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- graphQL
- Dependency Injection
- 웹크롤링
- PYTHON
- java
- 안드로이드 디자인패턴
- Kotlin
- Android
- 유니티
- unit test
- dagger-hilt
- 안드로이드
- 파이썬 크롤링
- ubuntu python
- mvvm
- 자바
- flutter
- Apollo GraphQL
- MVVM pattern
- Android test
- 안드로이드 mvp
- 안드로이드 테스트
- 우분투 파이썬
- Data structure
- Nexus GraphQL
- Design Pattern
- prisma
- Apollo Server
- LinkedList
- 자바기초
- Today
- Total
Hun's Blog
Android RecyclerView + ItemTouchHelper - 드래그 앤 드롭, 스와이프 본문
RecyclerView + ItemTouchHelper -> Drag and Drop과 swipe 구현
activity_main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
android:id="@+id/rv_tab_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/tab_item"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
|
tools:listitem -> 리사이클러뷰에 추가 될 레이아웃을 지정한다.
tab_item.xml -> 추가될 아이템 레이아웃
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:minHeight="60dp"
android:orientation="horizontal"
android:paddingEnd="20dp"
android:paddingStart="20dp">
<TextView
android:id="@+id/name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:textColor="@android:color/primary_text_light"
android:textSize="20sp"
android:text="TAB NAME" />
<FrameLayout
android:id="@+id/drag_handle"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:src="@drawable/ic_drag_handle" />
</FrameLayout>
</LinearLayout>
|
TabItem 모델
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
public class TabItem {
private String name;
private int number;
public TabItem(String name, int number){
this.name = name;
this.number = number;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
|
아이템 레이아웃에 셋팅 될 Tab name과 리스트 순번을 모델 객체가 저장하고 반환한다.
ItemTouchHelperListener 인터페이스
1
2
3
4
|
public interface ItemTouchHelperListener {
boolean onItemMove(int form_position, int to_position);
void onItemSwipe(int position);
}
|
RecylcerView의 Adapter 클래스에서 상속받는다.
onItemMove -> 아이템의 현재 위치와 이동 위치를 입력받아 아이템 리스트에의 위치를 수정하도록 구현
onItemSwipe -> 아이템의 포지션값을 받아 해당 아이템을 Swipe할때 로직을 구현
ItemTouchHelperCallback
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
public class ItemTouchHelperCallback extends ItemTouchHelper.Callback {
private ItemTouchHelperListener listener;
public ItemTouchHelperCallback(ItemTouchHelperListener listener) { this.listener = listener; }
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView,
@NonNull RecyclerView.ViewHolder viewHolder) {
return makeMovementFlags(drag_flags,swipe_flasg);
}
@Override
public boolean onMove(@NonNull RecyclerView recyclerView,
@NonNull RecyclerView.ViewHolder viewHolder,
@NonNull RecyclerView.ViewHolder target) {
return listener.onItemMove(viewHolder.getAdapterPosition(),target.getAdapterPosition());
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
listener.onItemSwipe(viewHolder.getAdapterPosition());
}
@Override
public boolean isLongPressDragEnabled() {
return true;
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
ItemTouchHelperCallback 생성자
-> 해당 클래스를 생성할 때 ItemTouchHelperListener를 입력받아 멤버 인스턴스로 지정하고 ItemTouchHelper.Callback이 지원하는 여러 메소드를 오버라이딩 하여 필요에 따라 사용한 후 결과값들을 반환해 준다. 아이템 위치변경 , 스와이프 , 롱클릭 등 다양한 기능을 지원한다.
getMovementFlags
-> 리사이클러뷰와 리사이클러뷰 뷰홀더를 입력받는다.
-> drag 위치와 swipe 위치를 ItemTouchHelper에서 받아 셋팅한다.
-> makeMovementFlags() 메소드로 drag위치와 swipe 위치를 입력하여 현재 위치값을 int로 반환해준다.
onMove
-> 리사이클러뷰,viewHolder, target(viewHolder 중 선택된 아이템)을 입력받아 움직임을 감지한다.
-> ItemTouchHelperListener의 onItemMove메소드로 해당 아이템의 움직임을 감지한다.
-> onItemMove 메소드는 아이템이 움직이고 있는 가를 판별하고 boolean 값으로 반환한다.
onSwiped
-> 리사이클러뷰의 뷰홀더와 움직일 방향을 입력받는다.
-> ItemTouchHelperListner의 onItemSwipe메소드에 움직일 방향을 입력하여 swipe를 구현한다.
isLongPressDragEnabled()
-> true를 반환하도록 설정하면 롱클릭을 감지한다.
TabListAdpater
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
public class TabListAdapter extends RecyclerView.Adapter<TabListAdapter.ItemViewHolder>
implements ItemTouchHelperListener{
private ArrayList<TabItem> items = new ArrayList<>();
public TabListAdapter(){}
@NonNull
@Override
public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.tab_item, parent, false);
return new ItemViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) {
}
@Override
public int getItemCount() {
return items.size();
}
public void setItems(ArrayList<TabItem> itemList){
items = itemList;
notifyDataSetChanged();
}
@Override
public boolean onItemMove(int form_position, int to_position) {
TabItem item = items.get(form_position);
items.add(to_position,item);
item.setNumber(to_position);
notifyItemMoved(form_position, to_position);
return true;
}
@Override
public void onItemSwipe(int position) {
notifyItemRemoved(position);
}
public class ItemViewHolder extends RecyclerView.ViewHolder {
TextView tabName;
public ItemViewHolder(@NonNull View itemView) {
super(itemView);
tabName = itemView.findViewById(R.id.name);
}
public void onBind(TabItem item,int position){
tabName.setText(item.getName());
item.setNumber(position);
}
}
}
|
-> RecyclerView.Adapter 를 상속받는다.
Adapter에는 RecyclerView.ViewHolder를 상속받은 내부 클래스를 구현하고 제네릭으로 지정하여 상속받아야 한다.
-> ItemTouchHelperListener를 상속받아 onItemMove과 onItemSwipe를 오버라이딩하여 행동을 구현해준다.
-> TabItem 모델을 제네릭으로 지정한 ArrayList를 생성한다.
--
RecyclerView 상속 오버라이딩 메소드
onCreateViewHolder
-> 리사이클러뷰에 추가될 item 레이아웃을 연결한다.
-> ItemViewHolder 클래스에 View(item레이아웃)를 입력한다.
onBindViewHolder
-> ItemViewHolder와 아이템의 리스트상 위치를 입력받는다.
-> ItemViewHolder 내부에 구현한 onBind 메소드에 아이템 리스트에서 포지션값으로 아이템을 선택하여 입력한다.
getItemCount
-> items의 전체 갯수 숫자를 반환한다.
--
setItems
-> 메인액티비티에서 TabItem 객체를 생성한 후에 리스트를 입력하여 어댑터의 멤버 items에 매치시킨다.
-> notifyDataSetChanged메소드로 데이터가 셋팅되었음을 알린다.
--
ItemTouchHelperListener 오버라이딩 메소드
onItemMove
-> 아이템의 리스트상 현재위치와 움직일 위치를 입력받느다.
-> 입력받은 값으로 아이템의 이동을 구현한다.
-> notifyItemMoved 메소드로 데이터가 이동함을 알린다.
onItemSwipe
-> 포지션값을 입력받는다.
-> 포지션값으로 아이템리스트의 해당 포지션 아이템을 삭제한다.
-> notifyItemRemoved 메소드로 데이터가 삭제되었음을 알린다.
--
ItemViewHolder 클래스
ItemViewHolder
-> 아이템 레이아웃의 name TextView 와 연결한다.
onBind
-> TabItem객체에 셋팅된 값으로 각각의 레이아웃에 셋팅한다.
MainActivity
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private TabListAdapter mAdapter;
private ItemTouchHelper mItemTouchHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = (RecyclerView) findViewById(R.id.rv_tab_list);
LinearLayoutManager manager = new LinearLayoutManager(getApplicationContext());
manager.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(manager);
mAdapter = new TabListAdapter();
mRecyclerView.setAdapter(mAdapter);
mItemTouchHelper = new ItemTouchHelper(new ItemTouchHelperCallback(mAdapter));
mItemTouchHelper.attachToRecyclerView(mRecyclerView);
ArrayList<TabItem> items = new ArrayList<>();
TabItem item1 = new TabItem("SUBSCRIBE",0);
TabItem item2 = new TabItem("BEST",0);
TabItem item3 = new TabItem("MUSIC",0);
TabItem item4 = new TabItem("SPORTS",0);
TabItem item5 = new TabItem("GAME",0);
TabItem item6 = new TabItem("MOVIE",0);
TabItem item7 = new TabItem("NEWS",0);
TabItem item8 = new TabItem("LIVE",0);
items.add(item1);
items.add(item2);
items.add(item3);
items.add(item4);
items.add(item5);
items.add(item6);
items.add(item7);
items.add(item8);
mAdapter.setItems(items);
}
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs |
-> 리사이클러뷰를 생성한다.
-> 리사이클러뷰에 LinearLayoutManager를 활용해 속성을 지정한다.
-> 리사이클러뷰에 TabListAdpater를 셋팅한다.
-> 어댑터를 입력한 ItemTouchHelperCallback 클래스를 ItemTouchHelper 생성자에 입력하여 생성한다.
-> TouchHelper 의 attachToRecyclerView 메소드를 활용해 Touch를 구현할 리사이클러뷰를 연결한다.
-> TabItem 을 제네릭으로 받는 ArrayList를 생성하고 임의의 값을 셋팅한다.
-> 어댑터의 setItems 메소드에 해당 ArrayList를 입력한다.
참고
https://fullstatck.tistory.com/15
https://everyshare.tistory.com/27
https://developer.android.com/guide/topics/ui/drag-drop?hl=ko
'Android' 카테고리의 다른 글
안드로이드 Room Database + Live Data (0) | 2020.03.25 |
---|---|
안드로이드 Chip 레이아웃 - Chip + Chip Group (0) | 2020.03.24 |
[Android] 디자인패턴 5 - MVVM패턴 (0) | 2020.03.22 |
[Android] 디자인패턴 4 - MVP패턴 Google todo-mvp (0) | 2020.03.22 |
[Android] 디자인패턴 3 - MVP 패턴 (0) | 2020.03.22 |