안드로이드 앱은 액티비티의 집합으로 이루어져 있다. 생명주기도 액티비티마다 제각각이고 시작시점과 종료시점도 때로는 불분명한 것이 안드로이드의 현 주소이다. 가장 단순한 시나리오인 앱의 종료에 있어서도 생각할 것이 많다. 액티비티만 종료를 한다면 앱의 프로세스가 살아 있어서 예기치 못한 부작용이 나타나기도 하고, 앱의 프로세스만 종료하면 Task List에 앱이 여전히 남아있는 등, 다양한 문제가 나타난다.
여러 가지 실험 결과 앱을 완전히 종료하기 위해서는 다음의 스텝을 따라야 한다는 것을 깨달아서 남겨본다. 태스크를 백그라운드로 이동 -> 액티비티 종료 -> Task List에서 지우기 -> 앱 프로세스 종료. 이 중 하나만 빠져도 예기치 못한 상황이 발생한다. 아직까지는 이 방법으로 문제가 없는데, 앞으로도 문제가 없길 바라면서...
앱을 완전 종료하는 방법:
moveTaskToBack(true); // 태스크를 백그라운드로 이동
finishAndRemoveTask(); // 액티비티 종료 + 태스크 리스트에서 지우기
android.os.Process.killProcess(android.os.Process.myPid()); // 앱 프로세스 종료
In this tutorial we are going to create 3 Tabs .Every tab have its own Fragment to control over screen. Also user can swipe between 3 tabs.
we are using AndroidX support Library , ViewPager2 and 3 different fragment & 3 different xml for layouts. And TabLayout for Tabs.
Layout Demonstration :
Checkout the following pic which explains the complete overview of layout architecture. Basically we are using ViewPager as main layout and for individual pager views we use Fragments. The tabs are part of Action Bar.
STEP 1: CREATING PROJECT
Let’s start with creating new project in android studio with package name com.example.manualSliding and class name MainActivity.java and its layout name is activity_main.xml.
STEP 2: ADDING DEPENDENCIES
open file Gradle Scripts/build.gradle(Module: app)
under dependencies{ } add this:
dependencies {
//this is for ViewPager
implementation "androidx.viewpager2:viewpager2:1.0.0"
//this is for TabLayout
implementation 'com.google.android.material:material:1.2.0-alpha01'
}
new TabLayoutMediator(tabLayout, viewPager,(tab, position) -> tab.setText(titles[position])).attach();
complete code of MainActivity.java
package com.example.manualsliding;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
public class MainActivity extends AppCompatActivity {
private static final int NUM_PAGES = 3;
//The pager widget, which handles animation and allows swiping horizontally to access previous and next wizard steps.
public static ViewPager2 viewPager;
// The pager adapter, which provides the pages to the view pager widget.
private FragmentStateAdapter pagerAdapter;
// Arrey of strings FOR TABS TITLES
private String[] titles = new String[]{"Tab1", "Tab2", "Tab3"};
// tab titles
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = findViewById(R.id.mypager);
pagerAdapter = new MyPagerAdapter(this);
viewPager.setAdapter(pagerAdapter);
//inflating tab layout
TabLayout tabLayout =( TabLayout) findViewById(R.id.tab_layout);
//displaying tabs
new TabLayoutMediator(tabLayout, viewPager,(tab, position) -> tab.setText(titles[position])).attach();
}
private class MyPagerAdapter extends FragmentStateAdapter {
public MyPagerAdapter(FragmentActivity fa) {
super(fa);
}
@Override
public Fragment createFragment(int pos) {
switch (pos) {
case 0: {
return FirstFragment.newInstance("fragment 1");
}
case 1: {
return SecondFragment.newInstance("fragment 2");
}
case 2: {
return ThirdFragment.newInstance("fragment 3");
}
default:
return FirstFragment.newInstance("fragment 1, Default");
}
}
@Override
public int getItemCount() {
return NUM_PAGES;
}
}
@Override
public void onBackPressed() {
if (viewPager.getCurrentItem() == 0) {
// If the user is currently looking at the first step, allow the system to handle the
// Back button. This calls finish() on this activity and pops the back stack.d
super.onBackPressed();
} else {
// Otherwise, select the previous step.
viewPager.setCurrentItem(viewPager.getCurrentItem() - 1);
}
}
}