Develop/Java

[Java] 자바 Android 튜토리얼 페이지 구현

JunJangE 2021. 8. 11. 19:12

안드로이드를 개발하다 보면 설명이 필요한 기능이나 권한의 용도를 설명해야 할 때가 있다.

이러한 경우에는 튜토리얼 페이지를 통해 사용자가 쉽게 이해할 수 있도록 도울 수 있다.

그럼 이제 튜토리얼 페이지를 구현해보자.

res -> strings.xml

우선 튜토리얼 페이지에서 사용할 글자를 정의한다.

<resources>
    <string name="app_name">TutorialActivity</string>

    <!-- 이름을 정의하여 조건에 따라 페이지의 이름을 띄운다.  -->
    <string name="next">다음</string>
    <string name="skip">건너띄기</string>
    <string name="start">시작</string>
    
</resources>

여기서 정의된 글자는 버튼의 글자이며 조건에 따라 글자를 띄울 것이다.

res -> values.xml

다음으로 색을 정의할 것이다.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="purple_200">#FFBB86FC</color>
    <color name="purple_500">#FF6200EE</color>
    <color name="purple_700">#FF3700B3</color>
    <color name="teal_200">#FF03DAC5</color>
    <color name="teal_700">#FF018786</color>
    <color name="black">#FF000000</color>
    <color name="white">#FFFFFFFF</color>

    <!-- 배경색-->
    <color name="bg_screen1">#07E940</color>
    <color name="bg_screen2">#FFAD03</color>
    <color name="bg_screen3">#FF3385</color>
    <color name="bg_screen4">#25C8E4</color>

    <!-- 선택되지 않은 점(선택 되지 않은 페이지 점) -->
    <color name="dot_dark_screen1">#1C7C34</color>
    <color name="dot_dark_screen2">#A5662D</color>
    <color name="dot_dark_screen3">#A54B6A</color>
    <color name="dot_dark_screen4">#2D717A</color>

    <!-- 선택된 점(해당 페이지 일 때) -->
    <color name="dot_light_screen1">#67FF8C</color>
    <color name="dot_light_screen2">#FFCE70</color>
    <color name="dot_light_screen3">#FF74A8</color>
    <color name="dot_light_screen4">#64E7FF</color>

    <array name="array_dot_active">
        <item>@color/dot_light_screen1</item>
        <item>@color/dot_light_screen2</item>
        <item>@color/dot_light_screen3</item>
        <item>@color/dot_light_screen4</item>
    </array>

    <array name="array_dot_inactive">
        <item>@color/dot_dark_screen1</item>
        <item>@color/dot_dark_screen2</item>
        <item>@color/dot_dark_screen3</item>
        <item>@color/dot_dark_screen4</item>
    </array>

</resources>

정의한 색은 배경색과 페이지를 넘길 때 하단에 생기는 점의 색을 정의했다.

자신이 원하는 색으로 바꿔가며 프로젝트를 수행하면 좋을 것 같다.

layout -> page.xml 생성

레이아웃에서 자신이 튜토리얼에 띄울 페이지를 만든다.

예제에서는 4개를 만들었다.

page1.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:background="@color/bg_screen1"
    android:orientation="vertical"
    android:gravity="center">


        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="메론!"
            android:textColor="@android:color/white"
            android:textSize="18dp"
            android:textStyle="bold"
            android:layout_margin="30dp"/>

        <ImageView
            android:layout_width="250dp"
            android:layout_height="250dp"
            android:src="@drawable/melon" />


</LinearLayout>

page2.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:background="@color/bg_screen2"
    android:orientation="vertical"
    android:gravity="center">


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="오렌지!"
        android:textColor="@android:color/white"
        android:textSize="18dp"
        android:textStyle="bold"
        android:layout_margin="30dp"/>

    <ImageView
        android:layout_width="250dp"
        android:layout_height="250dp"
        android:src="@drawable/orange" />


</LinearLayout>

page3.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:background="@color/bg_screen3"
    android:orientation="vertical"
    android:gravity="center">


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="사과!"
        android:textColor="@android:color/white"
        android:textSize="18dp"
        android:textStyle="bold"
        android:layout_margin="30dp"/>

    <ImageView
        android:layout_width="250dp"
        android:layout_height="250dp"
        android:src="@drawable/apple" />


