오늘이라도

[Android] 17. ViewPager / 옵션 메뉴, 액션 바 / 라이브러리 추가, 탭 만들어서 여러 프래그먼트 보기 본문

취업성공패키지 SW 개발자 교육/Android

[Android] 17. ViewPager / 옵션 메뉴, 액션 바 / 라이브러리 추가, 탭 만들어서 여러 프래그먼트 보기

upcake_ 2020. 5. 28. 09:18
반응형

https://github.com/upcake/Class_Examples

교육 중에 작성한 예제들은 깃허브에 올려두고 있습니다. 

gif 파일은 클릭해서 보는 것이 정확합니다.


 - ViewPager -

▲ViewPager 작동 화면

▼activity_main.xml

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

    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="두 번째 화면 보여주기"
        android:textSize="24sp" />

    <!--뷰페이저 : 화면을 여러개 나열하고 옆으로 넘기게 하는것-->
    <androidx.viewpager.widget.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <!--탭을 만들어주는 태그 PagerTabStrip-->
        <androidx.viewpager.widget.PagerTabStrip
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#CDDC39"
            android:paddingTop="5dp"
            android:paddingBottom="5dp" />
    </androidx.viewpager.widget.ViewPager>
</LinearLayout>

▼MainActivity.java

package com.example.my22_viewpager;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    //객체 선언
    Button button1;
    ViewPager pager;

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

        //객체 초기화
        button1 = findViewById(R.id.button1);
        pager = findViewById(R.id.pager);

        //페이저 기능 추가
        //setOffscreenPageLimit() : 좌우를 포함해해 미리 생성해 둘 페이지 수
       pager.setOffscreenPageLimit(3);

       //페이저 어댑터 객체 초기화
        //MyPagerAdapter는 프래그먼트매니저를 매개 변수로 받는다.
       MyPagerAdapter adapter = new MyPagerAdapter(getSupportFragmentManager());

       //프래그먼트 객체 초기화
       Fragment1 fragment1 = new Fragment1();
       Fragment2 fragment2 = new Fragment2();
       Fragment3 fragment3 = new Fragment3();

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

       //페이저에 어댑터를 붙여준다.
       pager.setAdapter(adapter);

       //버튼 초기화, 기능 추가
       Button button1 = findViewById(R.id.button1);
       button1.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               //페이저에서 이동할 좌표를 지정하는 메서드
               pager.setCurrentItem(1);
           }
       });
    }

    class MyPagerAdapter extends FragmentStatePagerAdapter {
        //MyPagerAdapter 클래스를 만들고 Alt + Enter로 implement 하고 생성자를 만든다
        public MyPagerAdapter(@NonNull FragmentManager fm) {
            super(fm);
        }

        //Fragment를 넣을 리스트 초기화
        ArrayList<Fragment> items = new ArrayList<>();

        //리스트에 프래그먼트를 추가하는 메서드를 만든다
        public void addItem(Fragment item) {
            items.add(item);
        }

        @NonNull
        @Override
        public Fragment getItem(int position) {
            //items의 프래그먼트 인덱스를 받아서 리턴하게끔 설정
            return items.get(position);
        }

        //items에 들어있는 원소의 갯수를 반환
        @Override
        public int getCount() {
            return items.size();
        }

        //CharSequence : 어떤 글자를 넘길 것인가
        @Nullable
        @Override
        public CharSequence getPageTitle(int position) {
            return "페이지" + (position + 1);
        }
    }
}

 

▼fragment1.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:background="#00BCD4">

    <Button
        android:id="@+id/button2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="첫 번째"/>
</LinearLayout>

▼Fragment1.java

package com.example.my22_viewpager;

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

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

public class Fragment1 extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        //XML, java 연결
        //XML이 메인에 직접 붙으면 true, 프래그먼트에 붙으면 false
        ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment1, container, false);

        return rootView;
    }
}

 

▼fragment2.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:background="#2196F3">

    <Button
        android:id="@+id/button3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="두 번째"/>
</LinearLayout>

▼Fragment2.java

package com.example.my22_viewpager;

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

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

