【Android】ViewPager2与Fragment的组合
三三要成为安卓糕手
一:需求
实现像抖音这种界面,左滑可以进入商城,关注,右滑…;顶部的选择,随着页面的滑动而改变;反之亦是如此
二:使用方法
1:定义、依赖、继承关系
本质是一个容器,在xml布局中<ViewPager2…;优先使用ViewPage2
<androidx.viewpager2.widget.ViewPager2android:layout_below="@+id/radio_group"android:id="@+id/view_pager"android:layout_width="match_parent"android:layout_height="match_parent" />
老的工程需要引入这个包
implementation 'com.google.android.material:material:1.10.0'
继承关系
三:总体代码
public class TableActivity extends AppCompatActivity {private static final String TAG = "TableActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_table);RadioButton rbRecommend = findViewById(R.id.rb_recommend);RadioButton rbShop = findViewById(R.id.rb_shop);RadioButton rbFollow = findViewById(R.id.rb_follow);RadioButton rbCity = findViewById(R.id.rb_city);RadioButton rbChioce = findViewById(R.id.rb_choice);ViewPager2 viewPager = findViewById(R.id.view_pager);viewPager.setAdapter(new FragmentStateAdapter(this) {@NonNull@Overridepublic Fragment createFragment(int position) {return new BlueFragment();}@Overridepublic int getItemCount() {return 5;}});viewPager.setOrientation(ViewPager2.ORIENTATION_VERTICAL);
// viewPager.setUserInputEnabled(false);RadioGroup radioGroup = findViewById(R.id.radio_group);//设置Radio勾选监听器:让ViewPager随着RadioGroup的改变而改变radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {@Overridepublic void onCheckedChanged(RadioGroup group, int checkedId) {if (checkedId == R.id.rb_recommend) {//通过代码指定viewpager显示哪一个positionviewPager.setCurrentItem(0);} else if (checkedId == R.id.rb_shop) {viewPager.setCurrentItem(1);} else if (checkedId == R.id.rb_follow) {viewPager.setCurrentItem(2);} else if (checkedId == R.id.rb_city) {viewPager.setCurrentItem(3);} else if (checkedId == R.id.rb_choice) {viewPager.setCurrentItem(4);}}});//设置注册器页面改变回调提醒:让ViewPager随着RadioGroup的改变而改变viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {/*** 滑动过程中会被调用*/@Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {super.onPageScrolled(position, positionOffset, positionOffsetPixels);Log.i(TAG, "onPageScrolled: position" + position);}/*** 页面被选中时调用* @param position Position index of the new selected page.*/@Overridepublic void onPageSelected(int position) {super.onPageSelected(position);switch (position) {case 0:rbRecommend.setChecked(true);break;case 1:rbShop.setChecked(true);break;case 2:rbFollow.setChecked(true);break;case 3:rbCity.setChecked(true);break;case 4:rbChioce.setChecked(true);break;}}/*** 滑动状态变化* @param state*/@Overridepublic void onPageScrollStateChanged(int state) {super.onPageScrollStateChanged(state);}});}
}
1:设置适配器
借鉴之前处理item的思路,利用适配器装view视图
viewPager.setAdapter(new FragmentStateAdapter(this) {@NonNull@Overridepublic Fragment createFragment(int position) {return new BlueFragment();}@Overridepublic int getItemCount() {return 5;}});
最少要传递一个参数Fragment,这里传递this
老版本只继承Activity是不够的,得继承FragmentActivity;所以我们的Activity类继承自AppcompatActivity
(1)createFragment
理解成关联一个Fragment
虽然BlueFragment关联的xml布局中高度设置的为wrap但是viewpager的match_parent会改变我们当前视图的高度
(2)getItemCount
创建几个收纳这样的Fragment的页面
2:设置方向
viewPager.setOrientation(ViewPager2.ORIENTATION_VERTICAL);
ViewPager2中自带常量
3:设置用户能用手势嘛
viewPager.setUserInputEnabled(false);
默认值为true支持
四:Pager随Radio的改变而改变
<RadioGroupandroid:id="@+id/radio_group"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignParentTop="true"android:orientation="horizontal"><RadioButtonandroid:id="@+id/rb_recommend"android:layout_width="wrap_content"android:layout_height="wrap_content"android:checked="true"android:text="推荐" /><RadioButtonandroid:id="@+id/rb_shop"android:layout_width="wrap_content"android:layout_height="wrap_content"android:checked="false"android:text="商城" /><RadioButtonandroid:id="@+id/rb_follow"android:layout_width="wrap_content"android:layout_height="wrap_content"android:checked="false"android:text="关注" /><RadioButtonandroid:id="@+id/rb_city"android:layout_width="wrap_content"android:layout_height="wrap_content"android:checked="false"android:text="同城" /><RadioButtonandroid:id="@+id/rb_choice"android:layout_width="wrap_content"android:layout_height="wrap_content"android:checked="false"android:text="精选" /></RadioGroup>
1:setOnCheckChangeListenser
设置勾选改变监听器,传参一个接口,重写onCheckedChanged,让勾选的radio作为判定条件,ViewPager随之跳转页面
五:Radio随Pager的改变而改变
//设置注册器页面改变回调提醒:让ViewPager随着RadioGroup的改变而改变viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {/*** 滑动过程中会被调用*/@Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {super.onPageScrolled(position, positionOffset, positionOffsetPixels);Log.i(TAG, "onPageScrolled: position" + position);}/*** 页面被选中时调用* @param position Position index of the new selected page.*/@Overridepublic void onPageSelected(int position) {super.onPageSelected(position);switch (position) {case 0:rbRecommend.setChecked(true);break;case 1:rbShop.setChecked(true);break;case 2:rbFollow.setChecked(true);break;case 3:rbCity.setChecked(true);break;case 4:rbChioce.setChecked(true);break;}}/*** 滑动状态变化* @param state*/@Overridepublic void onPageScrollStateChanged(int state) {super.onPageScrollStateChanged(state);}});
1:registerOnPageChangeCallBack
同样实现接口,重写三个方法
(1)onPageSelected
让不同的Position和Button做关联
(2)onPageScrollStateChanged
SCROLL_STATE_IDLE
(值为 0):表示ViewPager2
处于空闲状态,SCROLL_STATE_DRAGGING
(值为 1):表示ViewPager2
正在被主观拖拽。SCROLL_STATE_SETTLING
(值为 2):表示ViewPager2
处于惯性滚动状态
SCROLL_STATE_IDLE → scroll_state_idle 英 [ˈaɪdl] 空闲的
SCROLL_STATE_DRAGGING → scroll_state_dragging
SCROLL_STATE_SETTLING → scroll_state_settling
六:ViewPager与不同的Fragment怎么关联
1:使用集合
思路很简单,弄一个放Fragment的ArrayList(容器),用下标关联ArrayList中的Fragment和RadioButton
核心代码不多:如下;Fragment关联的页面自己diy去
ArrayList<Fragment> fragments = new ArrayList<>();fragments.add(new RecommendFragment());fragments.add(new ShopFragment());fragments.add(new FollowFragment());fragments.add(new CityFragment());fragments.add(new ChoiceFragment());
@NonNull@Overridepublic Fragment createFragment(int position) {return fragments.get(position);}@Overridepublic int getItemCount() {return fragments.size() == 0 ? 0 : fragments.size();}
2:数据通讯思路
类似setArgument这样子