본문 바로가기
안드로이드/개발자 일상

안드로이드 RecyclerView 리스트 이동 (삼선 이미지 드래그 시)

by 차누감 2020. 4. 13.

2020/03/22 - [안드로이드/개발자 일상] - 안드로이드 Retrofit2+RecyclerView 1-1(영화진흥위원회 오픈 API 이용)

이전 위 링크  RecyclerView 예제에서 리스트 이동하는 기능을 추가하여 작성하였습니다.

(변경 사항은 버튼을 누르지 않고 바로 데이터를 load 했습니다.)

(이전 예제 참고 부탁드립니다.)

 

 

<실행 화면> - 삼선 이미지를 드래그 하면 목록이 이동되고, 다른 것을 누르면 반응이 없습니다.

리스트 이동 추가 코드
ItemTouchHelperCallback Class를 생성하고
Adapter에 implements 하여 메소드 @Override onItemMove()
MainActivity에 적용만 하면 됩니다. 
(간단)


activity_main.xml

( 이전 예제와 달리 버튼을 눌러서 영화 목록을 가져 올 것이 아니기 때문에 RecyclerView 만 배치시킵니다.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="utf-8"?>
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
 
        android:id="@+id/rv_recyclerview"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        android:orientation="vertical"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>
 
 
 

우선 삼선 이미지를 추가합니다.

리스트가 보여줄 아이템의 레이아웃을 만듭니다.

recyclerview_item.xml (이전 예제 추가 사항 : 45번 줄 Imageview 추가 및 삼선 이미치 적용)

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
<?xml version="1.0" encoding="utf-8"?>
    android:layout_width="match_parent"
    android:layout_height="100dp"
    xmlns:tools="http://schemas.android.com/tools">
 
    <TextView
        android:id="@+id/tv_rank"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:background="@color/colorAccent"
        android:textSize="24sp"
        android:textColor="#FFFFFF"
        android:gravity="center"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.12"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.506"/>
    <TextView
        android:id="@+id/tv_movieNm"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.352"
        app:layout_constraintStart_toEndOf="@+id/tv_rank"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.506"
        tools:text="movieName" />
 
    <TextView
        android:id="@+id/tv_openDt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="16dp"
        android:textSize="14sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        tools:text="2020-01-01" />
 
    <ImageView
        android:id="@+id/iv_drag"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_marginEnd="16dp"
        android:src="@drawable/ic_dehaze_black_24dp"
        android:clickable="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
 
 
 

<기능 추가 전 모습 - 리스트만 존재>

이제 리스트를 이동할 수 있도록 해봅니다.

추가
ItemTouchHelperCallback Class를 생성하고
Adapter에 implements 하여 메소드 @Override onItemMove()
MainActivity에 적용만 하면 됩니다.
(간단)

 

이동되는 주 기능인 ItemToucHelper.Callback을 상속받는 클래스를 생성합니다.

ItemTouchHelperCallback.java

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
 
 
import androidx.annotation.NonNull;
 
public class ItemTouchHelperCallback extends ItemTouchHelper.Callback {
 
    static int dragFlag=0;
 
 
    public interface OnItemMoveListener{
        void onItemMove(int fromPosition, int toPosition);
    }
 
    private final OnItemMoveListener onItemMoveListener;
    public ItemTouchHelperCallback(OnItemMoveListener onItemMoveListener) {
        this.onItemMoveListener = onItemMoveListener;
    }
 
    @Override
    public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
 
        // 삼선 이미지 클릭 시에만 이동 가능
        viewHolder.itemView.findViewById(R.id.iv_drag).setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
 
                if( event.getAction()== MotionEvent.ACTION_DOWN ||  event.getAction()== MotionEvent.ACTION_MOVE){
                    dragFlag = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
                }else dragFlag=0;
                return false;
            }
        });
       return makeMovementFlags(dragFlag,0);
    }
 
    @Override
    public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
        onItemMoveListener.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
        return false;
    }
    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
    }
 
}// ItemTouchHelperCallback class..
 
 

 

