티스토리 뷰

아래와 같은 결과를 얻고자 합니다. 



이것을 구현할 개략적인 순서와 방법은 아래와 같습니다.


MainActivity 의 View 인 activity_main 에서 TabLayout과 ViewPager 를 갖습니다. 

ViewPager 에는 각각의 fragment 가 그려지고, TabLayout 을 사용해서 다른 fragment 로 옮겨갈 수 있으며

TabLayout 의 tabItem 들은, Fragment 와 같은 Adapter 를 적용해서 코드에서 동적으로 생성을 해줍니다.

우리의 어플리케이션에서 일 하게 될 클래스들을 좀 보겠습니다.


○ FragmentManager

fragment 를 가져오거나, 삭제하는 등, Activity 내의 Fragment 를 관리합니다.

참고 : https://jungwoon.github.io/android/2017/08/13/Android_Fragment/


○ FragmentPagerAdapter

유저가 페이지로 다시 돌아올 수 있는 한, Fragment Manager 에서 관리하는 Fragment 를 나타내주는 

PagerAdapter의 implementation 입니다. 


○ PagerAdapter

adapter 로 하여금 ViewPager 내부를 차지하게(populate) 해주는 기본 클래스입니다.

프로그래머는 아마, 조금더 명시적인 구현을, 가령, FragmentPagerAdapter , FragmentStatePagerAdapter 같은

것을 implement 해야할 것 입니다.


○ ViewPager

유저로 하여금, 페이지를 왼쪽 오른 쪽으로 넘길 수 있게 해줍니다.

프로그래머는, PagerAdapter 의 implement 를 구현해주어야 view 가 보여줄 페이지들을 활성화 시킬 수 있습니다


myapplication/MainActivity.java


public class MainActivity extends AppCompatActivity {


private ViewPager mViewPager;
SectionPageAdapter adapter = new SectionPageAdapter(getSupportFragmentManager());
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
A*-1 mViewPager = (ViewPager) findViewById(R.id.container);
setupViewPager(mViewPager);

TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
}
public void setupViewPager(ViewPager viewPager) {
adapter.addFragment(new Fragment_First(), "추천");
adapter.addFragment(new Fragment_Second(), "오늘의 추천");
adapter.addFragment(new Fragment_Third(), "최근 등록");
viewPager.setAdapter(adapter);
}
}

MainActivity 인데요, 

A*-1 라인에서, mViewPager 를 선언/할당합니다. R.id.container 에 해당되는 아이템은 ViewPager 입니다.

그리고, setupVewPager(mViewPager) 를 이용해서, SectionPageAdapter 에 Fragment 를 추가해줍니다.


myapplication/SectionPageAdapter.java


public class SectionPageAdapter extends FragmentPagerAdapter {

private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();

public void addFragment(Fragment fragment, String title){
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
public SectionPageAdapter(FragmentManager fm){
super(fm);
}
@Override
public Fragment getItem(int position) { return mFragmentList.get(position); }

@Override
public int getCount() {
return mFragmentList.size() ;
}


}

리스트 두 개를 이용해서, Fragment 객체 자체와, Fragment 의 이름을 각각 관리해줍니다. 

다시, MainActivity.class 의 남은 부분만 가져오겠습니다.

TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);

이제, TabLayout 을 세팅해주려고 합니다. 이 코드는 어플리케이션에서 아래에 표시된 영역에 작용합니다. 

findViewById 로 tabLayout 에 대한 reference 를 얻어온 후, 

tabLayout 클래스에, setupWithViewPager 메소드에 파라미터로 앞에서 선언하고, 세팅한 mViewPager 를 넘깁니다


추천 | 오늘의 추천 | 최근 등록



자, 이제 저희는 프래그먼트가 3개가 있는데요, 예제의 brevity 를 위해서, 각각의 프래그먼트에

textView 의 글자만 다르게 설정해놓았습니다.

 

myapplication/Fragment_First.java


public class Fragment_First extends Fragment {
ViewPager viewPager;

public Fragment_First(){

}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View view = inflater.inflate(R.layout.fragment_first, container, false);
return view;

}

}

특별한 것 없습니다. 다만 Fragment 는 실제로 view 가 그려지는 것은 onCreateView 에서 이므로 이것을 override 합니다.

