삽질도사

[안드로이드] 뷰페이저2 (자바) 기본사용법 본문

안드로이드

[안드로이드] 뷰페이저2 (자바) 기본사용법

전성진블로그 2021. 4. 30. 19:17

뷰페이저2가 나왔고 리사이클러뷰만큼이나 많이 사용되지만 올라온 예제가 많이 없는 점이 사실입니다. (특히 자바)

뷰페이저2는 기본적으로 리사이클러뷰랑 사용방법이 거의 흡사합니다.

 

개인적으로 사용처는 게시물에 올라온 포멧을 전체화면으로 보려고 사용했을 때 필요한 예제입니다.

여러분 상황에 맞게 커스텀해서 사용하시면 되겠습니다.

 

결과물부터 보여드립죠

결과물

 

준비물: 

 

activity_formats_pager.xml (게시물의 사진을 누르면 도화지로 사용할 새로운 액티비티를 띄움)

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="@color/black"
    android:layout_height="match_parent"
    android:layout_width="match_parent">

<androidx.viewpager2.widget.ViewPager2

    android:id="@+id/formats_pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    />

</FrameLayout>

 

item_formats_pager.xml (뷰페이저2의 어댑터에 사용될 item)

<?xml version="1.0" encoding="utf-8"?>

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="@color/black"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.github.chrisbanes.photoview.PhotoView
        android:id="@+id/formats_imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:visibility="gone" />

    <com.google.android.exoplayer2.ui.PlayerView
        android:id="@+id/formats_exoPlayerView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="gone" />

</FrameLayout>

 

Formats_PagerAdapter (뷰페이저2 어댑터 사실상 리사이클러뷰랑 똑같음)

public class Formats_PagerAdapter extends RecyclerView.Adapter<Formats_PagerAdapter.PagerHolder> {
    private Boolean playWhenReady = true;
    private int currentWindow = 0;
    private Long playbackPosition = 0L;

    private ArrayList<String> formats;
    private Context context;
    private SimpleExoPlayer player;
    LayoutInflater inflater;

    public Formats_PagerAdapter(Context context, ArrayList<String> formats) {
            this.context = context;
            this.formats = formats;
            inflater = LayoutInflater.from(context);
        }

    public class PagerHolder extends RecyclerView.ViewHolder {
        PhotoView imageView;
        PlayerView playerView;
        public PagerHolder(@NonNull View itemView) { //뷰홀더에서 작업들 실행
            super(itemView);
            imageView = itemView.findViewById(R.id.formats_imageView);
            playerView = itemView.findViewById(R.id.formats_exoPlayerView);
        }
    }

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

    @Override
    public void onBindViewHolder(@NonNull PagerHolder holder, int position) {
        if(isVideo(formats.get(position))){
            holder.imageView.setVisibility(View.INVISIBLE);
            holder.playerView.setVisibility(View.VISIBLE);
            initializePlayer(holder.playerView,formats.get(position));
        }else{
            holder.imageView.setVisibility(View.VISIBLE);
            holder.playerView.setVisibility(View.INVISIBLE);
            releasePlayer(holder.playerView);
            Glide.with(context).load(formats.get(position)).transform(new CenterCrop()).thumbnail(0.4f).into(holder.imageView);
        }
    }

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

