学习笔记-------------viewpager2遇到的坑

先上结果:
在这里插入图片描述

一、bug分析

这个项目一共遇到两个问题:
1.Imageview使用混合图片的时候state_checked这个属性在代码中setSelected(true)是无效的,具体原因没有找到请添加图片描述请添加图片描述
请添加图片描述
于是我就用state_pressed这个属性替代
在这里插入图片描述
但是又产生了一个问题,按压按钮是会变色了,松手后又弹回原来的颜色,于是我就把点击事件改为触摸事件
在这里插入图片描述
这样一来触摸就可以直接捕获到状态。
2.text使用setTextcolor(R.color.xxx)的时候变色失效
在这里插入图片描述
原因是setTextcolor接受的是16进制的数据,而不是资源id,如果要用需要调用getColor方法
在这里插入图片描述

二、实现效果

好了,话不多说,开始正文
· 在activity中添加viewpager2控件(旧版sdk可能需要在build.gradle中添加对应的控件包)
在这里插入图片描述

· 准备八张图片(阿里巴巴矢量图标库),在drawable中创建四组图片资源文件(点击改变图片背景)

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/faxian_on"  android:state_pressed="true"/>
    <item android:drawable="@drawable/faxian"  />
</selector>

· 创建导航栏

<?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="horizontal">
    <LinearLayout
        android:id="@+id/weixin"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical">
        //添加混合图片weixinliaotian_fix
        <ImageView
            android:id="@+id/weixin_button"
            android:layout_gravity="center_horizontal"
            android:background="@drawable/weixinliaotian_fix"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TextView
            android:text="微信"
            android:id="@+id/t1"
            android:layout_gravity="center_horizontal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>
    <LinearLayout
        android:id="@+id/tongxunlu"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical">
        <ImageView
            android:id="@+id/tongxunlu_button"
            android:layout_gravity="center_horizontal"
            android:background="@drawable/tongxunlu_fix"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TextView
            android:id="@+id/t2"
            android:layout_gravity="center_horizontal"
            android:text="通讯录"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>
    <LinearLayout
        android:id="@+id/faxian"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical">
        <ImageView
            android:id="@+id/faxian_button"
            android:layout_gravity="center_horizontal"
            android:background="@drawable/faxian_fix"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TextView
            android:id="@+id/t3"
            android:layout_gravity="center_horizontal"
            android:text="发现"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>
    <LinearLayout
        android:id="@+id/wode"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical">
        <ImageView
            android:id="@+id/wode_button"
            android:layout_gravity="center_horizontal"
            android:background="@drawable/wode_fix"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TextView
            android:id="@+id/t4"
            android:layout_gravity="center_horizontal"
            android:text="我"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>
</LinearLayout>

· 在活动界面引入导航栏
在这里插入图片描述
· 在activity中获取viewpager2对象并设置adapter

 viewPager2 = findViewById(R.id.vp2);
  viewpageradapter = new viewpageradapter(getSupportFragmentManager(), getLifecycle(), fragmentList);
  viewPager2.setAdapter(viewpageradapter);

· 创建Fragment(就只有一个text控件)

· 创建适配器 (继承FragmentStateAdapter而不是FragmentPagerAdapter
FragmentPageAdapter和FragmentPageStateAdapter的区别:

FragmentPageAdapter在每次切换页面的的时候,是将Fragment进行分离,适合页面较少的Fragment使用以保存一些内存,对系统内存不会多大影响

FragmentPageStateAdapter在每次切换页面的时候,是将Fragment进行回收,适合页面较多的Fragment使用,这样就不会消耗更多的内存

public class viewpageradapter extends FragmentStateAdapter {
	//接收fragment
    List<Fragment> fragmentList;
    
    public viewpageradapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle,List<Fragment> fragmentList) {
        super(fragmentManager, lifecycle);
        this.fragmentList=fragmentList;
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
    //返回对应位置的fragment界面
        return fragmentList.get(position);
    }

    @Override
    public int getItemCount() {
    //返回fragment数量
        return fragmentList.size();
    }
}

· 重点来了 实现fragment和导航栏按钮的联动效果
要用到这个回调函数:实现三个方法,我们需要实现的只有改变页面的方法

 viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
 		
 		/**
         * 这个方法负责侦听页面的偏移量
         * @param position 当前显示的第一页的位置索引 如果 positionOffset 非零,则页面位置+1 将可见。
         * @param positionOffset [0, 1) 中的值指示从页面位置的偏移量。
         * @param positionOffsetPixels 以像素为单位的值,指示与位置的偏移量。
         */
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                super.onPageScrolled(position, positionOffset, positionOffsetPixels);
            }
		//解决getcolor的版本问题(可以删掉)
            @RequiresApi(api = Build.VERSION_CODES.M)
         //这个方法负责切换页面 poistion从0开始
            @Override
            public void onPageSelected(int position) {
                changetab(position);
            }
		//当滚动状态改变时调用。 用于发现用户何时开始拖动、何时开始假拖动、何时寻呼机自动稳定到当前页面,或何时完全停止/空闲。
            @Override
            public void onPageScrollStateChanged(int state) {
                super.onPageScrollStateChanged(state);
            }
        });
    }