여기에도 특별한 기능을 추가하지 않았습니다. 단지 inflater 를 사용해서 fragment 를 그려줄뿐입니다. 이 코드는 

아래에 빨간색 안의 영역을 '그려'줍니다.


잠시, 첫 번 째 Fragment 의 XML 을 보겠습니다.

layout/fragment_first

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

<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment 1" />

</android.support.constraint.ConstraintLayout>

위와같은 layout 이 VIEW_PAGER 안에서 각각 프래그마다 그려지는 원리입니다.


그런데, 의문스러운게 Fragment 를 그려주는 코드는 분명히 있었습니다

myapplication/MainActivity.java

public void setupViewPager(ViewPager viewPager) {
adapter.addFragment(new Fragment_First(), "추천");
adapter.addFragment(new Fragment_Second(), "오늘의 추천");
adapter.addFragment(new Fragment_Third(), "최근 등록");
viewPager.setAdapter(adapter);
}

그런데, TabLayout 에 각각 아이템은 그려준 적이 없음에도 불구하고 생겼는데요 그것은 바로

myapplication/MainActivity.java


TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);

여기에서, setupWithViewPager 에 mViewPager 를 넘겨주었기 때문에.

공식문서에 따르면


ViewPager 를 TabLayout 과 함께 쓴다면, setUpWithViewPager(ViewPager) 를 함께 연동함으로 써.

자동적으로 PagerAdapter 의 페이지 타이틀로 옮겨진다는겁니다. 

그래서 

 adapter.addFragment(new Fragment_First(), "추천");
adapter.addFragment(new Fragment_Second(), "오늘의 추천");
adapter.addFragment(new Fragment_Third(), "최근 등록");

만을 설정해주고 

tabLayout.setupWithViewPager(mViewPager);
을 해버리면, TabLayout 이 설정되는겁니다. 왜냐하면 mViewPager 는
private ViewPager mViewPager;

이니까요.



◎ 파일구조

◎ 코드

myapplication/MainActivity.java


public class MainActivity extends AppCompatActivity {


private ViewPager mViewPager;
SectionPageAdapter adapter = new SectionPageAdapter(getSupportFragmentManager());
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mViewPager = (ViewPager) findViewById(R.id.container);
setupViewPager(mViewPager);

TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
}
public void setupViewPager(ViewPager viewPager) {
adapter.addFragment(new Fragment_First(), "추천");
adapter.addFragment(new Fragment_Second(), "오늘의 추천");
adapter.addFragment(new Fragment_Third(), "최근 등록");
viewPager.setAdapter(adapter);
}
}


myapplication/Fragment_First.java

public class Fragment_First extends Fragment {
ViewPager viewPager;

public Fragment_First(){

}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View view = inflater.inflate(R.layout.fragment_first, container, false);
return view;

}

myapplication/Fragment_Second.java

public class Fragment_Second extends Fragment {

public ViewPager viewPager;

public Fragment_Second(){

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View view = inflater.inflate(R.layout.fragment_second, container, false);
return view;
}
}

myapplication/Fragment_Third.java

public class Fragment_Third extends Fragment {

public Fragment_Third(){

}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_third,container,false);

return view;
}
}

myapplication/SectionPageAdapter.java

public class SectionPageAdapter extends FragmentPagerAdapter {

private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();

public void addFragment(Fragment fragment, String title){
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
public SectionPageAdapter(FragmentManager fm){
super(fm);
}
@Override
public Fragment getItem(int position) { return mFragmentList.get(position); }

@Override
public int getCount() {
return mFragmentList.size() ;
}


}

layout/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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">


<android.support.design.widget.TabLayout

android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@+id/container"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">

</android.support.design.widget.TabLayout>

<android.support.v4.view.ViewPager
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="@+id/tabs"
app:layout_constraintTop_toBottomOf="@+id/tabs">

</android.support.v4.view.ViewPager>


</android.support.constraint.ConstraintLayout>

layout/fragment_firstx.ml

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

<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment 1" />

</android.support.constraint.ConstraintLayout>

layout/fragment_second.xml

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

<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment 2 " />

</android.support.constraint.ConstraintLayout>

layout/fragment_third.xml

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

<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment 3" />

</android.support.constraint.ConstraintLayout>


댓글