격자 형태로 쇼핑 상품을 보여주는 화면을 구성할 것이다. 상품을 클릭하면 해당 상품의 정보가 토스트 메시지로 나타난다.

 

1️⃣ xml 파일 만들기

activity_main.xml (좌) / shopping_item.xml (우)

🔸activity_main.xml 코드🔸

더보기
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="30dp"
        android:text="쇼핑상품"
        android:textSize="30sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginStart="20dp"
        android:layout_marginEnd="20dp"
        android:layout_marginBottom="20dp"
        android:background="@drawable/graystroke"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView">

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/RecyclerView"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginStart="30dp"
            android:layout_marginTop="30dp"
            android:layout_marginEnd="30dp"
            android:layout_marginBottom="30dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

🔸shopping_item.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"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="2dp"
    android:background="@drawable/blackstroke"
    android:orientation="vertical"
    android:padding="15dp">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="130dp"
        android:layout_height="150dp"
        app:srcCompat="@mipmap/ic_launcher" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="상품명"
        android:textSize="14sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="가격"
        android:textColor="#C31056C4"
        android:textSize="14sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/textView3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="상품설명"
        android:textSize="14sp" />

</LinearLayout>

2️⃣ 아이템의 정보가 담길 클래스 만들기

쇼핑 상품의 정보는 4가지이다. 상품명(name), 상품가격(price), 상품설명(description), 상품이미지(image)

여기서 상품이미지resId를 가져오는 것이므로, int형으로 선언한다. (나머지는 String 형)

🔸ShoppingItem.java🔸

더보기

생성자를 만든 뒤 getter and setter로 각 상품정보의 get, set 메서드를 자동으로 만들어준다.

package com.example.doitmission_14;

public class ShoppingItem {
    int image; //resId
    String name;
    String price;
    String descrpiton;

    public ShoppingItem(String name, String price, String descrpiton, int resId) {
        this.image = resId;
        this.descrpiton = descrpiton;
        this.name = name;
        this.price = price+"원";
    }

    public int getImage() {
        return image;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    public String getDescrpiton() {
        return descrpiton;
    }

    public void setDescrpiton(String descrpiton) {
        this.descrpiton = descrpiton;
    }
}

3️⃣ 어댑터 만들기

  • 쇼핑 어댑터 내부에 아이템(ShoppingItem 객체)이 담길 ArrayList를 만든다.
  • 쇼핑 어댑터 내부에 필수 메서드 3개를 생성한 뒤, 내부에 코드를 작성/수정 한다.
  • 쇼핑 어댑터 내부에 뷰홀더 클래스를 만들고, 그 안에 생성자랑 setItem 메서드를 생성한다.
  • 앳샛갯샛 메서드를 작성한다. (addItem, setItems, getItem, setItem)

🔸ShoppingAdapter.java🔸

더보기
package com.example.doitmission_14;

public class ShoppingAdapter extends RecyclerView.Adapter<ShoppingAdapter.ViewHolder>{
    ArrayList<ShoppingItem> items = new ArrayList<ShoppingItem>();

    static class ViewHolder extends RecyclerView.ViewHolder {
        TextView name, price, description;
        ImageView image;
        public ViewHolder(@NonNull View itemView, final OnShoppingItemClickListener listener) {
            super(itemView);
            image = itemView.findViewById(R.id.imageView);
            name = itemView.findViewById(R.id.textView);
            price = itemView.findViewById(R.id.textView2);
            description = itemView.findViewById(R.id.textView3);
        }

        public void setItem(ShoppingItem item){
            image.setImageResource(item.getImage());
            name.setText(item.getName());
            price.setText(item.getPrice());
            description.setText(item.getDescrpiton());
        }
    }

    @NonNull
    @Override
    public ShoppingAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View itemView = inflater.inflate(R.layout.shopping_item, parent, false);
        return new ViewHolder(itemView, this);
    }

    @Override
    public void onBindViewHolder(@NonNull ShoppingAdapter.ViewHolder holder, int position) {
        ShoppingItem item = items.get(position);
        holder.setItem(item);
    }

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

    public void addItem(ShoppingItem item){
        items.add(item);
    }
    public void setItems(ArrayList<ShoppingItem> items){
        this.items = items;
    }
    public ShoppingItem getItem(int position){
        return items.get(position);
    }
    public void setItem(int position, ShoppingItem item){
        items.set(position, item);
    }

}

4️⃣ 인터페이스 만들기

상품을 클릭할 시 mainActivity에서 작성한 어떠한 동작이 가능하도록 설정한다.

  • 리스너를 생성한다.
  • 어댑터 수정 : 어댑터가 리스너를 상속하도록 한다.
  • 어댑터 수정 : 상속 후 생성되어야 할 필수 메서드를 생성한다.
  • 어댑터 수정 : 새로 만든 리스너 객체를 생성한다.
  • 어댑터 수정 : 뷰 클릭 시 해당 위치를 읽어와 그 뷰의 정보를 리스너에 담는다.