</LinearLayout>

page4.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:background="@color/bg_screen4"
    android:orientation="vertical"
    android:gravity="center">


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="포도!"
        android:textColor="@android:color/white"
        android:textSize="18dp"
        android:textStyle="bold"
        android:layout_margin="30dp"/>
    <ImageView
        android:layout_width="250dp"
        android:layout_height="250dp"
        android:src="@drawable/grape" />

</LinearLayout>

이제 본격적으로 튜토리얼을 구현하는 코드를 작성해보자.

주석을 잘 확인하면서 작성하면 좋을 것 같다.

MainActivity

import androidx.appcompat.app.AppCompatActivity;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

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

        Button moveButton;
        moveButton = findViewById(R.id.moveButton);
        moveButton.setOnClickListener(onClickListener);


        // 최초 실행 여부를 판단 ->>>
        SharedPreferences pref = getSharedPreferences("checkFirst", Activity.MODE_PRIVATE);
        boolean checkFirst = pref.getBoolean("checkFirst", false);

        // false일 경우 최초 실행
        if(!checkFirst){
            // 앱 최초 실행시 하고 싶은 작업
            SharedPreferences.Editor editor = pref.edit();
            editor.putBoolean("checkFirst",true);
            editor.apply();
            finish();

            Intent intent = new Intent(MainActivity.this, TutorialActivity.class);
            startActivity(intent);

        }
    }

    Button.OnClickListener onClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this, TutorialActivity.class);
                startActivity(intent);
                finish();
        }
    };
}

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"
    android:orientation="vertical">


    <Button
        android:id="@+id/moveButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="이동"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
        
        
</androidx.constraintlayout.widget.ConstraintLayout>

TutorialActivity

튜토리얼 페이지를 띄어줄 액티비티를 만든다.

import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager.widget.ViewPager;

public class TutorialActivity extends AppCompatActivity {

    private ViewPager viewPager;
    private PagerAdapter pagerAdapter;
    private LinearLayout dotsLayout;
    private TextView[] dots;
    private int[] layouts;
    private Button btnSkip, btnNext;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        if (Build.VERSION.SDK_INT >= 21) {
            getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
        }

        setContentView(R.layout.activity_tutorial);

        viewPager = findViewById(R.id.view_pager);
        dotsLayout = findViewById(R.id.layoutDots);
        btnSkip = findViewById(R.id.btn_skip);
        btnNext = findViewById(R.id.btn_next);

        // 변화될 레이아웃들 주소
        // 원하는 경우 레이아웃을 몇 개 더 추가
        layouts = new int[]{
                R.layout.page1,
                R.layout.page2,
                R.layout.page3,
                R.layout.page4
        };

        // 하단 점 추가
        addBottomDots(0);

        // 알림 표시줄을 투명하게 만들기
        changeStatusBarColor();

        pagerAdapter = new PagerAdapter();
        viewPager.setAdapter(pagerAdapter);
        viewPager.addOnPageChangeListener(viewPagerPageChangeListener);


