마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

이미지뷰 정렬 구현하기?

0 추천
imageView.setImageResource(0);
imageview.setVisibility(View.INVISIBLE);

 

저런식으로 어떤 경우일 때 이미지를 없애는걸 구현하고 있는데 이미지 여러개 가지구요!

 

만약 4개 이미지가 있다면 1,2,4번만 보여주고 3번이 없어진다는 가정이면 124번 이미지가 3번 이미지 공백없이 순서대로 나오게 하려면 어떻게 해야하나요? 위에 코드처럼 null로 하면 3번 이미지가 공백으로 있어서 12번 이미지 띄고 4번 이미지가 나와서요!

enerigpy (2,110 포인트) 님이 2023년 2월 14일 질문

2개의 답변

+1 추천
 
채택된 답변

이미지 갯수가 많다면 RecyclerView, 몇 개정도라면 LinearLayout, GridLayout같은 ViewGroup에 보여줄 이미지 리스트를 ImageView를 동적으로 생성해서 추가하는 방법은 어떨까요?

아래와 같은 식으로 보여줄 이미지 리스트만 가지고 화면에 보여주면 될 것 같은데요.

List<Integer> allImageResources = getAllImageResources();

List<Integer> visibleImageResources = new ArrayList();
for (int resId : allImageResources) {
     if (someCondition()) {
         visibleImageResources.add(resId);
     }
}

recyclerViewAdapter.setData(visibleImageResources);

 

spark (227,830 포인트) 님이 2023년 2월 14일 답변
enerigpy님이 2023년 2월 14일 채택됨
하나더 질문할게요! 그럼 이미지뷰를 하나씩 추가하는 형식이면 각 이미지 안에 체크버튼을 넣으려고 하는데 그건 어떻게 구현해야할까요?
각각의 이미뷰자리에 아래와 같은 레이아웃을 사용하세요. LinearLayout 대신 다른 layout이 필요하면 사용하시구요.
 <LinearLayout>
   <ImageView />
   <Checkbox />
</LinearLayout>
그리고 이미지 리스트도 단순히 리소스ID 가 아닌 위의 구조를 반영할 수 있도록 해야겠죠.
예를 들면,
public class ImageInfo {
    private final int drawableid;
    private final boolean checked;
  
    // consturctor, getter 추가
}

List<ImageInfo> allImages = getAllImages();

List<ImageInfo> ...
네 저런식으로 구현하여 dataList가 이미지와 버튼을 반환하고 list.add 하는데요. 그럼 여기서 버튼 하나를 추가한 레이아웃일 경우 각각의 버튼 id는 어떻게 알수있나요? Button으로 부여하여 리스트로 정의할 수 없는거 같아서요!
해당 레이아웃을 직접 액티비티 레이아웃 안에 추가하시면 일일이 뷰를 찾아야하고 컨트롤이 복잡해 집니다. 구현이 쉽도록 RecyclerView를 사용해 보세요.
네 리사이클러뷰에서 구현하고 레이아웃에 이미지와 버튼 하나만 넣고 그거를 동적으로 add 하는거로 짰는데 하나씩 추가되었을 때 그것들의 id(?)는 어떻게 찾는건지 궁금해서요!
0 추천

뷰홀더에 있는 뷰에 이벤트(Click등)를 설정하시려는 건가요?
RecyclerView를 사용할 때는 직접 뷰홀더에 접근하지 않고 모든 처리를 어댑터를 통하여 하게 됩니다. 뷰홀더에 있는 버튼에 OnClickListener를 설정하려고 한다면, 이 또한 어댑터를 통하여 처리하시면 됩니다. 아래 코들 참고하세요.

public class ImageAdapter extends RecyclerView.Adapter<ImageViewHolder> {
    private static final String TAG = "CustomAdapter";

    private List<ImageInfo> mDataSet = new ArrayList<>();

    interface Listener {
        void onImageChecked(ImageInfo imageInfo);
    }

    private Listener mListener;
 
    public ImageAdapter(List<ImageInfo> dataSet, Listner listener) {
        mDataSet = dataSet;
        mListener = listener;
    }

    public void setData(List<ImageInfo> dataSet) {
        mDataSet = dataSet;
        notifyDataSetChanged();
    }

    public void setListener(Listener listener) {
        this.mListener = listener;
    }

    @Override
    public ImageViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        View v = LayoutInflater.from(viewGroup.getContext())
                .inflate(R.layout.row_item, viewGroup, false);
        return new ViewHolder(v, listener);
    }

    @Override
    public void onBindViewHolder(ImageViewHolder viewHolder, final int position) {
        viewHolder.bind(getItem(position);
    }
    
    private ImageInfo getItem(int position) {
         return mDataSet.get(position);
    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return mDataSet.length;
    }
}

public static class ImageViewHolder extends RecyclerView.ViewHolder {
        private final ImageView imageView;
        private final Checkbox checkBox;
        private final Listener listener;

        public ViewHolder(View v, Listener listener) {
            super(v);
            imageView = v.findViewById(R.id.imageView);
            button = v.findViewById(R.id.button);
            this.listener = listener;
        }

        public void bind(Imageinfo data) {
            imageView.setImageResource(data.getDrawableId());
            checkBox.setChecked(data.isChecked());
            checkBox.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                      if (listener != null) listener.onImageChecked(data)
                }
            });
        }
    }

어댑터에 리스너를 설정하는 코드는 어댑터를 사용하는 액비티티/프래그먼트에서 해줍니다.

//  Activity

private ImageAdapter imageAdapter;


public void onCreate(...) {
   super.onCreate(...);

   imageAdapter = new ImageAdapter(getImageData(), new ImageAdapter.Listener() {
        @Override
        public void onImageChecked(ImageInfo imageInfo) {
            // Do something()
        } 
   }
   recyclerView.setAdapter(imageAdapter);
}

private void refreshWithVisbleImges(List<ImageInfo> data) {
     imageAdapter.setDataSet(data);
}

 

spark (227,830 포인트) 님이 2023년 2월 15일 답변
아네 혹시 아이템 리스트 이미지를 불러올 때 동그라미 안에 이미지가 삽입되는데 이거는 어떻게 고쳐야할까요? 배경도 검은색으로 나옵니다.

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

main은 위에꺼로 정의하고 아이템 리스트 이미지는 아래처럼 했구요

<?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:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="4dp">

    <ImageView
        android:id="@+id/image"
        android:layout_width="282dp"
        android:layout_height="90dp"
        android:layout_marginTop="16dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
동그라미 안에 이미지가 삽입될 것 처럼 보이지는 않는데요. 혹 이미지를 Circle shape으로 만들고 싶으신 거라면, Circle 모양의 배경을 사용해도 될 것 같고, 효율적인 이미지 로딩등 여러가지를 고려하면 일반적으로 Glide같은 범용라이브러리를 사용해서 처리하는게 골치가 덜 안픕니다. Glide에 필요한 기능이 있습니다.
추가된 질문들이 본 질문에서 조금씩 벗어나는 질문이 되가고 있어서 추가적인 질문은 별도의 질문으로 올리시면 좋을 것 같네요.
아 원형으로 바꾸는 코드가 있었는데 눈에 보이지 않았네요. 해결했습니다!
...