KUSITMS/학술제

[안드로이드 스튜디오] 앨범에서 선택 후 RecyclerView로 보여주기

gom1n 2021. 11. 30. 01:31

이미지를 선택하면,

앨범으로 이동 후 사진(여러개 가능)을 선택하고,

다시 돌아왔을 때에 화면에 있던 recyclerview에 사진들을 보여주게끔 하였다.

번외로 선택된 사진들 갯수도 출력하였다.

 

우선 onCreate 안에 클릭이벤트앨범으로 이동시키는 코드

// 이미지 업로드
selectedImageRecyclerView = (RecyclerView) findViewById(R.id.selectedImageRecyclerView);	//이미지를 출력시킬 recylcerview
selectedImageCount = (TextView) findViewById(R.id.selectedImageCount);	//이미지 갯수
ImageView chooseImage = (ImageView) findViewById(R.id.chooseImage);
chooseImage.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // 앨범으로 이동
            Intent intent = new Intent(Intent.ACTION_PICK);
            intent.setType(MediaStore.Images.Media.CONTENT_TYPE);
            intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); //다중 이미지를 가져올 수 있도록
            intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            startActivityForResult(intent, 2222);
        }
    });

 

이때, recyclerView에 연결될 Adapter 클래스가 선언되어있어야 한다. uri를 통해 이미지뷰를 띄어줄 것이다.

MultiImageAdapter.class

import android.content.Context;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.Glide;
import com.example.auctionapp.R;

import java.util.ArrayList;

public class MultiImageAdapter extends RecyclerView.Adapter<MultiImageAdapter.ViewHolder>{
    private ArrayList<Uri> mData = null ;
    private Context mContext = null ;

    public MultiImageAdapter(ArrayList<Uri> list, Context context) {
        mData = list ;
        mContext = context;
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        ImageView selectedImage;

        ViewHolder(View itemView) {
            super(itemView) ;
            // 뷰 객체에 대한 참조.
            selectedImage = itemView.findViewById(R.id.selectedImage);
        }
    }

    @Override
    public MultiImageAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Context context = parent.getContext() ;
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) ;    // context에서 LayoutInflater 객체를 얻는다.
        View view = inflater.inflate(R.layout.choosing_item_image, parent, false) ;	// 리사이클러뷰에 들어갈 아이템뷰의 레이아웃을 inflate.
        MultiImageAdapter.ViewHolder vh = new MultiImageAdapter.ViewHolder(view) ;

        return vh ;
    }

    // onBindViewHolder() - position에 해당하는 데이터를 뷰홀더의 아이템뷰에 표시.
    @Override
    public void onBindViewHolder(MultiImageAdapter.ViewHolder holder, int position) {
        Uri image_uri = mData.get(position) ;

        Glide.with(mContext)
                .load(image_uri)
                .into(holder.selectedImage);
    }

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

}

 

 

다시 메인 액티비티로 돌아가, 앨범 선택 시 호출되는 onActivityResult 함수를 override한다.

@Override onActivityResult

// select image
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    //uriList.clear();    // 이미지 다시 선택 시 초기화
    uriList = new ArrayList<>();
    fileList = new ArrayList<>();
    if(requestCode == 2222){
        if(data == null){   // 어떤 이미지도 선택하지 않은 경우
            Toast.makeText(getApplicationContext(), "이미지를 선택하지 않았습니다.", Toast.LENGTH_LONG).show();
        }
        else{   // 이미지를 하나라도 선택한 경우
            if(data.getClipData() == null){     // 이미지를 하나만 선택한 경우
                Log.e("single choice: ", String.valueOf(data.getData()));
                selectedImageCount.setText("1/10");
                Uri imageUri = data.getData();
                uriList.add(imageUri);
                String imagePath = getRealpath(imageUri);
                File destFile = new File(imagePath);
                fileList.add(destFile);
                adapter = new MultiImageAdapter(uriList, getApplicationContext());
                selectedImageRecyclerView.setAdapter(adapter);
                selectedImageRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, true));
            }
            else{      // 이미지를 여러장 선택한 경우
                ClipData clipData = data.getClipData();
                selectedImageCount.setText(String.valueOf(clipData.getItemCount()) + "/10");

                if(clipData.getItemCount() > 10){   // 선택한 이미지가 11장 이상인 경우
                    Toast.makeText(getApplicationContext(), "사진은 10장까지 선택 가능합니다.", Toast.LENGTH_LONG).show();
                }
                else{   // 선택한 이미지가 1장 이상 10장 이하인 경우
                    Log.e(TAG, "multiple choice");

                    for (int i = 0; i < clipData.getItemCount(); i++){
                        Uri imageUri = clipData.getItemAt(i).getUri();  // 선택한 이미지들의 uri를 가져온다.
                        try {
                        	uriList.add(imageUri);  //uri를 list에 담는다.
                            String imagePath = getRealpath(imageUri);
                            File destFile = new File(imagePath);
                            fileList.add(destFile);
                        } catch (Exception e) {
                            Log.e(TAG, "File select error", e);
                        }
                    }
                    adapter = new MultiImageAdapter(uriList, getApplicationContext());
                    selectedImageRecyclerView.setAdapter(adapter);   // 리사이클러뷰에 어댑터 세팅
                    selectedImageRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, true));     // 리사이클러뷰 수평 스크롤 적용
                }
            }
        }
    }
}

uriList라는 ArrayList를 생성해 그 안에 선택된 이미지파일의 절대경로uri를 넣는다. 

(FileList는 나중에 레트로핏으로 서버에 넣어주기 위해 사용되는 것임)

10개 이하의 파일만 선택되도록 한다. (임의로)

그 다음, adapter를 활용해 recyclerView에 uriList로 사진들을 보여준다.

 

결과) 사진 선택 전 -> 선택 중 -> 선택 후 출력