这个是按钮触摸事件的触发方法

 @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        changetab(view.getId());
        return false;
    }

这个方法负责接收两种不同的参数,一是当前的滚动页面位置,二是按钮id
页面滚动调用按钮设置为按压状态,按钮按下将页面滚动至对应页面,从而实现联动效果。

	//上面两个引用为了设置文字颜色
 	@RequiresApi(api = Build.VERSION_CODES.M)
    @SuppressLint("ResourceAsColor")
   
    private void changetab(int position) {
    	//每次滚动之前把按压状态设置为false 文字颜色设置为初始颜色
        current.setPressed(false);
        currenttext.setTextColor(MainActivity.this.getColor(black));
        switch (position) {
            case R.id.weixin:
            	//传入按钮id不用保存当前状态/颜色的原因是 页面滚动会自动调用回调函数触发上面三个方法,也就是说会再次调用这个changetab方法,不过传入对应的position值 
                viewPager2.setCurrentItem(0);
                break;
            case 0:
            	//设置文字颜色
                t1.setTextColor(MainActivity.this.getColor(green));
                //设置imageview为按压状态
                weixin_button.setPressed(true);
                //保存当前状态/颜色
                current = weixin_button;
                currenttext = t1;
                break;
            case R.id.tongxunlu:
                viewPager2.setCurrentItem(1);
                break;
            case 1:
                t2.setTextColor(MainActivity.this.getColor(green));
                tongxunlu_button.setPressed(true);
                current = tongxunlu_button;
                currenttext = t2;
                break;
            case R.id.faxian:
                viewPager2.setCurrentItem(2);
                break;
            case 2:
                t3.setTextColor(MainActivity.this.getColor(green));
                faxian_button.setPressed(true);
                current = faxian_button;
                currenttext = t3;
                break;
            case R.id.wode:
                viewPager2.setCurrentItem(3);
                break;
            case 3:
                t4.setTextColor(MainActivity.this.getColor(green));
                wode_button.setPressed(true);
                current = wode_button;
                currenttext = t4;
                break;
        }

    }

三、源码

源码如下:

Maintivity