public class Fragment2 extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        //XML과 java 연결
        ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment2, container, false);

        return rootView;
    }


}

 

▼fragment3.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:background="#673AB7">

    <Button
        android:id="@+id/button4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="세 번째"/>
</LinearLayout>

▼Fragment3.java

package com.example.my22_viewpager;

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

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

public class Fragment3 extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment3, container, false);

        return rootView;
    }
}

 

 

 

 - 옵션 메뉴, 액션 바 -

▲옵션 메뉴 작동 화면

 

▼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">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

▼MainActivity.java

package com.example.my23_optionmenu;

import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    //액션바 객체 선언
    ActionBar bar;

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

        bar = getSupportActionBar();
        //액션바 안보이게 설정 방법 ①
//        bar.hide();

        //액션바 로고 바꾸기
        bar.setLogo(R.drawable.back);
        bar.setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP);

        //로고 클릭할 때 이벤트 발생하게 설정
        bar.setDisplayHomeAsUpEnabled(true);
    }

    //옵션 메뉴 붙이기
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        //getMenuInflater() : 프래그먼트 매니저와 비슷한 역할을 함
        getMenuInflater().inflate(R.menu.menu_option, menu);
        return true;
    }

    //옵션 아이콘을 클릭했을 때 이벤트 발생하게끔 설정
    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        int curId = item.getItemId();
        switch (curId) {
            case R.id.menu_refresh :
                Toast.makeText(this, "새로고침 메뉴 눌림...", Toast.LENGTH_SHORT).show();
                break;

            case R.id.menu_search :
                Toast.makeText(this, "검색 메뉴 눌림...", Toast.LENGTH_SHORT).show();
                break;

            case R.id.menu_settings :
                Toast.makeText(this, "설정 메뉴 눌림...", Toast.LENGTH_SHORT).show();
                break;

            //ancroid.R.id.home이 로고의 자리
            case android.R.id.home :
                Toast.makeText(this, "홈 메뉴 눌림...", Toast.LENGTH_SHORT).show();
                this.finish();
                break;
        }
        return true;
    }
}

 

▲menu 경로 생성

 

▲menu_option. 생성

▼menu_option.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <!--새로고침 버튼-->
    <!--app:showAsAction : 어떻게, 언제 보이게 할건지 설정-->
    <!--always : 항상 아이콘으로 보여줌-->
    <!--never : 더보기 버튼을 눌러야 타이틀이 보임-->
    <!--orderInCategory : 보이는 순서 설정-->
    <item
        android:id="@+id/menu_refresh"
        android:title="새로고침"
        android:icon="@drawable/menu_refresh"
        app:showAsAction="always"
        android:orderInCategory="101" />

    <!--검색 버튼-->
    <item
        android:id="@+id/menu_search"
        android:title="검색"
        android:icon="@drawable/menu_search"
        app:showAsAction="always"
        android:orderInCategory="103" />

    <!--설정 버튼-->
    <item
        android:id="@+id/menu_settings"
        android:title="설정"
        android:icon="@drawable/menu_settings"
        app:showAsAction="always"
        android:orderInCategory="105" />
</menu>

▼styles.xml

<resources>
    <!-- Base application theme. -->
    <!--액션바 테마 설정-->
    <!--액션바 안보이게 설정 방법 ②-->
    <!--NoActionBar : 액션바가 안보이게끔 설정-->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>
</resources>

 

 - 라이브러리 추가, 탭 만들어서 여러 프래그먼트 보기 -

 

 ○ 라이브러리를 추가하는 법

   ① Gradle Scripts → build.gradle (Moudle: app) - dependencies 블록에 implementation 문장을 작성한다.

implementation 'com.android.support:design:29.0.0'

   ② File → New → Project Structure → Dependencies → Add(+) Library Dependency

    - 작성한 뒤에 우측 상단의 Sync Now를 눌러 제대로 작성됐는지 확인한다.

 

 

▲탭 작동 화면

 

