본문 바로가기
안드로이드 자바

[JAVA][Android] 리사이클러뷰 접기, 펴기

by teamnova 2021. 11. 18.
728x90

오늘은 접었다 펼 수 있는 리사이클러뷰를 만들 거에요.

소스를 스틱코드에서 다운받고 본인의 앱에 맞게 수정해서 사용하세요.^^

https://stickode.com/detail.html?no=2579 

 

스틱코드

 

stickode.com

 

ItemData.java

-> 데이터의 값을 저장하는 클래스, 뷰에 보여주기 위해 필요한 데이터들을 하나의 클래스로 모아줘요.

public class ItemData {
    int image;
    String title;

    public ItemData(int image, String title){
        this.image = image;
        this.title = title;
    }

    public int getImage() {
        return image;
    }

    public void setImage(int image) {
        this.image = image;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}

 

OnViewHolderItemClickListener.java

-> 이벤트 리스너 생성

public interface OnViewHolderItemClickListener {
    void onViewHolderItemClick();
}

 

RecyclerVierAdapter.java

-> 데이터와 아이템에 대한 뷰를 생성해줍니다.


import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;

public class RecyclerVierAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    // adapter에 들어갈 list 입니다.
    private ArrayList<ItemData> listData = new ArrayList<>();

    // Item의 클릭 상태를 저장할 array 객체
    private SparseBooleanArray selectedItems = new SparseBooleanArray();
    // 직전에 클릭됐던 Item의 position
    private int prePosition = -1;


    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_movie, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
        ViewHolder viewHolder = (ViewHolder)holder;
        viewHolder.onBind(listData.get(position),position, selectedItems);
        // 뷰홀더에 아이템클릭리스너 인터페이스 붙이기
        viewHolder.setOnViewHolderItemClickListener(new OnViewHolderItemClickListener() {
            @Override
            public void onViewHolderItemClick() {
                if (selectedItems.get(position)) {
                    // 펼쳐진 Item을 클릭 시
                    selectedItems.delete(position);
                } else {
                    // 직전의 클릭됐던 Item의 클릭상태를 지움
                    selectedItems.delete(prePosition);
                    // 클릭한 Item의 position을 저장
                    selectedItems.put(position, true);
                }
                // 해당 포지션의 변화를 알림
                if (prePosition != -1) notifyItemChanged(prePosition);
                notifyItemChanged(position);
                // 클릭된 position 저장
                prePosition = position;
            }
        });
    }

    @Override
    public int getItemCount() {
        return listData.size();
    }

    void addItem(ItemData itemData) {
        // 외부에서 item을 추가시킬 함수입니다.
        listData.add(itemData);
    }
}

 

ViewHolder 구현

-> 데이터 값에 따라 변경되어 보여질 뷰

import android.animation.ValueAnimator;
import android.util.SparseBooleanArray;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

public class ViewHolder extends  RecyclerView.ViewHolder {

    TextView title;
    ImageView iv_1,iv_2;
    LinearLayout linearlayout;

    OnViewHolderItemClickListener onViewHolderItemClickListener;


    public ViewHolderMovie(@NonNull View itemView) {
        super(itemView);

        iv_1 = itemView.findViewById(R.id.iv_1);
        title = itemView.findViewById(R.id.title);
        iv_2 = itemView.findViewById(R.id.iv_2);
        linearlayout = itemView.findViewById(R.id.linearlayout);

        linearlayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onViewHolderItemClickListener.onViewHolderItemClick();
            }
        });
    }

    public void onBind(ItemData itemData, int position, SparseBooleanArray selectedItems){
        title.setText(itemData.getTitle());
        iv_1.setImageResource(itemData.getImage());
        iv_2.setImageResource(itemData.getImage());
        changeVisibility(selectedItems.get(position));
    }

    private void changeVisibility(final boolean isExpanded) {
        // ValueAnimator.ofInt(int... values)는 View가 변할 값을 지정, 인자는 int 배열
        ValueAnimator va = isExpanded ? ValueAnimator.ofInt(0, 600) : ValueAnimator.ofInt(600, 0);
        // Animation이 실행되는 시간, n/1000초
        va.setDuration(500);
        va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                // imageView의 높이 변경
                iv_2.getLayoutParams().height = (int) animation.getAnimatedValue();
                iv_2.requestLayout();
                // imageView가 실제로 사라지게하는 부분
                iv_2.setVisibility(isExpanded ? View.VISIBLE : View.GONE);
            }
        });
        // Animation start
        va.start();
    }

    public void setOnViewHolderItemClickListener(OnViewHolderItemClickListener onViewHolderItemClickListener) {
        this.onViewHolderItemClickListener = onViewHolderItemClickListener;
    }
}

 

MainActivity.java

-> 리사이클러뷰가 보여질 액티비티

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    RecyclerVierAdapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
        getData();

    }

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

        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(linearLayoutManager);

        adapter = new RecyclerVierAdapter();
        recyclerView.setAdapter(adapter);
    }

    private void getData(){
        ItemData itemData = new ItemData(R.drawable.aa, "a");
        adapter.addItem(itemData);
        itemData = new ItemData(R.drawable.bb, "b");
        adapter.addItem(itemData);
        itemData = new ItemData(R.drawable.cc, "c");
        adapter.addItem(itemData);
        itemData = new ItemData(R.drawable.dd, "d");
        adapter.addItem(itemData);
    }
}

 

activity_main.xml

<?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">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

 

item.xml

-> 리사이클러뷰 메뉴 하나에 들어갈 xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/linearlayout"
    android:orientation="vertical">


    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/iv_1"
            android:scaleType="centerCrop"
            android:layout_width="100dp"
            android:layout_height="80dp"/>

        <TextView
            android:padding="20dp"
            android:gravity="center"
            android:textSize="16dp"
            android:id="@+id/title"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

    </LinearLayout>

    <ImageView
        android:visibility="gone"
        android:id="@+id/iv_2"
        android:scaleType="centerCrop"
        android:layout_width="match_parent"
        android:layout_height="200dp"/>

</LinearLayout>

https://stickode.com/detail.html?no=2579 

 

스틱코드

 

stickode.com

 

결과 :