public class MainActivity extends AppCompatActivity implements View.OnTouchListener {
    List<Fragment> fragmentList;//fragment集合 传参给adapter
    viewpageradapter viewpageradapter;
    ViewPager2 viewPager2;
    LinearLayout weixin, tongxunlu, faxian, wode;
    ImageView weixin_button, tongxunlu_button, faxian_button, wode_button, current;//current记录当前imageview状态
    TextView t1, t2, t3, t4, currenttext;//currenttext记录当前text状态

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
        weixin.setOnTouchListener(this);
        tongxunlu.setOnTouchListener(this);
        faxian.setOnTouchListener(this);
        wode.setOnTouchListener(this);
        viewPager2 = findViewById(R.id.vp2);
        viewpageradapter = new viewpageradapter(getSupportFragmentManager(), getLifecycle(), fragmentList);
        viewPager2.setAdapter(viewpageradapter);
        viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                super.onPageScrolled(position, positionOffset, positionOffsetPixels);
            }

            @RequiresApi(api = Build.VERSION_CODES.M)
            @Override
            public void onPageSelected(int position) {
                changetab(position);
            }


            @Override
            public void onPageScrollStateChanged(int state) {
                super.onPageScrollStateChanged(state);
            }
        });
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    @SuppressLint("ResourceAsColor")
    private void changetab(int position) {
        current.setPressed(false);
        currenttext.setTextColor(MainActivity.this.getColor(black));
        switch (position) {
            case R.id.weixin:
                viewPager2.setCurrentItem(0);
                Log.d("TAG", "changetab:weixin按压 " + weixin_button.isPressed());
                break;
            case 0:
                t1.setTextColor(MainActivity.this.getColor(green));
                weixin_button.setPressed(true);
                Log.d("TAG", "changetab:weixin滑动 " + weixin_button.isPressed());
                current = weixin_button;
                currenttext = t1;
                break;
            case R.id.tongxunlu:
                viewPager2.setCurrentItem(1);
                Log.d("TAG", "changetab:tongxunlu按压 " + tongxunlu_button.isPressed());
                break;
            case 1:
                t2.setTextColor(MainActivity.this.getColor(green));
                tongxunlu_button.setPressed(true);
                Log.d("TAG", "changetab:tongxunlu滑动 " + tongxunlu.isPressed());
                current = tongxunlu_button;
                currenttext = t2;
                break;
            case R.id.faxian:
                viewPager2.setCurrentItem(2);
                Log.d("TAG", "changetab:faxian按压 " + faxian_button.isPressed());
                break;
            case 2:
                t3.setTextColor(MainActivity.this.getColor(green));
                faxian_button.setPressed(true);
                Log.d("TAG", "changetab:faxian滑动 " + faxian_button.isPressed());
                current = faxian_button;
                currenttext = t3;
                break;
            case R.id.wode:
                viewPager2.setCurrentItem(3);
                Log.d("TAG", "changetab:wode按压 " + wode_button.isPressed());
                break;
            case 3:
                t4.setTextColor(MainActivity.this.getColor(green));
                wode_button.setPressed(true);
                Log.d("TAG", "changetab:wode滑动 " + wode_button.isPressed());
                current = wode_button;
                currenttext = t4;
                break;
        }

    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    @SuppressLint("ResourceAsColor")
    private void init() {
        fragmentList = new ArrayList<>();
        fragmentList.add(BlankFragment.newInstance("微信"));
        fragmentList.add(BlankFragment.newInstance("联系人"));
        fragmentList.add(BlankFragment.newInstance("发现"));
        fragmentList.add(BlankFragment.newInstance("我的"));
        weixin = findViewById(R.id.weixin);
        tongxunlu = findViewById(R.id.tongxunlu);
        faxian = findViewById(R.id.faxian);
        wode = findViewById(R.id.wode);
        weixin_button = findViewById(R.id.weixin_button);
        tongxunlu_button = findViewById(R.id.tongxunlu_button);
        faxian_button = findViewById(R.id.faxian_button);
        wode_button = findViewById(R.id.wode_button);
        t1 = findViewById(R.id.t1);
        t2 = findViewById(R.id.t2);
        t3 = findViewById(R.id.t3);
        t4 = findViewById(R.id.t4);
        weixin_button.setPressed(true);
        t1.setTextColor(MainActivity.this.getColor(green));
        current = weixin_button;
        currenttext = t1;
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        changetab(view.getId());
        return false;
    }
}

Maintivity layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    tools:context=".MainActivity">

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/vp2"
        android:layout_height="0dp"
        android:layout_weight="11"
        android:layout_width="match_parent"/>
    <include
        layout="@layout/navigation"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:layout_width="match_parent"/>
</LinearLayout>

viewpagerAdapter

```java
public class viewpageradapter extends FragmentStateAdapter {

    List<Fragment> fragmentList;

    public viewpageradapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle,List<Fragment> fragmentList) {
        super(fragmentManager, lifecycle);
        this.fragmentList=fragmentList;
    }

    @NonNull
    @Override
    public Fragment createFragment(int position) {
        return fragmentList.get(position);
    }

    @Override
    public int getItemCount() {
        return fragmentList.size();
    }
}

viewpagerAdapter layout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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=".BlankFragment">

    <TextView
        android:id="@+id/ft1"
        android:text="nice"
        android:layout_centerInParent="true"
        android:textSize="50sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>

navigation(只有布局)

<?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="horizontal">

    <LinearLayout
        android:id="@+id/weixin"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical">
        <ImageView
            android:id="@+id/weixin_button"
            android:layout_gravity="center_horizontal"
            android:background="@drawable/weixinliaotian_fix"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TextView
            android:text="微信"
            android:id="@+id/t1"
            android:layout_gravity="center_horizontal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>
    <LinearLayout
        android:id="@+id/tongxunlu"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical">
        <ImageView
            android:id="@+id/tongxunlu_button"
            android:layout_gravity="center_horizontal"
            android:background="@drawable/tongxunlu_fix"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TextView
            android:id="@+id/t2"
            android:layout_gravity="center_horizontal"
            android:text="通讯录"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>
    <LinearLayout
        android:id="@+id/faxian"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical">
        <ImageView
            android:id="@+id/faxian_button"
            android:layout_gravity="center_horizontal"
            android:background="@drawable/faxian_fix"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TextView
            android:id="@+id/t3"
            android:layout_gravity="center_horizontal"
            android:text="发现"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>
    <LinearLayout
        android:id="@+id/wode"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical">
        <ImageView
            android:id="@+id/wode_button"
            android:layout_gravity="center_horizontal"
            android:background="@drawable/wode_fix"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TextView
            android:id="@+id/t4"
            android:layout_gravity="center_horizontal"
            android:text="我"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>

</LinearLayout>

图片和color就不放了

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值