Android开发笔记-Viewpager(2)的双联动效果
ViewPager(2)双联动效果
为了满足伸手党的需求,先贴上代码
- 源码
BaseLinkPageChangeListener.java
public class BaseLinkPageChangeListener implements ViewPager.OnPageChangeListener {
private final ViewPager linkViewPager;
private final ViewPager selfViewPager;
private int marginX = 0;
public BaseLinkPageChangeListener(ViewPager selfViewPager,ViewPager linkViewPager){
this.linkViewPager = linkViewPager;
this.selfViewPager = selfViewPager;
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//计算移动值
marginX = ((selfViewPager.getWidth() selfViewPager.getPageMargin()) * position
positionOffsetPixels) * (linkViewPager.getWidth() linkViewPager.getPageMargin()) /
(selfViewPager.getWidth() selfViewPager.getPageMargin());
if (linkViewPager.getScrollX() != marginX) {
linkViewPager.scrollTo(marginX, 0);
}
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
}
Activity.java
public class ViewpagerActivity extends AppCompatActivity {
private ViewPager mViewpager1;
private ViewPager mViewpager2;
private ZoomOutPageTransformer zoomOutPageTransformer;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_viewpage1);
initView();
}
private void initView() {
mViewpager1 = findViewById(R.id.viewpager1);
mViewpager2 = findViewById(R.id.viewpager2);
mViewpager1.setAdapter(new TopViewPgaerAdapter(this));
mViewpager2.setAdapter(new BottomViewPagerAdapter(this));
mViewpager1.setOffscreenPageLimit(5);
mViewpager2.setOffscreenPageLimit(5);
BaseLinkPageChangeListener baseLinkPageChangeListener = new BaseLinkPageChangeListener(mViewpager1, mViewpager2);
mViewpager1.addOnPageChangeListener(baseLinkPageChangeListener);
BaseLinkPageChangeListener baseLinkPageChangeListener1 = new BaseLinkPageChangeListener(mViewpager2, mViewpager1);
mViewpager2.addOnPageChangeListener(baseLinkPageChangeListener1);
}
private static class TopViewPgaerAdapter extends PagerAdapter {
private Context context;
public TopViewPgaerAdapter(Context context) {
this.context = context;
}
@Override
public int getCount() {
return 5;
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
// 判断是不是同一个视图
return view == object;
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
View inflate = LayoutInflater.from(context).inflate(R.layout.item_top, container, false);
container.addView(inflate);
return inflate;
}
}
private static class BottomViewPagerAdapter extends PagerAdapter {
private Context context;
public BottomViewPagerAdapter(Context context) {
this.context = context;
}
@Override
public int getCount() {
return 5;
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
// 判断是不是同一个视图
return view == object;
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
View inflate = LayoutInflater.from(context).inflate(R.layout.item_bottom, container, false);
container.addView(inflate);
return inflate;
}
}
}
activity_viewpager.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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=".viewpageruse1.ViewpagerActivity">
<androidx.viewpager.widget.ViewPager
android:id="@ id/viewpager1"
android:layout_width="match_parent"
android:layout_height="200dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.viewpager.widget.ViewPager
android:id="@ id/viewpager2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="30dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/viewpager1" />
</androidx.constraintlayout.widget.ConstraintLayout>
item_top.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="200dp"
android:layout_height="200dp"
android:background="@color/teal_200"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
item_bottom.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="20dp">
<TextView
android:layout_width="200dp"
android:layout_height="200dp"
android:background="@color/purple_500"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
- 分析
实现思路: 通过
ViewPager
的OnPageChangeListener
监听回调的onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
方法来实现联动效果,关键代码如下:
selfViewPager.getWidth() selfViewPager.getPageMargin()
偏移比例(selfViewPager.getWidth() selfViewPager.getPageMargin()) * position positionOffsetPixels
表示当前手指触摸的ViewPager的总偏移距离linkViewPager.getWidth() linkViewPager.getPageMargin()
表示联动的ViewPager的大小
//计算移动值'
//
marginX = ((selfViewPager.getWidth() selfViewPager.getPageMargin()) * position
positionOffsetPixels) * (linkViewPager.getWidth() linkViewPager.getPageMargin()) /
(selfViewPager.getWidth() selfViewPager.getPageMargin());
if (linkViewPager.getScrollX() != marginX) {
linkViewPager.scrollTo(marginX, 0);
}
-
测试
-
问题
-
问题产生原因分析
暂未找到原因 -
解决方案(先上代码)
activity_viewpager.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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"
android:splitMotionEvents="false"
tools:context=".viewpageruse1.Viewpager1Activity">
<com.ycy.customviewstudy.viewpageruse1.MyLinearLayout
android:id="@ id/mLinear1"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:background="@color/purple_500"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.viewpager.widget.ViewPager
android:id="@ id/viewpager1"
android:layout_width="match_parent"
android:layout_height="200dp" />
</com.ycy.customviewstudy.viewpageruse1.MyLinearLayout>
<com.ycy.customviewstudy.viewpageruse1.MyLinearLayout
android:id="@ id/mLinear2"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/mLinear1">
<androidx.viewpager.widget.ViewPager
android:id="@ id/viewpager2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="30dp" />
</com.ycy.customviewstudy.viewpageruse1.MyLinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
MyLinearLayout.java
public class MyLinearLayout extends LinearLayout {
private MyLinearLayout otherLinearLayout;
public MyLinearLayout(Context context) {
super(context);
}
public MyLinearLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public MyLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public MyLinearLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public LinearLayout getOtherLinearLayout() {
return otherLinearLayout;
}
public void setOtherLinearLayout(MyLinearLayout otherLinearLayout) {
this.otherLinearLayout = otherLinearLayout;
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (otherLinearLayout != null) {
otherLinearLayout.fakeTouchEvent(ev);
}
return super.dispatchTouchEvent(ev);
}
public void fakeTouchEvent(MotionEvent ev) {
super.dispatchTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return super.onTouchEvent(event);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return super.onInterceptTouchEvent(ev);
}
}
Activity.java
public class ViewPagerActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_viewpage);
MyLinearLayout mLinear1 = findViewById(R.id.mLinear1);
MyLinearLayout mLinear2 = findViewById(R.id.mLinear2);
mLinear1.setOtherLinearLayout(mLinear2);
mLinear2.setOtherLinearLayout(mLinear1);
ViewPager mViewpager1 = findViewById(R.id.viewpager1);
ViewPager mViewpager2 = findViewById(R.id.viewpager2);
mViewpager1.setAdapter(new TopViewPgaerAdapter(this));
mViewpager2.setAdapter(new BottomViewPagerAdapter(this));
mViewpager1.setOffscreenPageLimit(5);
mViewpager2.setOffscreenPageLimit(5);
}
private static class TopViewPgaerAdapter extends PagerAdapter {
private Context context;
public TopViewPgaerAdapter(Context context) {
this.context = context;
}
@Override
public int getCount() {
return 5;
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
// 判断是不是同一个视图
return view == object;
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
View inflate = LayoutInflater.from(context).inflate(R.layout.item_top, container, false);
container.addView(inflate);
return inflate;
}
}
private static class BottomViewPagerAdapter extends PagerAdapter {
private Context context;
public BottomViewPagerAdapter(Context context) {
this.context = context;
}
@Override
public int getCount() {
return 5;
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
// 判断是不是同一个视图
return view == object;
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
View inflate = LayoutInflater.from(context).inflate(R.layout.item_parent, container, false);
container.addView(inflate);
return inflate;
}
}
}
问题: 使用上述代码虽然解决了联动问题,但是在多指滑动时会出现如下问题
解决方案:
禁用多指触控
android:splitMotionEvents="false"
关键代码:
public void setOtherLinearLayout(MyLinearLayout otherLinearLayout) {
this.otherLinearLayout = otherLinearLayout;
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (otherLinearLayout != null) {
otherLinearLayout.fakeTouchEvent(ev);
}
return super.dispatchTouchEvent(ev);
}
public void fakeTouchEvent(MotionEvent ev) {
super.dispatchTouchEvent(ev);
}
可能连你页没有想到,竟然能使用这么少的代码的量解决了联动的问题,而且滑动起来还很丝滑,viewpager2也是使用这种方式来解决的,而且Viewpager2运行起来更加的丝滑,毫无违和感,这一切还得归功于享学课堂的Colin老师,目前网上大部分的教程在viewpager上实现双联动都是使用滑动监听回调和继承viewpager的方式来解决问题。自从加入了享学课堂,才两个多月老板就给涨了两千薪水,之前同事做不出来的功能,我参考享学课堂老师讲的都解决了,哈哈,以后我就要跟着Colin老师学习下去。
废话不多说,viewpager2实现双联动直接上代码
activity_viewpager2.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.qdkj.viewpager2use.MyLinearLayout
android:id="@ id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:layout_marginBottom="10dp">
<androidx.viewpager2.widget.ViewPager2
android:id="@ id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.qdkj.viewpager2use.MyLinearLayout>
<com.qdkj.viewpager2use.MyLinearLayout
android:id="@ id/linearLayout2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:layout_weight="1">
<androidx.viewpager2.widget.ViewPager2
android:id="@ id/viewPager2"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.qdkj.viewpager2use.MyLinearLayout>
</LinearLayout>
fragment_test.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
tools:context=".TestFragment">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:textSize="20dp"
android:text="@string/hello_blank_fragment" />
</FrameLayout>
ViewPager2Activity.java
public class ViewPager2Activity extends AppCompatActivity {
private List<Fragment> fragments = new ArrayList<>();
private List<Fragment> fragments2 = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager2 viewPager = findViewById(R.id.viewPager);
ViewPager2 viewPager2 = findViewById(R.id.viewPager2);
MyLinearLayout linearLayout1 = findViewById(R.id.linearLayout1);
MyLinearLayout linearLayout2 = findViewById(R.id.linearLayout2);
linearLayout1.setOtherLinearLayout(linearLayout2);
linearLayout2.setOtherLinearLayout(linearLayout1);
fragments.add( new OneFragment());
fragments.add( new TwoFragment());
fragments.add( new ThreeFragment());
fragments2.add( new OneFragment());
fragments2.add( new TwoFragment());
fragments2.add( new ThreeFragment());
viewPager.setAdapter(new ViewPagerAdapter(this,fragments));
viewPager2.setAdapter(new ViewPagerAdapter(this,fragments2));
}
}
ViewPagerAdapter.java
public class ViewPagerAdapter extends FragmentStateAdapter {
private final List<Fragment> fragments;
public ViewPagerAdapter(@NonNull FragmentActivity fragmentActivity, List<Fragment> fragments) {
super(fragmentActivity);
this.fragments = fragments;
}
@NonNull
@Override
public Fragment createFragment(int position) {
return fragments.get(position);
}
@Override
public int getItemCount() {
return fragments == null ? 0 : fragments.size();
}
}
OneFragment.java
public class TestFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_test, container, false);
}
}
TwoFragment.java
public class TwoFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_test, container, false);
}
}
ThreeFragment.java
public class ThreeFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_test, container, false);
}
}
效果:
看到没,要多丝滑,就有多丝滑,而且viewpager和viewpager2都是可以通用的,简简单单的代码就实现了,这一切都得感谢享学课堂的Colin老师,他们有着丰富的Android开发经验和前沿的开发技术,此刻都是独一无二的技术,好了,不多说了,我得找老师学习高级技术去了,学到了再分享给大家
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgfafih
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01