    //확장자가 비디오인지 이미지인지 확인
    private Boolean isVideo(String path) {
        String extension = getExtension(path);

//        if (extension.contains("mp4") || extension.contains("MP4") || extension.contains("MOV") || extension.contains("mov") || extension.contains("AVI") || extension.contains("avi") ||
//                extension.contains("MKV") || extension.contains("mkv") || extension.contains("WMV") || extension.contains("wmv") || extension.contains("TS") || extension.contains("ts") ||
//                extension.contains("TP") || extension.contains("tp") || extension.contains("FLV") || extension.contains("flv") || extension.contains("3GP") || extension.contains("3gp") ||
//                extension.contains("MPG") || extension.contains("mpg") || extension.contains("MPEG") || extension.contains("mpeg") || extension.contains("MPE") || extension.contains("mpe") ||
//                extension.contains("ASF") || extension.contains("asf") || extension.contains("ASX") || extension.contains("asx") || extension.contains("DAT") || extension.contains("dat") ||
//                extension.contains("RM") || extension.contains("rm"))
        if (extension.contains("mp4") || extension.contains("MP4") || extension.contains("MOV") || extension.contains("mov") || extension.contains("AVI") || extension.contains("avi") ||
                extension.contains("MKV") || extension.contains("mkv") || extension.contains("WMV") || extension.contains("wmv") || extension.contains("TS") || extension.contains("ts") ||
                extension.contains("TP") || extension.contains("tp") || extension.contains("FLV") || extension.contains("flv") || extension.contains("3GP") || extension.contains("3gp") ||
                extension.contains("MPG") || extension.contains("mpg") || extension.contains("MPEG") || extension.contains("mpeg") || extension.contains("MPE") || extension.contains("mpe") ||
                extension.contains("ASF") || extension.contains("asf") || extension.contains("ASX") || extension.contains("asx") || extension.contains("DAT") || extension.contains("dat") ||
                extension.contains("RM") || extension.contains("rm"))
        {
            return true;
        } else {
            return false;
        }
    }

    //확장자 나누기
    private String getExtension(String url) {
        return url.substring(url.lastIndexOf(".") + 1, url.lastIndexOf("?")+1);
    }

    private void initializePlayer(PlayerView playerView,String uri) {
        if (player == null) {
            player = ExoPlayerFactory.newSimpleInstance(context.getApplicationContext());
            //플레이어 연결
            playerView.setPlayer(player);
        }

        MediaSource mediaSource = buildMediaSource(Uri.parse(uri));

        //prepare
        player.prepare(mediaSource, true, false);
        //start,stop
        player.setPlayWhenReady(playWhenReady);
    }

    private MediaSource buildMediaSource(Uri uri) {

        String userAgent = Util.getUserAgent(context, "blackJin");

        return new ExtractorMediaSource.Factory(new DefaultHttpDataSourceFactory(userAgent))
                .createMediaSource(uri);
    }

    private void releasePlayer(PlayerView playerView) {
        if (player != null) {
            playbackPosition = player.getCurrentPosition();
            currentWindow = player.getCurrentWindowIndex();
            playWhenReady = player.getPlayWhenReady();

            playerView.setPlayer(null);
            player.release();
            player = null;

        }
    }

}

 

View_FormatsActivity (도화지 역할을 하게 될 activity)

public class View_FormatActivity extends AppCompatActivity {

    private ArrayList<String> formats;
    private int position;

    ViewPager2 viewPager2; //뷰페이저
    Formats_PagerAdapter viewPagerAdapter;

    @SuppressLint("WrongViewCast")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_formats_pager);

        Intent intent = getIntent();
        formats = (ArrayList<String>) intent.getSerializableExtra("formats");
        position = intent.getIntExtra("position",0);

        viewPager2 = findViewById(R.id.formats_pager);
        viewPagerAdapter = new Formats_PagerAdapter(this ,formats); //뷰페이저 어뎁터 생성
        viewPager2.setAdapter(viewPagerAdapter);//어뎁터 연결
        viewPager2.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL); //스크롤방향
        viewPager2.setCurrentItem(position); //사진의 포지션을 알고 있기때문에 터치한 사진부터 전체화면으로 볼 수 있다

    }

}

저는 액티비티에 viewpager2를 넣었고 거기에 넣을 item을 xml로 만들어 주었으며, 그에 대한 데이터처리는 adapter에서 했습니다. 따라서 액티비티에서 viewpager2와 adapter를 연결시켜주고 마무리 지었습니다.

 

사용하실 때에 복붙하시면 될정도의 기본예제구요, 다만 레이아웃이나 어댑터에서는 제가 사용하기 편하게 저의 기준으로 코딩되어있으니 그 부분만 쳐내고 여러분 편한대로 쓰시면 됩니다.

 

저는 올라오는 파일이 사진,영상,gif인지 모르는 상황에서 glide를 사용하고 싶어서 뷰페이저로 전체화면을 제공하기 위해 사용했습니다. 

 

리사이클러뷰와 거의 동일한 예제이니 어려운 점은 없으실거라 봅니다만, 워낙에 다양하게 쓰이고 사람마다 다 다르게 쓰기 때문에 참고하시면 될 것 같습니다.