728x90
안녕하세요! 많은 어플리케이션에서 상위 카테고리를 클릭하면 해당 카테고리에 해당하는 아이템만 보여줄 수 있도록 동작하는 리사이클러뷰들을 자주 찾아볼 수있는데요, 오늘은 두개의 리사이클러뷰 컴포넌트를 사용하여 어떻게 아래와 같이 구현할 수 있는지 알아봅시다.
우선 레이아웃 xml 파일입니다. 리사이클러뷰 두개가 있는 것을 확인할 수 있습니다. 저는 각각 staticRv, dynamicRv라고 아이디 값을 지정해주었습니다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/staticRv"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/dynamicRv"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
리사이클러뷰에 사용할 아이템 클래스도 생성해주었습니다.
public class RvItem {
int staticRvImg;
String staticRvStr;
public RvItem(int staticRvImg, String staticRvStr) {
this.staticRvImg = staticRvImg;
this.staticRvStr = staticRvStr;
}
public int getRvImg() {return staticRvImg;}
public String getRvStr() {return staticRvStr;}
//setter는 사용하지않아 generate 하지않음.
}
우선 상위 리사이클러뷰 아이템 클릭 시 하위 리사이클러뷰가 함께 움직일 수 있도록 도와주는 리스너를 생성합니다. 파라미터로는 하위 리사이클러뷰에 적용시킬 어레이리스트를 받습니다.
public interface UpdateRvListener {
void onUpdateDynamicRv(ArrayList<RvItem> list);
}
이제 카테고리 부분에 해당하는 상위 리사이클러뷰 컴포넌트의 어댑터 클래스를 생성해줍니다. (StaticAdapter)
public class StaticAdapter extends RecyclerView.Adapter<StaticAdapter.StaticViewHolder>{
ArrayList<RvItem> arrayList;
ArrayList<RvItem> dynamicArrayList = new ArrayList<>();//하위리사이클러뷰에 넘겨줄 어레이리스트
UpdateRvListener mListener;//하위 리사이클러뷰 업데이트를 위한 리스너
int index = -1;//첫클릭을 파악하기 위해 -1값 사용. 이후 포지션 값
public StaticAdapter(ArrayList<RvItem> arrayList, UpdateRvListener mListener) {
this.arrayList = arrayList;
this.mListener = mListener;
}
@NonNull
@Override
public StaticAdapter.StaticViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new StaticViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.static_frame,parent,false));
}
@Override
public void onBindViewHolder(@NonNull StaticAdapter.StaticViewHolder holder,
@SuppressLint("RecyclerView") int position) {
RvItem staticRvItem = arrayList.get(position);
holder.staticRvImg.setImageResource(staticRvItem.getRvImg());
holder.staticRvStr.setText(staticRvItem.getRvStr());
if(index==-1){
callItems(0);//미클릭 상태에서 아이템 표기
}
holder.itemView.setOnClickListener(new View.OnClickListener() {
@SuppressLint("NotifyDataSetChanged")
@Override
public void onClick(View v) {
//첫클릭 시 -1 >> position 값으로 변화
index = position;
notifyDataSetChanged();
callItems(position);
}
});
if(index==position){
//선택된 아이템은 글씨색상 purple_500으로
holder.staticRvStr.setTextColor(holder.itemView.getContext().getColor(R.color.purple_500));
}else{
//미선택 아이템은 black으로 글씨가 보여지도록하기.
holder.staticRvStr.setTextColor(holder.itemView.getContext().getColor(R.color.black));
}
}
@Override
public int getItemCount() {
return arrayList.size();
}
public class StaticViewHolder extends RecyclerView.ViewHolder {
ImageView staticRvImg;
TextView staticRvStr;
public StaticViewHolder(@NonNull View itemView) {
super(itemView);
staticRvImg = itemView.findViewById(R.id.staticRvImg);
staticRvStr = itemView.findViewById(R.id.staticRvStr);
}
}
//포지션에 따라 아이템을 불러오는 함수
public void callItems(int position){
if(dynamicArrayList.size()>0){
dynamicArrayList.clear();
}
if(position==0){//과일
dynamicArrayList.add(new RvItem(R.drawable.pineapple,"과일1"));
dynamicArrayList.add(new RvItem(R.drawable.pineapple,"과일2"));
dynamicArrayList.add(new RvItem(R.drawable.pineapple,"과일3"));
dynamicArrayList.add(new RvItem(R.drawable.pineapple,"과일4"));
dynamicArrayList.add(new RvItem(R.drawable.pineapple,"과일5"));
dynamicArrayList.add(new RvItem(R.drawable.pineapple,"과일6"));
}else if(position==1){//채소
dynamicArrayList.add(new RvItem(R.drawable.radish,"채소1"));
dynamicArrayList.add(new RvItem(R.drawable.radish,"채소2"));
dynamicArrayList.add(new RvItem(R.drawable.radish,"채소3"));
dynamicArrayList.add(new RvItem(R.drawable.radish,"채소4"));
dynamicArrayList.add(new RvItem(R.drawable.radish,"채소5"));
dynamicArrayList.add(new RvItem(R.drawable.radish,"채소6"));
}else if(position==2){//육류
dynamicArrayList.add(new RvItem(R.drawable.meat,"육류1"));
dynamicArrayList.add(new RvItem(R.drawable.meat,"육류2"));
dynamicArrayList.add(new RvItem(R.drawable.meat,"육류3"));
dynamicArrayList.add(new RvItem(R.drawable.meat,"육류4"));
dynamicArrayList.add(new RvItem(R.drawable.meat,"육류5"));
dynamicArrayList.add(new RvItem(R.drawable.meat,"육류6"));
}else{//생선
dynamicArrayList.add(new RvItem(R.drawable.salmon,"생선1"));
dynamicArrayList.add(new RvItem(R.drawable.salmon,"생선2"));
dynamicArrayList.add(new RvItem(R.drawable.salmon,"생선3"));
dynamicArrayList.add(new RvItem(R.drawable.salmon,"생선4"));
dynamicArrayList.add(new RvItem(R.drawable.salmon,"생선5"));
dynamicArrayList.add(new RvItem(R.drawable.salmon,"생선6"));
}
if(mListener!= null){
mListener.onUpdateDynamicRv(dynamicArrayList);
}
}
}
파라미터로 받은 어레이리스트를 하위 리사이클러뷰에 적용해줄 하위 리사이클러뷰 어댑터 클래스도 생성해줍니다. (DynamicAdapter)
public class DynamicAdapter extends RecyclerView.Adapter<DynamicAdapter.DynamicViewHolder>{
ArrayList<RvItem> dynamicArrayList;
public DynamicAdapter(ArrayList<RvItem> dynamicArrayList) {
this.dynamicArrayList = dynamicArrayList;
}
@NonNull
@Override
public DynamicAdapter.DynamicViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new DynamicViewHolder(LayoutInflater.from(parent.getContext())
.inflate(R.layout.dynamic_frame,parent,false));
}
@Override
public void onBindViewHolder(@NonNull DynamicAdapter.DynamicViewHolder holder, int position) {
RvItem dynamicRvItem = dynamicArrayList.get(position);
holder.dynamicRvImg.setImageResource(dynamicRvItem.getRvImg());
holder.dynamicRvStr.setText(dynamicRvItem.getRvStr());
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(holder.itemView.getContext(),
dynamicRvItem.getRvStr()+"가 클릭되었습니다",
Toast.LENGTH_SHORT).show();
}
});
}
@Override
public int getItemCount() {
return dynamicArrayList.size();
}
public class DynamicViewHolder extends RecyclerView.ViewHolder {
ImageView dynamicRvImg;
TextView dynamicRvStr;
public DynamicViewHolder(@NonNull View itemView) {
super(itemView);
dynamicRvImg = itemView.findViewById(R.id.dynamicRvImg);
dynamicRvStr = itemView.findViewById(R.id.dynamicRvStr);
}
}
}
이제 어댑터들과 리사이클러뷰들을 서로 연결해주고 리스너 동작을 구현해줍시다.
public class MainActivity extends AppCompatActivity {
private RecyclerView dynamicRv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView staticRv = findViewById(R.id.staticRv);
dynamicRv = findViewById(R.id.dynamicRv);
//리사이클러뷰 리니어레이아웃매니저 세팅
//staticRv 부분은 가로로 되어있기 때문에 두번째 파라미터 값을 Horizontal 로 주기.
staticRv.setLayoutManager(new LinearLayoutManager(this,RecyclerView.HORIZONTAL,false));
dynamicRv.setLayoutManager(new LinearLayoutManager(this,RecyclerView.VERTICAL,false));
//리사이클러뷰 크기가 고정되어있음을 안드로이드에 알려 레이아웃을 다시 그리는 작업을 피하게 해주기.
//setHasFixedItemSize(false)인 경우 >리사이클러뷰의 아이템이 들어오거나 나갈 때마다 RecyclerView 전체의 레이아웃을 다시 그려준다.
staticRv.setHasFixedSize(true);
dynamicRv.setHasFixedSize(true);
final ArrayList<RvItem> rvItems = new ArrayList<>();
rvItems.add(new RvItem(R.drawable.pineapple,"과일"));
rvItems.add(new RvItem(R.drawable.radish,"채소"));
rvItems.add(new RvItem(R.drawable.meat,"육류"));
rvItems.add(new RvItem(R.drawable.salmon,"생선"));
//staticAdapter 생성
StaticAdapter staticAdapter = new StaticAdapter(rvItems, new UpdateRvListener() {
@SuppressLint("NotifyDataSetChanged")
@Override
public void onUpdateDynamicRv(ArrayList<RvItem> list) {
DynamicAdapter adapter = new DynamicAdapter(list);
dynamicRv.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
});
//staticAdapter 세팅하기.
staticRv.setAdapter(staticAdapter);
}
}
이렇게 위에 보이는 형식의 리사이클러뷰를 구현해보았습니다.
'안드로이드 자바' 카테고리의 다른 글
[Android][Java]RecyclerView-Selection 라이브러리 사용 (0) | 2022.12.22 |
---|---|
[Java][Android] Wear(웨어러블) 앱 프로젝트 만들어보기 (0) | 2022.12.10 |
[Java][Android] 네이버 지도 - 숫자 마커 만들기(롱클릭 이벤트) (0) | 2022.12.05 |
[Android/안드로이드] 키보드 화면조정 (0) | 2022.12.04 |
[Java][Android] AutoFitTextView 사용하기 (0) | 2022.11.27 |