Splash 이후 뭔가 홍보나 광고 가이드 화면을 ViewPager를 이용하여 Fragment를 연결시켜 스와이프 제스처가 가능한 화면을 만들어 볼 거다. 그리고 스킵과 메인화면으로 넘어가는 버튼을 만들었다. 생각해보면 엄청 많이 필요한 것 같아서 적어봤다.
1. 우선 화면에 사용할 이미지를 먼저 drawable 폴더에 넣어준다.
(나는 화면 구분을 위해 대충 3개 만들었다.)
2. 처음 생성된 main 제외하고 fragment 3개 정도만 만들자. 이미지 참조
3. Fragment는 이미지 뷰와 텍스트뷰 또는 버튼뷰를 배치한다. Activity는 ViewPager2를 배치한다.
fragment_guide1.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".GuideFragment1">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_height="match_parent"
android:layout_width="match_parent">
<ImageView
android:id="@+id/iv_guide1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@+id/tv_skip1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.522"
app:srcCompat="@drawable/img_guide1"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/tv_skip1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="56dp"
android:text="건너뛰기 >"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
fragment_guide2.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".GuideFragment2">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_height="match_parent"
android:layout_width="match_parent">
<ImageView
android:id="@+id/iv_guide2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@+id/tv_skip2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.522"
app:srcCompat="@drawable/img_guide2"
tools:ignore="ContentDescription" />
<TextView
android:id="@+id/tv_skip2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="56dp"
android:text="건너뛰기 >"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
fragment_ad1.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".AdFragment1">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_height="match_parent"
android:layout_width="match_parent">
<ImageView
android:id="@+id/iv_ad1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@+id/btn_skip3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/img_ad1" />
<Button
android:id="@+id/btn_skip3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:text="시작하기 >"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
프리뷰로 본 Fragment 화면이다.
activity_guide.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=".GuideActivity">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/vp_guide"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
3. ViewPager의 Adapter를 만들어준다.
ViewPagerAdapter.java
package com.saii.viewpager2_guide;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;
class ViewPagerAdapter extends FragmentStateAdapter {
public int mCount;
public ViewPagerAdapter(FragmentActivity fa, int count) {
super(fa);
mCount = count;
}
public Fragment createFragment(int position) {
int index = getRealPosition(position);
if(index==0) return new GuideFragment1();
else if(index==1) return new GuideFragment2();
else return new AdFragment1();
}
@Override
public int getItemCount() {
return 3;
}
public int getRealPosition(int position) { return position % mCount; }
}
4. MainActivity.java에서 ViewPager와 Adapter를 연결해준다.
MainActivity.java
package com.saii.viewpager2_guide;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
private ViewPager2 mPager;
private FragmentStateAdapter pagerAdapter;
private final int num_page = 3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPager = findViewById(R.id.vp_guide);
pagerAdapter = new ViewPagerAdapter(this, num_page);
mPager.setAdapter(pagerAdapter);
mPager.setCurrentItem(1); //시작 지점
mPager.setOffscreenPageLimit(num_page); //최대 페이지 수
mPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
super.onPageScrolled(position, positionOffset, positionOffsetPixels);
if (positionOffsetPixels == 0) {
mPager.setCurrentItem(position);
}
}
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
}
});
}
}
5. 각 Fragment에 이벤트를 정의합니다. Fragment에는 메인 화면으로 갈 수 있는 이벤트를 코딩했습니다. 클릭 이벤트를 커스텀 하고 싶다면 onClick 안에 다른 코딩을 하시면 됩니다. 간혹 Fragment에서 뷰가 인식이 안된다는 사람이 있는데 그 부분은 나중에 Fragment를 참조하면 될 것 같다.
GuideFragment1.java
package com.saii.viewpager2_guide;
import android.content.Intent;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class GuideFragment1 extends Fragment {
private TextView tvSkip1;
private View view;
@Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_guide1, container, false);
tvSkip1 = view.findViewById(R.id.tv_skip1);
tvSkip1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
startActivity(intent);
getActivity().finish();
}
});
return view;
}
}
GuideFragment2.java
package com.saii.viewpager2_guide;
import android.content.Intent;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class GuideFragment2 extends Fragment {
private TextView tvSkip2;
private View view;
@Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_guide2, container, false);
tvSkip2 = view.findViewById(R.id.tv_skip2);
tvSkip2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
startActivity(intent);
getActivity().finish();
}
});
return view;
}
}
AdFragment1.java
package com.saii.viewpager2_guide;
import android.content.Intent;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
public class AdFragment1 extends Fragment {
private Button btnSkip3;
private View view;
@Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_ad1, container, false);
btnSkip3 = view.findViewById(R.id.btn_skip3);
btnSkip3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
startActivity(intent);
getActivity().finish();
}
});
return view;
}
}
참조
https://github.com/saii42/android/tree/main/example/Splash
GitHub - saii42/android: android
android. Contribute to saii42/android development by creating an account on GitHub.
github.com