Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
ViewPager2について調べてみた
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Kazuki Nishida
March 14, 2019
Programming
1.5k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
ViewPager2について調べてみた
Kazuki Nishida
March 14, 2019
Other Decks in Programming
See All in Programming
Mujeres en SEO Summit 2026 - Greatest Disaster Hits en Web Performance
guaca
0
200
Datadog × OpenTelemetry 入門と実践のあいだ
kn_to_maxpno
1
170
正しくソフトウェアを作る、前提を疑うための認知の視点 / doubt-premise
minodriven
21
7k
Semantic Version 単位で戦略を柔軟に変えて、パッケージアップデートを自動化する
daitasu
1
300
Observability in Practice:Grafana 與 Edge Device SRE 的那些事
blueswen
0
170
LaravelLive Japan の裏方のすべて — 第188回 PHP勉強会@東京 (2026-06-24)
suguruooki
2
110
Honoでのサプライチェーン侵害対策 〜 3つのライブラリに学ぶ
yusukebe
7
1.4k
ふつうのFeature Flag実践入門
irof
8
4.2k
IBM Bobを活用したレガシーアプリの最新化
oniak3ibm
PRO
1
210
AI時代のUIはどこへ行く?その2!
yusukebe
22
7.5k
Make SRE Operations Easier with Azure SRE Agent
kkamegawa
0
7.7k
気づいたらRubyで100作品 ー クリエイティブコーディングが生活の一部になるまで / 100 Ruby Sketches Later: How Creative Coding Became Part of My Life
chobishiba
3
610
Featured
See All Featured
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
750
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Designing for Timeless Needs
cassininazir
1
260
Being A Developer After 40
akosma
91
590k
Build your cross-platform service in a week with App Engine
jlugia
234
18k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.4k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
10k
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
540
Paper Plane
katiecoart
PRO
1
52k
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
490
Reality Check: Gamification 10 Years Later
codingconduct
0
2.2k
Transcript
ViewPager2について調べてみた Kazuki Nishida(@kazkn_24)
みんな大好きViewPager • ViewPagerとはAndroidにおいて横方向のページャー画面を実装する為に使われる Widget • ListViewやRecyclerViewと同じようにAdapterを用いて表示要素の取得を行う • ViewPager用のAdapterとしてはFragmentPagerAdapterもしくは FragmentStatePagerAdapterを用いて1ページ=1Fragmentとして実装を行う for
Beginners
ViewPager2とは • RecyclerViewの機能を用いて作成された新しいViewPager • AdapterはRecyclerViewと同じRecyclerView.Adapterを継承したものを使用する • RTLレイアウト対応 • 縦方向のPager機能も簡単時実現可能 •
現時点(2019/03/10)では1.0.0-alpha01 https://developer.android.com/jetpack/androidx/releases/viewpager2
RecyclerViewとの関係
レシピ名 public class ViewPager2 extends ViewGroup { private RecyclerView mRecyclerView;
… private void initialize(Context context, AttributeSet attrs) { mRecyclerView = new RecyclerView(context) { … }; mRecyclerView.setId(ViewCompat.generateViewId()); mLayoutManager = new LinearLayoutManager(context); mRecyclerView.setLayoutManager(mLayoutManager); setOrientation(context, attrs); … attachViewToParent(mRecyclerView, 0, mRecyclerView.getLayoutParams()); } public final void setAdapter(@Nullable Adapter adapter) { mRecyclerView.setAdapter(adapter); } } 内部にRecyclerViewを持っている • ViewGroupを継承しており、子Viewとして RecyclerView生成する • LayoutManagerはLinerLayoutManager固定 • ViewPager2にセットしたAdapterは単純に内 部のRecyclerViewにセットされるだけ • RecyclerViewは(いまのところ)外部からは取 得する方法なし
レシピ名 public class ViewPager2 extends ViewGroup { private RecyclerView mRecyclerView;
… private void initialize(Context context, AttributeSet attrs) { … new PagerSnapHelper().attachToRecyclerView(mRecyclerView); … } } ページスナップ(1ページごとにスクロールが 止まるやつ) • PagerSnapHelperクラスで実現されているお り、PagerSnapHelper内部でRecyclerViewに 対してScrollListenerなどのコールバックを設 定している • attachToRecyclerView()のパラメータは RecyclerViewなのでViewPager2とは関係な いRecyclerViewにも適用は可能?
使い方
レシピ名 viewPager.adapter = object : RecyclerView.Adapter<ViewHolder>() { override fun onCreateViewHolder(parent:
ViewGroup, viewType: Int): ViewHolder { return ViewHolder( LayoutInflater.from(this@ViewPagerActivity1).inflate( R.layout.pager_item_text, parent, false ) ) } override fun getItemCount() = 5 override fun onBindViewHolder(holder: ViewHolder, position: Int) { val binding = DataBindingUtil.bind<PagerItemTextBinding>(holder.root) ?.apply { text = "page$position" } } } RecyclerView.Adapterを使用する例 • RecyclerView使用時と同じようなAdapterを 作ればOK • 各ページはRecyclerView.ViewHolderによっ て提供されるView
レシピ名 <?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="text" type="String"/>
</data> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="@{text}" android:gravity="center"/> </layout> ページ側Layoutを作成する際の注意点 • ページ用に指定するLayoutを指定する場合、 ルートViewのサイズはwidth, heightともに match_parentを指定する • そうしないとIllegalStateExceptionで死ぬ
レシピ名 viewPager.orientation = ViewPager2.ORIENTATION_VERTICAL <androidx.viewpager2.widget.ViewPager2 … android:orientation="vertical" … /> 縦方向にスクロールする
• ページ用に指定するLayoutを指定する場合、 ルートViewのサイズはwidth, heightともに match_parentを指定する コードで指定 XMLで指定
レシピ名 viewPager.adapter = object : FragmentStateAdapter(supportFragmentManager) { override fun getItem(position:
Int) = PageFragment.newInstance("page$position") override fun getItemCount() = 5 } … class PageFragment : Fragment() { … override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) = DataBindingUtil.inflate<PagerItemTextBinding>(inflater, R.layout.pager_item_text, container, false).apply { text = arguments?.getString(ARG_TEXT) }.root } } FragmentStateAdapterを使用する例 • Fragmentを使用してページを作成する場合は FragmentStateAdapterを使用する • 現時点ではOffscreenPageLimitの仕組みが 存在しないため、隣接するページのFragment の生成は実際のスクロール開始時に行われる • 生成済みのページに関してはRecyclerViewで いくつかキャッシュされるが、 RecyclerView.setItemViewCacheSize()や、 LinearLayoutManager.getExtraLayoutSpace ()のOverrideでキャッシュ数を調整したりは出 来ない
いまのところ出来ない事
いまのところ未実装 • no offscreen limit control • needs better TabLayout
integration • no pageWidth setter (forced 100%/100%) • page transformer: no hardware/software layer choice; no reverse drawing order https://developer.android.com/jetpack/androidx/releases/viewpager2 ※もうちょい色々書いてあります。 これ
Groupie使える?
レシピ名 viewPager.adapter = GroupAdapter<ViewHolder>().apply { add(TextItem("page1")) add(TextItem("page2")) add(TextItem("page3")) add(TextItem("page4")) add(TextItem("page5"))
} } private class TextItem( private val text: String ) : BindableItem<PagerItemTextBinding>() { override fun getLayout() = R.layout.pager_item_text override fun bind(viewBinding: PagerItemTextBinding, position: Int) { viewBinding.text = text } } 単純な使用例 • GroupieのGroupAdapterは RecyclerView.Adapterを継承しているので普 通に使える • 自前でAdapterを実装するよりは少し楽かもし れない。
レシピ名 viewPager.adapter = GroupAdapter<ViewHolder>().apply { add(TextItem("page1")) add(ImageItem("world_press17.jpg")) add(TextItem("page3")) add(ImageItem("181126jpower.jpg")) add(TextItem("page5"))
add(ImageItem("img_473_1488875864.jpg")) } 単純な使用例2 • 当然、異なる形のページをGroupieのItemとし て表現する事も可能 • ViewTypeが複数ある場合は自前でAdapter 作るよりもだいぶ便利かもしれない
レシピ名 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) … groupLayoutManager
= GridLayoutManager(this, groupAdapter.spanCount).apply { spanSizeLookup = groupAdapter.spanSizeLookup } ) … recyclerView.apply { layoutManager = groupLayoutManager } グリッド表示 • LayoutManagerがLinerLayoutManagerなの で実現できません!!!! Groupieのサンプルコードから これ
レシピ名 viewPager.adapter = GroupAdapter<ViewHolder>().apply { add(Section().apply { setHeader(TextItem("header")) setFooter(TextItem("footer")) add(TextItem("page1"))
add(TextItem("page2")) add(TextItem("page3")) }) } セクションヘッダー、フッター付き • 使えるけども、 Header→Item→Item→Item→Footerと表示 されるだけなので、まぁ、なんか使えるかもしれ ない…
感想 • 基本的には実績のあるRecyclerViewの実装に依存するので、alphaだけど安定性 は高いと思う • 旧ViewPagerに実装されていたpageWidthなどの設定が出来ないので、ちょっと凝っ たレイアウトの場合はまだ旧ViewPagerを使うほうがいい • Offscreen Page
Limitの仕組み、キャッシュなどの動きを考えるとページの構成物 がImageViewだけみたいな場合にはViewPager2、Fragment内に複雑なレイアウトを 必要とする場合はViewPagerが良いのではないかな。いまのところ。