在Android中正确实现ViewPager2 [英] Proper implementation of ViewPager2 in Android
问题描述
我开始了解 ViewPager2 ,并尝试了来实现它,但是没有找到合适的例子.
I came to know about ViewPager2 and tried to implement it, but didn't find any proper example.
任何人都可以告诉我如何使用它.
Can anyone tell me how can I use it.
我正在寻找正确的用法,而不是示例.
I am looking for proper usage, not an example.
推荐答案
UPDATE 7
如果要使用View Pager2实现Carousel,请查看我的回答
Check out my answer if you want to implement Carousel using View Pager2
如何在ViewPager2中使用TabLayout
How to use TabLayout with ViewPager2
示例代码
在 dependencies
Use below dependencies
implementation 'com.google.android.material:material:1.1.0-alpha08'
implementation 'androidx.viewpager2:viewpager2:1.0.0-beta02'
示例代码
XMl布局
XMl layout
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
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">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewpager"
app:layout_anchor="@id/tabs"
app:layout_anchorGravity="bottom"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
活动
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
import com.google.android.material.tabs.TabLayoutMediator
import com.google.android.material.tabs.TabLayout
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// setSupportActionBar(toolbar)
viewpager.adapter = AppViewPagerAdapter(supportFragmentManager, lifecycle)
TabLayoutMediator(tabs, viewpager, object : TabLayoutMediator.OnConfigureTabCallback {
override fun onConfigureTab(tab: TabLayout.Tab, position: Int) {
// Styling each tab here
tab.text = "Tab $position"
}
}).attach()
}
}
输出
来自文档
新功能
- 从右到左(RTL)布局支持
- 垂直方向支持
- notifyDataSetChanged完全可用
-
FragmentStateAdapter
替换FragmentStatePagerAdapter
-
RecyclerView.Adapter
替换PagerAdapter
-
registerOnPageChangeCallback
替换addPageChangeListener
FragmentStateAdapter
replacesFragmentStatePagerAdapter
RecyclerView.Adapter
replacesPagerAdapter
registerOnPageChangeCallback
replacesaddPageChangeListener
API更改
API changes
示例代码
为
ViewPager2
implementation 'androidx.viewpager2:viewpager2:1.0.0-alpha01'
布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
tools:context=".MainActivity">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
活动
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;
import java.util.ArrayList;
public class MyActivity extends AppCompatActivity {
ViewPager2 myViewPager2;
MyAdapter MyAdapter;
private ArrayList<String> arrayList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
myViewPager2 = findViewById(R.id.view_pager);
arrayList.add("Item 1");
arrayList.add("Item 2");
arrayList.add("Item 3");
arrayList.add("Item 4");
arrayList.add("Item 5");
MyAdapter = new MyAdapter(this, arrayList);
myViewPager2.setOrientation(ViewPager2.ORIENTATION_VERTICAL);
myViewPager2.setAdapter(MyAdapter);
}
}
MyAdapter
MyAdapter
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private Context context;
private ArrayList<String> arrayList = new ArrayList<>();
public MyAdapter(Context context, ArrayList<String> arrayList) {
this.context = context;
this.arrayList = arrayList;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.tvName.setText(arrayList.get(position));
}
@Override
public int getItemCount() {
return arrayList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView tvName;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
tvName = itemView.findViewById(R.id.tvName);
}
}
}
新功能
现在我们需要使用
ViewPager2.OnPageChangeCallback()
来获取ViewPager2
示例代码
myViewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
super.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
Log.e("Selected_Page", String.valueOf(position));
}
@Override
public void onPageScrollStateChanged(int state) {
super.onPageScrollStateChanged(state);
}
});
我们可以使用
myViewPager2.setOrientation()
示例代码
对于HORIZONTAL Orientation
使用
myViewPager2.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);
对于VERTICAL Orientation
使用
myViewPager2.setOrientation(ViewPager2.ORIENTATION_VERTICAL);
我们可以使用
notifyDataSetChanged
,与在RecyclerView.Adapter
示例代码以添加新项目
btnAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
arrayList.add("New ITEM ADDED");
MyAdapter.notifyDataSetChanged();
}
});
示例代码以删除新项目
btnRemove.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
arrayList.remove(3);
MyAdapter.notifyItemRemoved(3);
}
});
更新
如果要将Fragment
与ViewPager2
一起使用
,请尝试此操作
UPDATE
Try this if you want to use Fragment
with ViewPager2
首先创建一个
ViewPagerFragmentAdapter
类,该类扩展了FragmentStateAdapter
First create a
ViewPagerFragmentAdapter
class which extendsFragmentStateAdapter
import java.util.ArrayList;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.viewpager2.adapter.FragmentStateAdapter;
public class ViewPagerFragmentAdapter extends FragmentStateAdapter {
private ArrayList<Fragment> arrayList = new ArrayList<>();
public ViewPagerFragmentAdapter(@NonNull FragmentManager fragmentManager) {
super(fragmentManager);
}
@NonNull
@Override
public Fragment getItem(int position) {
return arrayList.get(position);
}
public void addFragment(Fragment fragment) {
arrayList.add(fragment);
}
@Override
public int getItemCount() {
return arrayList.size();
}
}
现在在您的活动中使用
Now use like this in your activity
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;
import neel.com.bottomappbar.R;
public class MainActivity extends AppCompatActivity {
ViewPager2 myViewPager2;
ViewPagerFragmentAdapter myAdapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myViewPager2 = findViewById(R.id.view_pager);
myAdapter = new ViewPagerFragmentAdapter(getSupportFragmentManager());
// add Fragments in your ViewPagerFragmentAdapter class
myAdapter.addFragment(new FragmentOne());
myAdapter.addFragment(new Fragmenttwo());
myAdapter.addFragment(new FragmentThree());
// set Orientation in your ViewPager2
myViewPager2.setOrientation(ViewPager2.ORIENTATION_VERTICAL);
myViewPager2.setAdapter(myAdapter);
}
}
有关更多信息,请检查此
for more information check this
- ViewPager2
- ViewPager2 under the Hood
- Hands on With ViewPager2
新功能
- 能够禁用用户输入(
setUserInputEnabled
,isUserInputEnabled
)
API更改
-
ViewPager2
最终班级
ViewPager2
class final
错误修复
-
FragmentStateAdapter
稳定性修复程序
FragmentStateAdapter
stability fixes
示例代码以禁止在viewpager2中滑动
myViewPager2.setUserInputEnabled(false);// SAMPLE CODE to disable swiping in viewpager2
myViewPager2.setUserInputEnabled(true);//SAMPLE CODE to enable swiping in viewpager2
更新3
Version 1.0.0-alpha03
新功能
- 以编程方式滚动ViewPager2的能力: fakeDragBy(offsetPx).
- Ability to programmatically scroll ViewPager2: fakeDragBy(offsetPx).
-
FragmentStateAdapter
现在需要一个Lifecycle
对象.添加了两个实用程序构造函数,以从主机FragmentActivity
或主机Fragment 获取它
FragmentStateAdapter
now requires aLifecycle
object. Two utility constructors added to obtain it from the hostFragmentActivity
or the host Fragment
API更改
API changes
示例代码
ViewPagerFragmentAdapter
ViewPagerFragmentAdapter
import java.util.ArrayList;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Lifecycle;
import androidx.viewpager2.adapter.FragmentStateAdapter;
public class ViewPagerFragmentAdapter extends FragmentStateAdapter {
private ArrayList<Fragment> arrayList = new ArrayList<>();
public ViewPagerFragmentAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) {
super(fragmentManager, lifecycle);
}
@NonNull
@Override
public Fragment getItem(int position) {
return arrayList.get(position);
}
public void addFragment(Fragment fragment) {
arrayList.add(fragment);
}
@Override
public int getItemCount() {
return arrayList.size();
}
}
MainActivity代码
MainActivity code
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager2.widget.ViewPager2;
import neel.com.bottomappbar.R;
public class MainActivity extends AppCompatActivity {
ViewPager2 myViewPager2;
ViewPagerFragmentAdapter myAdapter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myViewPager2=findViewById(R.id.view_pager);
myAdapter = new ViewPagerFragmentAdapter(getSupportFragmentManager(), getLifecycle());
// add Fragments in your ViewPagerFragmentAdapter class
myAdapter.addFragment(new FragmentOne());
myAdapter.addFragment(new Fragmenttwo());
myAdapter.addFragment(new FragmentThree());
myViewPager2.setOrientation(ViewPager2.ORIENTATION_VERTICAL);
myViewPager2.setAdapter(myAdapter);
}
}
更新4
-
ItemDecorator
的行为与RecyclerView
一致.
引入了 -
MarginPageTransformer
以便提供在页面之间(页面插图之外)创建空间的功能.
引入了 -
CompositePageTransformer
以提供组合多个PageTransformers
的功能
ItemDecorator
introduced with a behaviour consistent withRecyclerView
.MarginPageTransformer
introduced to provide an ability to create space between pages (outside of page inset).CompositePageTransformer
introduced to provide an ability to combine multiplePageTransformers
-
FragmentStateAdapter#getItem
方法重命名为FragmentStateAdapter#createFragment
-以前的方法名称被证明是过去漏洞的来源. -
OFFSCREEN_PAGE_LIMIT_DEFAULT
值从0更改为-1.如果使用OFFSCREEN_PAGE_LIMIT_DEFAULTconstant
,则无需更改客户端代码. FragmentStateAdapter#getItem
method renamed toFragmentStateAdapter#createFragment
- previous method name has proven to be a source of bugs in the past.OFFSCREEN_PAGE_LIMIT_DEFAULT
value changed from 0 to -1. No need for a client code change if theOFFSCREEN_PAGE_LIMIT_DEFAULTconstant
used.
API更改
API changes
示例代码
活动代码
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager2.widget.MarginPageTransformer;
import androidx.viewpager2.widget.ViewPager2;
import neel.com.bottomappbar.R;
public class MainActivity extends AppCompatActivity {
ViewPager2 myViewPager2;
ViewPagerFragmentAdapter myAdapter;
private ArrayList<Fragment> arrayList = new ArrayList<>();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myViewPager2 = findViewById(R.id.myViewPager2);
// add Fragments in your ViewPagerFragmentAdapter class
arrayList.add(new FragmentOne());
arrayList.add(new Fragmenttwo());
arrayList.add(new FragmentThree());
myAdapter = new ViewPagerFragmentAdapter(getSupportFragmentManager(), getLifecycle());
// set Orientation in your ViewPager2
myViewPager2.setOrientation(ViewPager2.ORIENTATION_HORIZONTAL);
myViewPager2.setAdapter(myAdapter);
myViewPager2.setPageTransformer(new MarginPageTransformer(1500));
}
}
ViewPagerFragmentAdapter
ViewPagerFragmentAdapter
import java.util.ArrayList;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Lifecycle;
import androidx.viewpager2.adapter.FragmentStateAdapter;
public class ViewPagerFragmentAdapter extends FragmentStateAdapter {
private ArrayList<Fragment> arrayList = new ArrayList<>();
public ViewPagerFragmentAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) {
super(fragmentManager, lifecycle);
}
@NonNull
@Override
public Fragment createFragment(int position) {
switch (position) {
case 0:
return new FragmentOne();
case 1:
return new Fragmenttwo();
case 2:
return new FragmentThree();
}
return null;
}
@Override
public int getItemCount() {
return 3;
}
}
这篇关于在Android中正确实现ViewPager2的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!