본문 바로가기

안드로이드/코드

[안드로이드] 각 프래그먼트 별 뒤로가기 버튼(백버튼) 이벤트 (뷰페이저 사용) - onBackPressed,FragmentStatePagerAdapter,ViewPager,AlertDialog

반응형

 

 

 

 

백버튼1

 

ViewPager를 이용해서 프래그먼트 3개를 넣고  각 프래그먼트마다 다른 이벤트가 발생하도록 만들어보겠습니다.

 

1번 프래그먼트 - 뒤로가기 두번을 누르면 액티비티 종료

2번 프래그먼트 - 3번 프래그먼트로 페이지 전환

3번 프래그먼트 - 종료 다이얼로그 띄우기

 

1. 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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

뷰페이저만 추가했기 때문에 특이사항은 없습니다.

아이디 값만 제대로 입력해주시면 됩니다.

 

2. 프래그먼트 xml 생성

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:background="#9C27B0">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="Fragment1"
        android:textColor="@android:color/white"
        android:textSize="30sp"
        android:textStyle="bold" />

</LinearLayout>

 

Fragment1, Fragment2, Fragment3으로 만들었고, 텍스트뷰의 텍스트를 1,2,3으로 변경해주고 레이아웃의 background를 프래그먼트마다 다른색으로 적용해줬습니다.

fragment1.xml, fragment2.xml, fragment3.xml 총 3개를 만드셔야합니다.

 

백버튼2

 

3. OnBackPressedListener 인터페이스 생성

public interface OnBackPressedListener {
    void onBackPressed();
}

 

4-1. Fragment1.java (백버튼 두번 누르면 종료하는 이벤트 적용)

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

public class Fragment1 extends Fragment implements OnBackPressedListener{
    ViewGroup viewGroup;
    MainActivity activity;
    long backKeyPressedTime;
    Toast toast;
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        viewGroup = (ViewGroup) inflater.inflate(R.layout.fragment1,container,false);
        activity = (MainActivity) getActivity();
        toast = Toast.makeText(getContext(),"한번 더 누르면 종료됩니다.",Toast.LENGTH_SHORT);
        return viewGroup;
    }

    @Override
    public void onBackPressed() {

        //터치간 시간을 줄이거나 늘리고 싶다면 2000을 원하는 시간으로 변경해서 사용하시면 됩니다.
        if(System.currentTimeMillis() > backKeyPressedTime + 2000){
            backKeyPressedTime = System.currentTimeMillis();
            toast.show();
            return;
        }
        if(System.currentTimeMillis() <= backKeyPressedTime + 2000){
            getActivity().finish();
            toast.cancel();
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        activity.setOnBackPressedListener(this);
    }
}

 

4-2 Fragment2.java (Fragment3으로 페이지를 전환하는 이벤트 적용)

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

public class Fragment2 extends Fragment implements OnBackPressedListener{
    ViewGroup viewGroup;
    MainActivity activity;
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        viewGroup = (ViewGroup) inflater.inflate(R.layout.fragment2,container,false);
        activity = (MainActivity) getActivity();
        return viewGroup;
    }

    @Override
    public void onBackPressed() {
        activity.setCurrentItem();
    }

    @Override
    public void onResume() {
        super.onResume();
        activity.setOnBackPressedListener(this);
    }
}

 

4-3 Fragment3.java(종료 다이얼로그 띄우는 이벤트 적용)

import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;

public class Fragment3 extends Fragment implements OnBackPressedListener{
    ViewGroup viewGroup;
    MainActivity activity;
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        viewGroup = (ViewGroup) inflater.inflate(R.layout.fragment3,container,false);
        activity = (MainActivity) getActivity();
        return viewGroup;
    }

    @Override
    public void onBackPressed() {
        showDialog();
    }

    public void showDialog(){
        AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
        builder.setTitle("종료");
        builder.setMessage("종료하시겠습니까?");
        builder.setPositiveButton("아니오",
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                    }
                });
        builder.setNegativeButton("예",
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        activity.finish();
                    }
                });
        builder.show();
    }

    @Override
    public void onResume() {
        super.onResume();
        activity.setOnBackPressedListener(this);
    }

}

 

AlertDialog가 궁금하신 분들은 밑의 링크로 들어가서 확인해보시면 됩니다.

 

 

 

참고사항

각 프래그먼트마다 화면이 전환될때마다 리스너가 변경돼야 하기 때문에 onCreateView안에서 적용한다면 마지막 Fragment3이 리스너로 적용이 되기 때문에 각 프래그먼트마다 적용이 될 수 있도록 onResume()안에서 액티비티의 백프레스 리스너를 적용해줍니다.

 

5. PagerAdapter.java (뷰페이저의 어댑터 클래스)

package com.everyshare.backbuttonevent;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;

import java.util.ArrayList;

public class PagerAdapter extends FragmentStatePagerAdapter {
    ArrayList<Fragment> items = new ArrayList<>();

    public PagerAdapter(@NonNull FragmentManager fm, int behavior) {
        super(fm, behavior);
    }

    //프래그먼트 추가
    public void addItem(Fragment item){
        items.add(item);
    }

    //페이지 전환시 해당 포지션의 프래그먼트를 반환
    @NonNull
    @Override
    public Fragment getItem(int position) {
        return items.get(position);
    }

    //현재 어댑터 안의 프래그먼트 총 갯수
    @Override
    public int getCount() {
        return items.size();
    }
}

 

6. MainActivity.java

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {
    Fragment1 fragment1;
    Fragment2 fragment2;
    Fragment3 fragment3;
    PagerAdapter adapter;
    ViewPager viewPager;
    OnBackPressedListener listener;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        viewPager = findViewById(R.id.viewPager);
        //페이지 수 3개로 설정
        viewPager.setOffscreenPageLimit(3);

        fragment1 = new Fragment1();
        fragment2 = new Fragment2();
        fragment3 = new Fragment3();

        adapter = new PagerAdapter(getSupportFragmentManager()
                ,FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);

        //어댑터에 프래그먼트 추가
        adapter.addItem(fragment1);
        adapter.addItem(fragment2);
        adapter.addItem(fragment3);

        //뷰페이저에 어댑터 세팅
        viewPager.setAdapter(adapter);
    }

    public void setOnBackPressedListener(OnBackPressedListener listener){
        this.listener = listener;
    }

    @Override
    public void onBackPressed() {
        if(listener!=null){
            listener.onBackPressed();
        }else{
            super.onBackPressed();
        }
    }

    public void setCurrentItem(){
        //fragment3으로 페이지 전환
        viewPager.setCurrentItem(2);
    }
}

 

실행해보시면 각 프래그먼트마다 다른 백버튼 이벤트가 적용된것을 확인 하실 수 있습니다.

반응형