이제 Adapter에 구현을 합니다.

( 이전 예제와 다른 점을 표기했습니다. )

 

MyAdapter.java

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
59
60
61
62
63
64
65
66
67
68
 
 
 
import androidx.annotation.NonNull;
 
 
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> implements ItemTouchHelperCallback.OnItemMoveListener{
    private ArrayList<Map<String, Object>> items= new ArrayList<Map<String, Object>>();
 
    public MyAdapter(ArrayList<Map<String, Object>> resultList){
        this.items=resultList;
    }
    @NonNull
    @Override
    public MyAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return new MyViewHolder(itemView);
    }
 
    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        Map<String, Object> item = items.get(position);
        holder.setItem(item);
    }
 
    @Override
    public int getItemCount() {
        return items.size();
    }
 
    @Override
    public void onItemMove(int fromPosition, int toPosition) {
        notifyItemMoved(fromPosition, toPosition);
    }
 
    public static class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView tvRank, tvMovieNm, tvOpenDt;
        public ImageView ivDrag;
        public MyViewHolder(View itemView) {
            super(itemView);
            tvRank=itemView.findViewById(R.id.tv_rank);
            tvMovieNm=itemView.findViewById(R.id.tv_movieNm);
            tvOpenDt=itemView.findViewById(R.id.tv_openDt);
            ivDrag=itemView.findViewById(R.id.iv_drag);
 
        }
        public void setItem(Map<String, Object> item){
 
            //"rank", "movieNm", "openDt"은 Json파일에 저장되어 있던 key값
            tvRank.setText(item.get("rank").toString());
            tvMovieNm.setText(item.get("movieNm").toString());
            tvOpenDt.setText(item.get("openDt").toString());
 
        }
    }
}
 
 

이제 MainActivity에 적용을 합니다.

( 이전 예제와 다른 점을 표기했습니다. )

MainActivity.java

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
59
60
61
62
63
64
65
66
67
 
 
 
 
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
 
 
public class MainActivity extends AppCompatActivity { //implements MyAdapter.OnStartDragListener
 
    private RecyclerView recyclerView;
    private RecyclerView.Adapter mAdapter;
 
    String baseUrl = "http://www.kobis.or.kr";
    String API_KEY = "영화진흥위원회에서 발급 받은 Key를 넣어주세요";
 
    Retrofit retrofit;
 
    ItemTouchHelper itemTouchHelper;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        recyclerView=findViewById(R.id.rv_recyclerview);
 
        //Retrofit 객체생성
        retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        RetrofitInterface retrofitInterface= retrofit.create(RetrofitInterface.class);
 
        retrofitInterface.getBoxOffice(API_KEY,"20200412").enqueue(new Callback<Map<String, Object>>() {
            @Override
            public void onResponse(Call<Map<String, Object>> call, Response<Map<String, Object>> response) {
 
                Map<String,Object> boxOfficeResult= (Map<String, Object>response.body().get("boxOfficeResult");
                ArrayList<Map<String, Object>> jsonList = (ArrayList) boxOfficeResult.get("dailyBoxOfficeList");
                mAdapter=new MyAdapter(jsonList);
 
                ItemTouchHelperCallback callback= new ItemTouchHelperCallback((ItemTouchHelperCallback.OnItemMoveListener) mAdapter);
                itemTouchHelper= new ItemTouchHelper(callback);
                itemTouchHelper.attachToRecyclerView(recyclerView);
                recyclerView.setAdapter(mAdapter);
            }
 
            @Override
            public void onFailure(Call<Map<String, Object>> call, Throwable t) {
            }
        });
 
    }// onCreate()..
 
}// MainActivity class..
 
 

<실행 화면> - 삼선 이미지를 드래그 하면 목록이 이동되고, 다른 것을 누르면 반응이 없습니다.

댓글