리싸이클러뷰
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
순서 바꾸기 적용
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
https://black-jin0427.tistory.com/101?category=727620
https://black-jin0427.tistory.com/102?category=727620
'안드로이드 > Android View' 카테고리의 다른 글
[Android] 뷰페이저안에 웹뷰안에 뷰페이저 (0) | 2022.12.14 |
---|---|
스크롤 중복시 or 터치 우선순위 관리 (0) | 2022.11.09 |
[Android] DrawerLayout 숨겨있다가 액션 취하면 나타나는 기능 (0) | 2022.11.04 |
[Android] Coordinatorlayout에 대해 알아보자 (0) | 2022.11.04 |
[Android] Elevation (그림자 효과) (0) | 2022.10.27 |