보기가 있는 ViewPager
ViewPager는 제스처 탐색을 구현할 수 있는 레이아웃 관리자입니다. 제스처 탐색을 사용하면 왼쪽과 오른쪽으로 살짝 밀어 데이터 페이지를 단계별로 실행할 수 있습니다. 이 가이드에서는 뷰를 데이터 페이지로 사용하여 ViewPager 및 PagerTabStrip을 사용하여 살짝 밀기 가능한 UI를 구현하는 방법을 설명합니다(후속 가이드에서는 페이지에 조각을 사용하는 방법을 설명합니다).
개요
이 가이드는 낙엽수 및 상록 트리의 이미지 갤러리를 구현하는 데 사용하는 ViewPager
방법을 단계별 데모로 제공하는 연습입니다. 이 앱에서 사용자는 "트리 카탈로그"를 통해 왼쪽과 오른쪽으로 살짝 밀어 트리 이미지를 봅니다. 카탈로그의 각 페이지 맨 위에 트리 이름이 나열PagerTabStrip
되고 트리 이미지가 표시됩니다 ImageView
. 어댑터는 기본 데이터 모델에 인터페이스 ViewPager
하는 데 사용됩니다. 이 앱은 .에서 PagerAdapter
파생된 어댑터를 구현합니다.
-based 앱은 s를 사용하여 Fragment
구현되는 경우가 많지만ViewPager
, s의 Fragment
추가 복잡성이 필요하지 않은 몇 가지 비교적 간단한 사용 사례가 있습니다. 예를 들어 이 연습에 설명된 기본 이미지 갤러리 앱은 s를 사용할 Fragment
필요가 없습니다. 콘텐츠가 정적이며 사용자가 서로 다른 이미지 간에만 앞뒤로 살짝 밀기 때문에 표준 Android 보기 및 레이아웃을 사용하여 구현을 더 간단하게 유지할 수 있습니다.
앱 프로젝트 시작
TreePager라는 새 Android 프로젝트를 만듭니다(새 Android 프로젝트를 만드는 방법에 대한 자세한 내용은 Hello, Android 참조). 다음으로, NuGet 패키지 관리자 시작합니다. (NuGet 패키지 설치에 대한 자세한 내용은 다음을 참조하세요 .연습: 프로젝트에 NuGet 포함). Android 지원 라이브러리 v4 찾기 및 설치:
또한 Android 지원 라이브러리 v4에서 다시 필요한 추가 패키지도 설치합니다.
예제 데이터 원본 추가
이 예제에서 트리 카탈로그 데이터 원본(클래스로 TreeCatalog
표시됨)은 항목 콘텐츠를 제공합니다 ViewPager
.
TreeCatalog
에는 어댑터가 s를 만드는 View
데 사용할 트리 이미지 및 트리 제목의 즉시 만든 컬렉션이 포함되어 있습니다. 생성자에는 TreeCatalog
인수가 필요하지 않습니다.
TreeCatalog treeCatalog = new TreeCatalog();
인덱서에서 각 이미지에 TreeCatalog
액세스할 수 있도록 이미지 컬렉션이 구성됩니다. 예를 들어 다음 코드 줄은 컬렉션의 세 번째 이미지에 대한 이미지 리소스 ID를 검색합니다.
int imageId = treeCatalog[2].imageId;
구현 세부 정보는 TreeCatalog
이해 ViewPager
TreeCatalog
와 관련이 없으므로 코드는 여기에 나열되지 않습니다.
소스 코드 TreeCatalog
는 TreeCatalog.cs 사용할 수 있습니다.
이 소스 파일을 다운로드하거나 코드를 복사하여 새 TreeCatalog.cs 파일에 붙여넣고 프로젝트에 추가합니다. 또한 이미지 파일을 다운로드하여 Resources/drawable 폴더에 압축을 풀고 프로젝트에 포함합니다.
ViewPager 레이아웃 만들기
Resources/layout/Main.axml을 열고 해당 내용을 다음 XML로 바꿉니다.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</android.support.v4.view.ViewPager>
이 XML은 ViewPager
전체 화면을 차지하는 값을 정의합니다. 지원 라이브러리에 패키지되어 있으므로 ViewPager
정규화된 이름 android.support.v4.view.ViewPager를 사용해야 합니다. ViewPager
는 Android 지원 라이브러리 v4에서만 사용할 수 있으며 Android SDK에서는 사용할 수 없습니다.
ViewPager 설정
MainActivity.cs 편집하고 다음 문을 추가합니다.using
using Android.Support.V4.View;
OnCreate
메서드를 다음 코드로 바꿉니다.
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
ViewPager viewPager = FindViewById<ViewPager>(Resource.Id.viewpager);
TreeCatalog treeCatalog = new TreeCatalog();
}
이 코드는 다음을 수행합니다.
Main.axml 레이아웃 리소스에서 보기를 설정합니다.
레이아웃에서 참조를
ViewPager
검색합니다.새
TreeCatalog
데이터를 데이터 원본으로 인스턴스화합니다.
이 코드를 빌드하고 실행하면 다음 스크린샷과 유사한 디스플레이가 표시됩니다.
이 시점에서 ViewPager
는 TreeCatalog의 콘텐츠에 액세스하기 위한 어댑터가 없기 때문에 비어 있습니다. 다음 섹션에서는 TreeCatalog에 연결 ViewPager
하기 위해 PagerAdapter를 만듭니다.
어댑터 만들기
ViewPager
는 데이터 원본과 데이터 원본 사이에 ViewPager
있는 어댑터 컨트롤러 개체를 사용합니다(어댑터의 그림 참조). 이 데이터에 ViewPager
액세스하려면 에서 파생된 PagerAdapter
사용자 지정 어댑터를 제공해야 합니다. 이 어댑터는 각 ViewPager
페이지를 데이터 원본의 콘텐츠로 채웁니다. 이 데이터 원본은 앱별이므로 사용자 지정 어댑터는 데이터에 액세스하는 방법을 이해하는 코드입니다. 사용자가 페이지를 ViewPager
살짝 밀면 어댑터가 데이터 원본에서 정보를 추출하여 표시할 페이지 ViewPager
로 로드합니다.
구현할 PagerAdapter
때는 다음을 재정의해야 합니다.
InstantiateItem – 지정된 위치에 대한 페이지(
View
)를 만들어 '의 뷰 컬렉션에ViewPager
추가합니다.DestroyItem – 지정된 위치에서 페이지를 제거합니다.
Count – 사용 가능한 보기(페이지) 수를 반환하는 읽기 전용 속성입니다.
IsViewFromObject – 페이지가 특정 키 개체와 연결되어 있는지 여부를 결정합니다. (이 개체는 메서드에
InstantiateItem
의해 만들어집니다.) 이 예제에서 키 개체는 데이터 개체입니다TreeCatalog
.
TreePagerAdapter.cs 이라는 새 파일을 추가하고 해당 내용을 다음 코드로 바꿉니다.
using System;
using Android.App;
using Android.Runtime;
using Android.Content;
using Android.Views;
using Android.Widget;
using Android.Support.V4.View;
using Java.Lang;
namespace TreePager
{
class TreePagerAdapter : PagerAdapter
{
public override int Count
{
get { throw new NotImplementedException(); }
}
public override bool IsViewFromObject(View view, Java.Lang.Object obj)
{
throw new NotImplementedException();
}
public override Java.Lang.Object InstantiateItem (View container, int position)
{
throw new NotImplementedException();
}
public override void DestroyItem(View container, int position, Java.Lang.Object view)
{
throw new NotImplementedException();
}
}
}
이 코드는 필수 PagerAdapter
구현을 스텁합니다. 다음 섹션에서는 이러한 각 메서드를 작업 코드로 바꿉니다.
생성자 구현
앱이 인스턴스화 TreePagerAdapter
되면 컨텍스트( MainActivity
)와 인스턴스화된 TreeCatalog
컨텍스트를 제공합니다. TreePagerAdapter.cs 클래스의 TreePagerAdapter
맨 위에 다음 멤버 변수 및 생성자를 추가합니다.
Context context;
TreeCatalog treeCatalog;
public TreePagerAdapter (Context context, TreeCatalog treeCatalog)
{
this.context = context;
this.treeCatalog = treeCatalog;
}
이 생성자의 목적은 사용할 컨텍스트와 TreeCatalog
인스턴스를 TreePagerAdapter
저장하는 것입니다.
개수 구현
구현은 Count
비교적 간단합니다. 트리 카탈로그의 트리 수를 반환합니다. Count
를 다음 코드로 바꿉니다.
public override int Count
{
get { return treeCatalog.NumTrees; }
}
NumTrees
데이터 집합의 TreeCatalog
트리 수(페이지 수)를 반환하는 속성입니다.
InstantiateItem 구현
메서드는 InstantiateItem
지정된 위치에 대한 페이지를 만듭니다. 또한 새로 만든 뷰를 '의 뷰 컬렉션에 ViewPager
추가해야 합니다. 이를 가능하게 ViewPager
하기 위해 컨테이너 매개 변수로 자신을 전달합니다.
InstantiateItem
메서드를 다음 코드로 바꿉니다.
public override Java.Lang.Object InstantiateItem (View container, int position)
{
var imageView = new ImageView (context);
imageView.SetImageResource (treeCatalog[position].imageId);
var viewPager = container.JavaCast<ViewPager>();
viewPager.AddView (imageView);
return imageView;
}
이 코드는 다음을 수행합니다.
지정된 위치에 트리 이미지를 표시하도록 새
ImageView
이미지를 인스턴스화합니다. 앱은MainActivity
생성자에 전달ImageView
될 컨텍스트입니다.리소스를
ImageView
지정된 위치에 있는TreeCatalog
이미지 리소스 ID로 설정합니다.전달된 컨테이너
View
를 참조로ViewPager
캐스팅합니다. 이 캐스트를 올바르게 수행하는 데 사용해야JavaCast<ViewPager>()
합니다(Android에서 런타임 확인 형식 변환을 수행하도록 이 작업이 필요합니다).인스턴스화된
ImageView
값을ViewPager
추가하고 호출자에게 반환ImageView
합니다.
이미지를 ViewPager
position
표시하면 이 ImageView
이미지가 표시됩니다. 처음에는 InstantiateItem
처음 두 페이지를 보기로 채우기 위해 두 번 호출됩니다. 사용자가 스크롤할 때 현재 표시된 항목 바로 뒤와 앞에 보기를 유지하기 위해 다시 호출됩니다.
DestroyItem 구현
메서드는 DestroyItem
지정된 위치에서 페이지를 제거합니다. 지정된 위치의 보기가 변경 ViewPager
될 수 있는 앱에서는 새 보기로 바꾸기 전에 해당 위치에서 부실 보기를 제거하는 방법이 있어야 합니다. TreeCatalog
이 예제에서는 각 위치의 보기가 변경되지 않으므로 해당 위치에 대해 호출될 때 InstantiateItem
제거된 DestroyItem
뷰가 단순히 다시 추가됩니다.
(효율성을 높이기 위해 동일한 위치에 다시 표시되는 재활용 풀 View
을 구현할 수 있습니다.)
DestroyItem
메서드를 다음 코드로 바꿉니다.
public override void DestroyItem(View container, int position, Java.Lang.Object view)
{
var viewPager = container.JavaCast<ViewPager>();
viewPager.RemoveView(view as View);
}
이 코드는 다음을 수행합니다.
전달된 컨테이너
View
를 참조로ViewPager
캐스팅합니다.전달된 Java 개체()를 C#
View
(view
view as View
);로 캐스팅합니다.에서 보기를
ViewPager
제거합니다.
IsViewFromObject 구현
사용자가 콘텐츠 ViewPager
페이지를 통해 왼쪽과 오른쪽으로 슬라이드할 때 지정된 위치에 있는 자식 View
이 같은 위치에 대해 어댑터의 개체와 연결되어 있는지 확인하기 위해 호출 IsViewFromObject
합니다(따라서 어댑터의 개체를 개체 키라고 함). 비교적 간단한 앱의 경우 연결은 ID 중 하나입니다. 해당 인스턴스의 어댑터 개체 키는 이전에 viaInstantiateItem
로 ViewPager
반환된 뷰입니다. 그러나 다른 앱의 경우 개체 키는 해당 위치에 표시되는 자식 뷰 ViewPager
와 연결되어 있지만 동일하지 않은 다른 어댑터별 클래스 인스턴스일 수 있습니다. 어댑터만 전달된 뷰 및 개체 키가 연결되어 있는지 여부를 알고 있습니다.
IsViewFromObject
는 제대로 작동하기 위해 PagerAdapter
구현되어야 합니다. 지정된 위치에 대해 반환 false
되는 경우 IsViewFromObject
해당 위치에 ViewPager
보기가 표시되지 않습니다. TreePager
앱에서 반환되는 InstantiateItem
개체 키는 트리의 페이지 View
이므로 코드는 ID만 확인해야 합니다(즉, 개체 키와 뷰가 하나이고 동일합니다). IsViewFromObject
를 다음 코드로 바꿉니다.
public override bool IsViewFromObject(View view, Java.Lang.Object obj)
{
return view == obj;
}
ViewPager에 어댑터 추가
TreePagerAdapter
이제 구현되었ViewPager
으므로 . MainActivity.cs 메서드의 끝에 OnCreate
다음 코드 줄을 추가합니다.
viewPager.Adapter = new TreePagerAdapter(this, treeCatalog);
이 코드는 컨텍스트(this
)로 전달하여 MainActivity
인스턴스화합니다TreePagerAdapter
. 인스턴스화 TreeCatalog
는 생성자의 두 번째 인수로 전달됩니다. ViewPager
'의 Adapter
속성은 인스턴스화된 TreePagerAdapter
개체로 설정됩니다. 이 속성은 에 연결됩니다.TreePagerAdapter
ViewPager
이제 핵심 구현이 완료되었습니다. 앱을 빌드하고 실행합니다. 다음 스크린샷의 왼쪽에 표시된 것처럼 트리 카탈로그의 첫 번째 이미지가 화면에 표시됩니다. 왼쪽으로 살짝 밀어 더 많은 트리 뷰를 표시한 다음 오른쪽으로 살짝 밀어 트리 카탈로그를 통해 다시 이동합니다.
호출기 표시기 추가
이 최소 ViewPager
구현은 트리 카탈로그의 이미지를 표시하지만 사용자가 카탈로그 내에 있는 위치에 대한 표시는 제공하지 않습니다. 다음 단계는 .를 추가하는 것입니다 PagerTabStrip
. 사용자에게 PagerTabStrip
표시되는 페이지를 알리고 이전 페이지와 다음 페이지의 힌트를 표시하여 탐색 컨텍스트를 제공합니다. PagerTabStrip
는 현재 페이지의 표시기로 사용되며 사용자가 각 페이지를 ViewPager
살짝 밀면 스크롤되고 업데이트됩니다.
Resources/layout/Main.axml을 열고 레이아웃에 추가 PagerTabStrip
합니다.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v4.view.PagerTabStrip
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:paddingBottom="10dp"
android:paddingTop="10dp"
android:textColor="#fff" />
</android.support.v4.view.ViewPager>
ViewPager
함께 PagerTabStrip
작동하도록 설계되었습니다. 레이아웃 내부를 PagerTabStrip
ViewPager
선언하면 자동으로 해당 레이아웃 ViewPager
을 PagerTabStrip
찾아 어댑터에 연결합니다. 앱을 빌드하고 실행할 때 각 화면의 맨 위에 빈 PagerTabStrip
항목이 표시됩니다.
제목 표시
각 페이지 탭에 제목을 추가하려면 파생 클래스에서 메서드를 PagerAdapter
구현 GetPageTitleFormatted
합니다. ViewPager
호출 GetPageTitleFormatted
(구현된 경우)을 호출하여 지정된 위치에 있는 페이지를 설명하는 제목 문자열을 가져옵니다. TreePagerAdapter.cs 클래스에 TreePagerAdapter
다음 메서드를 추가합니다.
public override Java.Lang.ICharSequence GetPageTitleFormatted(int position)
{
return new Java.Lang.String(treeCatalog[position].caption);
}
이 코드는 트리 카탈로그의 지정된 페이지(위치)에서 트리 캡션 문자열을 검색하고 Java String
로 변환한 후 해당 문자열을 ViewPager
반환합니다. 이 새 메서드를 사용하여 앱을 실행하면 각 페이지에 트리 캡션 PagerTabStrip
이 표시됩니다. 밑줄 없이 화면 맨 위에 트리 이름이 표시됩니다.
카탈로그에서 캡션된 각 트리 이미지를 보려면 앞뒤로 살짝 밀면 됩니다.
PagerTitleStrip 변형
PagerTitleStrip
는 현재 선택한 탭에 밑줄을 추가하는 것을 PagerTabStrip
제외하고는 매우 유사 PagerTabStrip
합니다. 위의 레이아웃으로 PagerTitleStrip
바꾸고 PagerTabStrip
앱을 다시 실행하여 다음과 같은 PagerTitleStrip
모양을 확인할 수 있습니다.
로 변환 PagerTitleStrip
하면 밑줄이 제거됩니다.
요약
이 연습에서는 s를 사용하지 Fragment
않고 기본 ViewPager
기반 앱을 빌드하는 방법에 대한 단계별 예제를 제공했습니다. 이미지 및 캡션 문자열을 포함하는 예제 데이터 원본, ViewPager
이미지를 표시하는 레이아웃 및 PagerAdapter
데이터 원본에 연결하는 하위 클래스를 제시했습니다 ViewPager
. 사용자가 데이터 집합을 탐색할 수 있도록 각 페이지의 맨 위에 이미지 캡션을 추가 PagerTabStrip
하거나 PagerTitleStrip
표시하는 방법을 설명하는 지침이 포함되었습니다.