안드로이드/Android View

리싸이클러뷰 기초

코딩하는후운 2022. 11. 4. 16:12
반응형

리싸이클러뷰
0.package준비
1)adapter
2)data
3)model
4)layout - activity.xml, item.xml

1.app단계의 build.gradle 추가

implementation 'com.android.support:appcompat-v7:28.0.0-rc02'
implementation "com.android.support:recyclerview-v7:28.0.0-rc02"
implementation "com.android.support:cardview-v7:28.0.0-rc02"

implementation "com.github.bumptech.glide:glide:3.7.0"


recyclerView, cardView, glide3가지 라이브러리를 추가해 줍니다.
이때 recycerView, cardView의 버전'28.0.0-rc02'는 본인의 support:appcompat-v7의 버전과 동일하게 설정해 줍니다.


2.인터넷 접근 권한 설정

3. activity_main.xml, item_movie.xml을 준비해줍니다.

<android.support.v7.widget.RecyclerView
  android:id="@+id/recyclerView"
  android:layout_width="match_parent"
  abndoid:layout_height="wrap_content"/>


 넣을 뷰

<android.support.v7.widget.CardView
  android:id="@+id/itemParent"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  app:cardCornerRadius="4dp"
  app:cardUseCompatPadding="true"
  app:cardElevation="4dp">
</android.support.v7.widget.CardView>




4. Movie데이터를 저장할 객체를 생성해 줍니다.

public class Movie{
  private String url;
  private String genre;

  public Movie(String url, String genere){
    this.url = url;
    this.genere = genere;
  }
}



5.Adapter를 생성해 줍니다.

public class MovieAdapter extends RecyclerView.Adapter<MoviewAdapter.Viewholder>{
  private ArrayList<Movie> items = new ArrayList<>();

  @NonNull
  @Override
  public MovieAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int i){
    View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_movie, parent, false);
    ViewHolder viewHolder = new ViewHolder(itemView);
    return viewholder;
  }

  @Override
  public void onBindViewHolder(@NonNull MovieAdapter.ViewHolder viewHolder, int position){
    Movie item = items.get(position);
    Glide.with(viewHolder.itemView.getContext())
        .load(item.getUrl())
        .into(viewHolder.ivMovie);

    viewHolder.뷰.셋팅
  }

  @override
  public int getItemCount(){
    return items.size();
  }

  public void setItems(ArrayList<Movie> items){
    this.items = items
  }

  class ViewHolder extends RecyclerView.ViewHolder{
    ImageView ivMovie;
    Textview tvTitle;

    ViewHolder(View itemView){
      super(itemView);

      ivMovie = itemView.findViewById(R.id.ivMovie);

    }
  }
}



6.샘플 데이터를 생성

public class SampleData{
  ArrayList<Movie> items = new ArrayList<>();

  public ArrayList<Moview> getItems(){
    Movie movie = new Moview("데이터");

    items.add(movie)
    items.add(movie)
    .
    .
    return items;
  }
}



7.MainActivity에서 뷰 초기화 및 어댑터를 연결해 줍니다.

//recyclerView 초기화
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);

//아이템 로드
adapter.setItems(new SampleData().getItems());

 


RecyclerView 레이아웃 매니저 종류

 

4가지 LayoutManager

//불규칙 레이아웃
StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);

//그리드 레이아웃
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 2);

//가로 레이아웃
LinearLayoutManager horizontalLayoutManager = new LinearLayoutManager(this, LinearLayout.HORIZONTAL, false);

//세로 레이아웃
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);

//레이아웃 매니저 연결
recycerView.setLayoutManager(linearLayoutManager);


4.불규칙 레이아웃
핀터레스트와 같은 화면을 구성할 수 있습니다.
아이템의 높이에 따라 불규칙 적으로 타일을 배치합니다.
그리드 레이아웃과 마찬가지로 spanCount를 제어할 수 있습니다.

public StaggeredGridLayoutManager(int spanCount, int orientation){
  this.mOrientation = orientation;
  this.setSpanCount(spanCount);
  this.mLayoutState = new LayoutState();
  this.createOrientationHelpers();
}

 


recyclerView 순서 바꾸기

https://fullstatck.tistory.com/15

 

[Android] RecyclerView 에서 드래그앤드롭(drag&drop)과 스와이프(swpie&dismiss) 사용하기

안드로이드 RecyclerView에서 drag&drop과 swipe-to-dismiss를 구현한 예제는 많지만 View.OnDragListener를 이용한 경우가 많다. 이것은 예전 버전을 사용한 경우이고 새로운 API를 사용하거나 GestureDetector나..

fullstatck.tistory.com

 

순서 바꾸기 적용

 

1. ItemTouchHelper.Callback을 상속받은 클래스를 만든다.
1-1. clearView는 모든 이동이 끝나고 호출된다!!

public class QuickItemTouchHelperCallback extends ItemTouchHelper.Callback {

    public QuickItemTouchHelperCallback(OnItemMoveListener listener){
        itemMoveListener = listener;
    }

    @Override
    public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
        int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
        return makeMovementFlags(dragFlags, 0);
    }

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


    @Override
    public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
        super.clearView(recyclerView, viewHolder);
        itemMoveListener.onItemMoved();
    }




    @Override
    public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {

    }


    private final OnItemMoveListener itemMoveListener;

    public interface OnItemMoveListener {
        boolean onItemMove(int fromPosition, int toPosition);
        void onItemMoved();
    }
}


