룬아님의 취중코딩

3-2. 안드로이드 개발 레벨업 교과서 (RecyclerView) 본문

카테고리 없음

3-2. 안드로이드 개발 레벨업 교과서 (RecyclerView)

룬아님 2019. 8. 27. 00:27

https://github.com/wikibook/advanced-android-book/tree/master/tech04/RecyclerViewSamples/app/src/main/java/com/github/advanced_android/recyclerviewsamples/divider

 

wikibook/advanced-android-book

『안드로이드 개발 레벨업 교과서: 현업 최고의 안드로이드 개발자가 알려 주는』 예제 코드. Contribute to wikibook/advanced-android-book development by creating an account on GitHub.

github.com

 

 


리사이클러뷰에 구분선 넣기


getItemOffsets() 메서드로 각 아이템에 대한 Offset(빈 영역)을 설정하고 onDraw() 메서드로 실제로 구분선을 그립니다.

public class DividerItemDecoration extends RecyclerView.ItemDecoration {

    private final int dividerHeight;
    private Drawable divider;

    public DividerItemDecoration(Context context) {
        // 기본인 ListView 구분선의 Drawable을 얻는다(구분선을 커스터마이징하고 싶을 때는 여기서 Drawable을 가져온다)
        final TypedArray a = context.obtainStyledAttributes(new int[]{android.R.attr.listDivider});
        divider = a.getDrawable(0);

        // 표시할 때마다 높이를 가져오지 않아도 되게 여기서 구해 둔다
        dividerHeight = divider.getIntrinsicHeight();
        a.recycle();
    }

//    View의 아이템보다 위에 그리고 싶을 때는 이쪽 메소드를 사용한다
//    @Override
//    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
//        super.onDrawOver(c, parent, state);
//    }


    // View의 아이템보다 아래에 그리고 싶을 때는 이쪽 메소드를 사용한다
    // 여기서는 RecyclerView의 아이템마다 아래에 선을 그린다
    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c, parent, state);
        // 좌우의 padding으로 선의 right과 left를 설정
        final int lineLeft = parent.getPaddingLeft();
        final int lineRight = parent.getWidth() - parent.getPaddingRight();

        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();

            // 애니메이션 등일 때에 제대로 이동하기 위해서
            int childTransitionY = Math.round(ViewCompat.getTranslationY(child));
            final int top = child.getBottom() + params.bottomMargin + childTransitionY;
            final int bottom = top + dividerHeight;

            // View 아래에 선을 그린다
            divider.setBounds(lineLeft, top, lineRight, bottom);
            divider.draw(c);
        }
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        // View 아래에 선이 들어가므로 아래에 Offset을 넣는다
        outRect.set(0, 0, 0, dividerHeight);
    }
}

 

addItemDecoration()을 호출합니다.

 recyclerView.addItemDecoration(new DividerItemDecoration(this));

 

 

 

 


드래그 앤드 드롭과 스와이프 구현

 

 

ItemTouchHelper 클래스를 이용하면 밀어서 삭제하거나 데이터를 이동할 수 있습니다. 이 클래스를 구현함으로써 드래그 앤드 드롭이나 스와이프 삭제가 가능해집니다.

private void setupRecyclerView() {
    recyclerView = (RecyclerView) findViewById(R.id.simple_recycler_view);

    // RecyclerView 자체의 크기가 변하지 않는 것을 알고 있을 때
    // 이 옵션을 지정해두면 성능이 개선된다
    recyclerView.setHasFixedSize(true);

    // Adapter를 설정한다
    simpleStringAdapter = new ManipulationSimpleStringAdapter(DummyDataGenerator.generateStringListData());
    recyclerView.setAdapter(simpleStringAdapter);

    // ItemTouchHelper클래스를 구현한다
    // 이에 따라 드래그앤드롭이나 스와이프로 삭제 등을 할 수 있게 된다.
    new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.RIGHT) {
        @Override
        public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
            // 드래그앤드롭 시
            simpleStringAdapter.move(viewHolder.getAdapterPosition(), target.getAdapterPosition());
            return true;
        }

        @Override
        public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
            // 아이템 스와이프 시
            simpleStringAdapter.removeAtPosition(viewHolder.getAdapterPosition());
        }
    }).attachToRecyclerView(recyclerView);
}

 

ItemTouchHelper의 생성자로 ItemTouchHelper.SimpleCallback을 구현한 인스턴스를 전달하기만 하면 됩니다. 첫 번째 인수로는 onMove()에서 이용할 방향(드래그하는 방향)을 전달하고, 두 번째 인수로는 onSwipe()에서 이용할 방향(스와이프하는 방향)을 전달합니다. 그리고 onMove() 메서드로 드래그 앤드 드롭했을 때의 처리 내용과 onSwiped() 메서드로 아이템을 스와이프했을 때의 처리 내용을 기술합니다.

반응형
Comments