🔸OnShoppingItemClickListener.java🔸

더보기
package com.example.doitmission_14;

public interface OnShoppingItemClickListener {
    public void onItemClick(ShoppingAdapter.ViewHolder holder, View view,int position);
}

🔸ShoppingAdapter.java🔸

더보기

어댑터에 의해 ViewHolder의 파라미터의 개수가 바뀌므로 수정해준다.

package com.example.doitmission_14;

public class ShoppingAdapter extends RecyclerView.Adapter<ShoppingAdapter.ViewHolder>
                             implements OnShoppingItemClickListener{
    ArrayList<ShoppingItem> items = new ArrayList<ShoppingItem>();
    OnShoppingItemClickListener listener;

    public void setOnItemClickListener(OnShoppingItemClickListener listener){
        this.listener = listener;
    }

    @Override
    public void onItemClick(ViewHolder holder, View view, int position) {
        if(listener!=null)
            listener.onItemClick(holder, view, position);
    }

    static class ViewHolder extends RecyclerView.ViewHolder {
        TextView name, price, description;
        ImageView image;
        public ViewHolder(@NonNull View itemView, final OnShoppingItemClickListener listener) {
            super(itemView);
            image = itemView.findViewById(R.id.imageView);
            name = itemView.findViewById(R.id.textView);
            price = itemView.findViewById(R.id.textView2);
            description = itemView.findViewById(R.id.textView3);

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    int position = getAdapterPosition();
                    if(listener!=null){
                        listener.onItemClick(ViewHolder.this, view, position);
                    }
                }
            });
        }

        public void setItem(ShoppingItem item){
            image.setImageResource(item.getImage());
            name.setText(item.getName());
            price.setText(item.getPrice());
            description.setText(item.getDescrpiton());
        }
    }

    @NonNull
    @Override
    public ShoppingAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View itemView = inflater.inflate(R.layout.shopping_item, parent, false);
        return new ViewHolder(itemView, this);
    }

    @Override
    public void onBindViewHolder(@NonNull ShoppingAdapter.ViewHolder holder, int position) {
        ShoppingItem item = items.get(position);
        holder.setItem(item);
    }

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

    public void addItem(ShoppingItem item){
        items.add(item);
    }
    public void setItems(ArrayList<ShoppingItem> items){
        this.items = items;
    }
    public ShoppingItem getItem(int position){
        return items.get(position);
    }
    public void setItem(int position, ShoppingItem item){
        items.set(position, item);
    }

}

5️⃣ MainActivity 작성하기

  • 어댑터에 상품 정보들을 추가한다.
  • 어댑터에 작성했던 리스너를 사용하여, 상품 클릭 시 해당 상품의 정보를 토스트메시지로 띄운다.

🔸MainActivity.java🔸

더보기
package com.example.doitmission_14;

public class MainActivity extends AppCompatActivity {

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

        RecyclerView recyclerView = findViewById(R.id.RecyclerView);
        ShoppingAdapter adapter = new ShoppingAdapter();

        GridLayoutManager layoutManager = new GridLayoutManager(this, 2);
        recyclerView.setLayoutManager(layoutManager);

        adapter.setOnItemClickListener(new OnShoppingItemClickListener() {
            @Override
            public void onItemClick(ShoppingAdapter.ViewHolder holder, View view, int position) {
                ShoppingItem item = adapter.getItem(position);
                String n,p,d;
                n=item.getName().toString();
                p=item.getPrice().toString();
                d=item.getDescrpiton().toString();
                Toast.makeText(getApplicationContext(), "이름:"+n+", 가격:"+p+", 설명:"+d, Toast.LENGTH_LONG).show();
            }
        });

        adapter.addItem(new ShoppingItem("롱코트","160,000","명절 기획상품...",R.drawable.longcoat));
        adapter.addItem(new ShoppingItem("방탄 와이셔츠","80,000","특가상품...",R.drawable.shirt));
        adapter.addItem(new ShoppingItem("조깅화","220,000","반값상품...",R.drawable.shoes));
        adapter.addItem(new ShoppingItem("선글라스","500,000","비싼상품...",R.drawable.sunglasses));
        recyclerView.setAdapter(adapter);
    }
}

위에서 나왔듯이 이미지는 resId 값을 넣어준다.

6️⃣ 실행결과

 

🔹실패한 스크린샷🔹

더보기

 

아이템이 담기는 뷰를 만드는 것도 은근 까다로운 일이다.

그나저나 왠지 인터넷 돌아다니다가 한번씩 본 느낌이라서 좀 킹받음

'TIL > 안드로이드 스튜디오' 카테고리의 다른 글

8장 - 페이징 슬라이딩  (0) 2025.01.18
8장 - 애니메이션  (0) 2025.01.18
도전!13 - 리싸이클러뷰에 고객 정보 추가하기  (0) 2025.01.15
7장 - 스피너🔻  (0) 2025.01.14
7장 - 리싸이클러뷰  (0) 2025.01.14