2. Adapter에서 OnItemMoveListener implement하기

override fun onItemMove(fromPosition: Int, toPosition: Int): Boolean {
    if (fromPosition < toPosition) {
        for(index in fromPosition until toPosition){
            Collections.swap(items, index, index + 1)
        }

    } else {
        for(index in toPosition downTo fromPosition){
            Collections.swap(items, index, index - 1)
        }
    }
    notifyItemMoved(fromPosition, toPosition)
    return true
}

override fun onItemMoved() {
    notifyDataSetChanged()
}



3. 액티비티에서 리사이클러뷰에 적용

rvRight.apply {
    layoutManager = LinearLayoutManager(this@QuickMenuActivity)
    itemAnimator = DefaultItemAnimator()

    val callback = QuickItemTouchHelperCallback(adapterRight)
    itemTouchHelper = ItemTouchHelper(callback)
    itemTouchHelper?.attachToRecyclerView(this)

    adapter = adapterRight
}

 


RecyclerView ItemDecoration

-리사이클러뷰에서 아이템 여백을 주는방법

1.ItemDecoration클래스를 만들어 줍니다.

public class MovieItemDecoration extends RecyclerView.ItemDecoration{
  private int size10;
  private int size5;

  public MovieItemDecoration(Context context){
    size10 = dpToPx(context, 10);
    size5 = dpToPx(context, 5);
  }

  //dp -> pixel단위로 변경
  private int dpTopx(Context context, int dp){
    return (int)TypedValue.applyDimension(TypeValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrix());
  }
}



아래 dpToPx함수는 dp 단위를 Pixel단위로 변경해주는 코드입니다.
코드를 통해 view사이즈에 변화를 주거나 여백을 설정해 줄 때는 위와 같이 Pixel단위로 변환해서 작업을 해줘야됩니다.
꼭 기억하세요!


2.getItemOffsets를 상속합니다.

@override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state){
  super.getItemOffsets(outRect, view, parent, state);

  int position = parent.getChildAdapterPosition(view);
  int itemCount = state.getItemCount();

  //상하 설정
  if(position == 0 || position == 1){
    //첫번째 줄 아이템
    outRect.top = size10;
    outRect.bottom = size10;
  }else{
    outRect.bottom = size10;
  }

  //spanIndex = 0 -> 왼쪽
  //spanIndex = 1 -> 오른쪽
  GridLayoutManager.LayoutParams lp = (GridLayoutManager.LayoutParams)view.getLayoutParams();
  int spanIndex = lp.getSpanIndex();

  if(spanIndex == 0){
    //왼쪽 아이템
    outRect.left = size10;
    outRect.right = size5;
  }else if(spanIndex == 1){
    //오른쪽 아이템
    outRect.left = size5;
    outRect.right = size10;
  }
}



getItemOffsets을 통해 recyclerView안에 있는 아이템에 여백을 설정해 줄 수 있습니다.

int position = parent.getChildAdapterPosition(view);
int itemCount = state.getItemCount();



position: 각 가이템의 포지션을 받아옵니다.
itemCount: 전체 아이템 개수를 받아옵니다.

GridLayoutManager.LayoutParams lp = (GridLayoutManager.LayoutParams)view.getLayoutParams();
int spanIndex = lp.getSpanIndex();


위 함수는 GridLayout혹은 StaggeredGridLayout에서만 받아올 수 있는 함수입니다.
spanCount=2일 때 SpanIndex가 0이면 왼쪽 아이템을 1이면 오른쪽 아이템을 나타냅니다.

outRect.top = size10;
outRect.right = size10;
outRect.bottom = size10;
outRect.left = size10;

위 함수들은 각각 상 우 하 좌에 여백을 설정해 줄 수 있는 코드입니다.


3. RecyclerView에 연결해 줍니다.
recyclerView.addItemDecoration(new MovieItemDecoration(this));

 

 

 

 

 

참조 :

https://black-jin0427.tistory.com/100?category=727620 

 

[Android, RecyclerView] 리사이클러 뷰 만들기

안녕하세요. 블랙진입니다. 이번 시간부터 안드로이드 리사이클러뷰에 관해 단계별로 포스팅을 하겠습니다. 그 첫번 째 시간으로 아래와 같은 리사이클러뷰를 만들어 보겠습니다. 0. package 준

black-jin0427.tistory.com

https://black-jin0427.tistory.com/101?category=727620 

 

[Android, RecyclerView] 리사이클러뷰 레이아웃 매니저 종류

안녕하세요. 블랙진입니다. 리사이클러뷰의 다양한 형태에 대해 포스팅 해보겠습니다. 이전 포스팅이였던 '리사이클러뷰 만들기' 예제를 사용했습니다. 4가지 LayoutManager 리사이클러뷰는 4가지

black-jin0427.tistory.com

https://black-jin0427.tistory.com/102?category=727620 

 

[Android, ItemDecoration] 리사이클러뷰에 아이템데코레이션 사용하기

안녕하세요. 블랙진입니다. 리사이클러뷰에서 아이템 여백을 주는 방법으로 ItemDecoration 을 사용하면 좀 더 유연하게 적용해 줄수 있습니다. 먼저 아래와 같은 그리드 레이아웃이 있습니다. 현

black-jin0427.tistory.com

 

반응형