▼activity_main.xml

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

    <!--전체적인 레이아웃을 잡음-->
    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <!--액션바 레이아웃-->
        <com.google.android.material.appbar.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="clip_horizontal|center"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@color/design_default_color_primary_dark"
                android:elevation="1dp"
                android:theme="@style/ThemeOverlay.AppCompat.Dark">
                <!--elevation : 약간 떠있는 느낌-->

                <TextView
                    android:id="@+id/titleText"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="타이틀"
                    android:textAppearance="@style/Widget.AppCompat.Toolbar"
                    android:textColor="#FFFFFF"
                    android:textSize="24sp" />
            </androidx.appcompat.widget.Toolbar>

            <!--탭 레이아웃-->
            <com.google.android.material.tabs.TabLayout
                android:id="@+id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@android:color/background_light"
                android:elevation="1dp"
                app:tabGravity="fill"
                app:tabMode="fixed"
                app:tabSelectedTextColor="@color/colorAccent"
                app:tabTextColor="@color/colorPrimaryDark" />
        </com.google.android.material.appbar.AppBarLayout>

        <FrameLayout
            android:id="@+id/contatiner"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">

        </FrameLayout>
    </androidx.coordinatorlayout.widget.CoordinatorLayout>
</RelativeLayout>

 

▼MainActivity.java

package com.example.my24_tab1;

import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;

import android.os.Bundle;
import android.util.Log;

import com.google.android.material.tabs.TabLayout;

public class MainActivity extends AppCompatActivity {
    //로그캣 사용 준비
    private static final String TAG = "MainActivity";

    //객체 선언
    Toolbar toolbar;
    TabLayout tabs;
    Fragment1 fragment1;
    Fragment2 fragment2;
    Fragment3 fragment3;
    Fragment selected = null;

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

        //툴바 설정
        toolbar = findViewById(R.id.toolbar);
//      setSupportActionBar(toolbar);

        //액션바 설정
        ActionBar actionBar = getSupportActionBar();
        actionBar.setDisplayShowTitleEnabled(false);
        actionBar.hide();

        //프래그먼트 초기화
        fragment1 = new Fragment1();
        fragment2 = new Fragment2();
        fragment3 = new Fragment3();

        //프래그먼트 넣기(바꾸기)
        getSupportFragmentManager().beginTransaction().replace(R.id.contatiner, fragment1).commit();

        //탭 만들기 (동적)
        tabs = findViewById(R.id.tabs);
        tabs.addTab(tabs.newTab().setText("통화 기록"));
        tabs.addTab(tabs.newTab().setText("스팸 기록"));
        tabs.addTab(tabs.newTab().setText("연락처"));

        //탭이 선택되었을때 작동하는 메서드
        tabs.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                int position = tab.getPosition();
                Log.d(TAG, "선택된 탭 : " + position);

                if (position == 0) {
                    selected = fragment1;
                } else if (position == 1) {
                    selected = fragment2;
                } else if (position == 2) {
                    selected = fragment3;
                }

                //선택된 프래그먼트로 바꾸기
                getSupportFragmentManager().beginTransaction().replace(R.id.contatiner, selected).commit();
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });
    }
}

 

▼fragment1.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:background="#00BCD4">

    <Button
        android:id="@+id/button2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="첫 번째"/>
</LinearLayout>

▼Fragment1.java

package com.example.my24_tab1;

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

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

public class Fragment1 extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        //XML, java 연결
        //XML이 메인에 직접 붙으면 true, 프래그먼트에 붙으면 false
        ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment1, container, false);

        return rootView;
    }
}

 

▼fragment2.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:background="#2196F3">

    <Button
        android:id="@+id/button3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="두 번째"/>
</LinearLayout>

▼Fragment2.java

package com.example.my24_tab1;

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

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

public class Fragment2 extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        //XML과 java 연결
        ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment2, container, false);

        return rootView;
    }


}

 

▼fragment3.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:background="#673AB7">

    <Button
        android:id="@+id/button4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="세 번째"/>
</LinearLayout>

▼Fragment3.java

package com.example.my24_tab1;

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

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

public class Fragment3 extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment3, container, false);

        return rootView;
    }
}

 

반응형