        // 건너띄기 버튼 클릭시 메인화면으로 이동
        btnSkip.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(TutorialActivity.this, MainActivity.class));
                finish();
            }
        });

        // 조건문을 통해 버튼 하나로 두개의 상황을 실행
        btnNext.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int current = getItem(+1);
                if (current < layouts.length) {
                    // 마지막 페이지가 아니라면 다음 페이지로 이동
                    viewPager.setCurrentItem(current);
                }
                else {
                    // 마지막 페이지라면 메인페이지로 이동
                    startActivity(new Intent(TutorialActivity.this, MainActivity.class));
                    finish();
                }
            }
        });
    }

    // 하단 점(선택된 점, 선택되지 않은 점) 구현
    private void addBottomDots(int currentPage) {
        dots = new TextView[layouts.length]; // 레이아웃 크기만큼 하단 점 배열에 추가

        int[] colorsActive = getResources().getIntArray(R.array.array_dot_active);
        int[] colorsInactive = getResources().getIntArray(R.array.array_dot_inactive);

        dotsLayout.removeAllViews();
        for (int i = 0; i < dots.length; i++) {
            dots[i] = new TextView(this);
            dots[i].setText(Html.fromHtml("&#8226;"));
            dots[i].setTextSize(35);
            dots[i].setTextColor(colorsInactive[currentPage]);
            dotsLayout.addView(dots[i]);
        }

        if (dots.length > 0)
            dots[currentPage].setTextColor(colorsActive[currentPage]);
    }

    private int getItem(int i) {
        return viewPager.getCurrentItem() + i;
    }

    // 뷰페이저 변경 리스너
    ViewPager.OnPageChangeListener viewPagerPageChangeListener = new ViewPager.OnPageChangeListener() {

        @Override
        public void onPageSelected(int position) {
            addBottomDots(position);

            // 다음 / 시작 버튼 바꾸기
            if (position == layouts.length - 1) {
                // 마지막 페이지에서는 다음 버튼을 시작버튼으로 교체
                btnNext.setText(getString(R.string.start)); // 다음 버튼을 시작버튼으로 글자 교체
                btnSkip.setVisibility(View.GONE);
            }
            else {

                // 마지막 페이지가 아니라면 다음과 건너띄기 버튼 출력
                btnNext.setText(getString(R.string.next));
                btnSkip.setVisibility(View.VISIBLE);
            }
        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {

        }

        @Override
        public void onPageScrollStateChanged(int arg0) {

        }
    };

    // 알림 표시줄을 투명하게 만들기
    private void changeStatusBarColor() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Window window = getWindow();
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(Color.TRANSPARENT);
        }
    }

    // 호출기 어댑터
    public class PagerAdapter extends androidx.viewpager.widget.PagerAdapter {
        private LayoutInflater layoutInflater;

        public PagerAdapter() {
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            layoutInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            View view = layoutInflater.inflate(layouts[position], container, false);
            container.addView(view);

            return view;
        }

        @Override
        public int getCount() {
            return layouts.length;
        }

        @Override
        public boolean isViewFromObject(View view, Object obj) {
            return view == obj;
        }


        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            View view = (View) object;
            container.removeView(view);
        }
    }
}

activity_tutorial.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:showIn="@layout/activity_tutorial">


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

    <!--    하단 점이 들어갈 레이아웃-->
    <!--    layout_alignParent로 아래에 위치-->
    <LinearLayout
        android:id="@+id/layoutDots"
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:layout_alignParentBottom="true"
        android:layout_marginBottom="20dp"
        android:gravity="center"
        android:orientation="horizontal">

    </LinearLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:alpha=".5"
        android:layout_above="@id/layoutDots"
        android:background="@android:color/white" />

    <!--    다음 버튼-->
    <!--    layout_alignParent로 아래 오른쪽에 위치-->
    <Button
        android:id="@+id/btn_next"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:background="@null"
        android:text="@string/next"
        android:textColor="@android:color/white" />

    <!--    스킵 버튼-->
    <!--    layout_alignParent로 아래 왼쪽에 위치-->
    <Button
        android:id="@+id/btn_skip"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:background="@null"
        android:text="@string/skip"
        android:textColor="@android:color/white" />

</RelativeLayout>

AndroidMainfest.xml

마지막으로 튜토리얼 액티비티에 타이틀 바를 제거하여 깔끔하게 튜토리얼을 볼 수 있게 한다.

<!-- 깔끔하게 튜토리얼만 보기 위해 타이틀 바를 제거 한다.
            android:theme="@style/Theme.AppCompat.DayNight.NoActionBar"   -->

AndroidMainfest.xml

위 코드를 모두 작성하고 실행하면 다음 결과 동영상과 같이 나오는 것을 확인할 수 있다.

<결과 동영상>

참고

 

Android How to Build Intro Slider for your App

Adding Welcome / Intro screens in your app is a great way of showcasing the major features of the app. Previously I explained about adding a static Splash Screen to your app. In this article we are going to learn how to add an intro slider to your app wher

www.androidhive.info

github

 

GitHub - junjange/Java-Learning: 자바 학습

자바 학습. Contribute to junjange/Java-Learning development by creating an account on GitHub.

github.com