浅谈ViewPager+Fragment的使用和理解

本文介绍了如何在Android中实现ViewPager结合Fragment的功能,包括导入必要的v4库、创建布局、添加RadioButton、初始化数据、创建适配器、设置事件监听。通过实例化Fragment,设置ViewPager的适配器和事件监听,实现页面的切换。同时,讨论了ViewPager的生命周期和无限轮播的实现方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

                   

首先看下效果图:

             

                             



                                                            


 我们平时在使用手机的时候,比如用QQ,微信等软件的时候经常会看到这样的如上图一样· 点击可以切换页面·左右滑动也可以切换页面。感觉很高大上,今天呢就跟大家分享一下关于这个是怎么实现的。


首先第一点大家要记住,如果要使用Viewpager的话一定要导入:import android.support.v4.view.ViewPager。这个包,必须是v4包下的 ,千万不能导错,然后我们就先创建布局:布局如下:


<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=".MainActivity" >


    <android.support.v4.view.ViewPager
        android:id="@+id/vp"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </android.support.v4.view.ViewPager>



创建好Viewpager的布局之后,我们今天说的是ViewPager+Fragment的组合使用,那么就得在布局底部加上几个RadioButton:


<RadioGroup
        android:id="@+id/rg"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal" >


        <RadioButton
            android:id="@+id/rb1"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:button="@null"
            android:gravity="center"
            android:background="@drawable/rg_selector"
            android:text="
我的界面" />
        <RadioButton
            android:id="@+id/rb2"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:button="@null"
            android:gravity="center"
            android:background="@drawable/rg_selector"
            android:text="
新闻界面
" />
    </RadioGroup>


创建好布局之后,接下来就该进入到代码实现的功能了:


import java.util.ArrayList;
import java.util.List;


import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;


import com.bwei.fragmentViewPager.fragment.FragmentBBY;
import com.bwei.fragmentViewPager.fragment.FragmentLL;
import com.bwei.fragmentViewPager.fragment.FragmentW;
import com.bwei.fragmentViewPager.fragment.FragmentYYL;


public class MainActivity extends FragmentActivity {


ViewPager vp;
List<Fragment> list;
RadioGroup rg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

/*
* 1:实例化控件  2:初始化数据  3:创建适配器   4:绑定
*/
vp = (ViewPager) findViewById(R.id.vp);
// 初始化数据源
initData();
// 设置适配器
MyFragmentPagerAdapter adapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
vp.setAdapter(adapter);// 添加适配器
// 关联
vp.setOnPageChangeListener(new OnPageChangeListener() {

@Override
public void onPageSelected(int arg0) {

switch (arg0) {
case 0:
rg.check(R.id.rb1);
break;
case 1:
rg.check(R.id.rb2);
break;
case 2:
rg.check(R.id.rb3);
break;
case 3:
rg.check(R.id.rb4);
break;


default:
break;
}

}

@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub

}

@Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub

}
});


rg = (RadioGroup) findViewById(R.id.rg);
// 选中改变监听事件
rg.setOnCheckedChangeListener(new OnCheckedChangeListener() {


/*
* 参数1:当前RadioGroup对象 参数2:当前被选中的RadioButton的id
*/

@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {

switch (checkedId) {
case R.id.rb1:
vp.setCurrentItem(0);
break;
case R.id.rb2:
vp.setCurrentItem(1);
break;
case R.id.rb3:
vp.setCurrentItem(2);
break;
case R.id.rb4:
vp.setCurrentItem(3);
break;


default:
break;
}

}
});
}


// 初始化数据方法
private void initData() {

list = new ArrayList<Fragment>();
list.add(new FragmentLL());
list.add(new FragmentYYL());
list.add(new FragmentBBY());
list.add(new FragmentW());


}
// 创建适配器
class MyFragmentPagerAdapter extends FragmentPagerAdapter{


public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);

}


@Override
public Fragment getItem(int arg0) {

return list.get(arg0);
}


@Override
public int getCount() {

return list.size();
}

}


}


最重要的四个步骤:

 1:实例化控件  2:初始化数据  3:创建适配器   4:绑定


首先实例化控件,把控件找到,然后初始化数据源,定义一个方法,在然后创建适配器,在绑定数据。

这里初始化数据源我们直接用了一个list集合然后new了几个Fragment,把Fragment当做数据源。

// 初始化数据方法
private void initData() {

list = new ArrayList<Fragment>();
list.add(new FragmentLL());
list.add(new FragmentYYL());
list.add(new FragmentBBY());
list.add(new FragmentW());


}


在newFragment的之前我们首先要创建几个Fragment类,这样才能new出来,要不是创建不出来的。


public class FragmentBBY extends Fragment {

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = View.inflate(getActivity(), R.layout.frag_byy, null);
return view;
}


}


创建Fragment类一定要继承Fragment,然后重写它的onCreateView方法,然后加载我们创建的Fragment布局:


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
     >


    <TextView
        android:id="@+id/tv_ll"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="
我的
页面"
        android:textSize="30sp"
        android:layout_centerInParent="true" />


</RelativeLayout>


接下来就该创建适配器了,


// 创建适配器
class MyFragmentPagerAdapter extends FragmentPagerAdapter{


public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);

}


@Override
public Fragment getItem(int arg0) {

return list.get(arg0);
}


@Override
public int getCount() {

return list.size();
}

}

创建好适配器需要继承FragmentPagerAdapterz这个类,然后重写它的3个构造方法

条目和数量。

接下来设置适配器:vp.setAdapter(adapter);


最后我们要做的就是让ViewPager和Fragment关联,这样才能做到左右可以滑动点击也可以滑动。

// 关联
vp.setOnPageChangeListener(new OnPageChangeListener() {

@Override
public void onPageSelected(int arg0) {

switch (arg0) {
case 0:
rg.check(R.id.rb1);
break;
case 1:
rg.check(R.id.rb2);
break;
case 2:
rg.check(R.id.rb3);
break;
case 3:
rg.check(R.id.rb4);
break;


default:
break;
}

}

@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub

}

@Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub

}
});


rg = (RadioGroup) findViewById(R.id.rg);
// 选中改变监听事件
rg.setOnCheckedChangeListener(new OnCheckedChangeListener() {


/*
* 参数1:当前RadioGroup对象 参数2:当前被选中的RadioButton的id
*/

@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {

switch (checkedId) {
case R.id.rb1:
vp.setCurrentItem(0);
break;
case R.id.rb2:
vp.setCurrentItem(1);
break;
case R.id.rb3:
vp.setCurrentItem(2);
break;
case R.id.rb4:
vp.setCurrentItem(3);
break;


default:
break;
}

}
});
}


这样一来就实现了ViewPager+Fragment的功能了,


但是还有一点要搞清楚的就是他们的声明周期:


 viewpager显示fragment的时候不会仅仅显示展现的那个fragment,而是将前一个,后一个,和正在显示的fragment的生命周期都跑一遍。


ViewPager不光可以左右滑动· 还可以设置无线滑动· 以及自动滑动。 这就是我们比如在淘宝或者京东一些商场里所见的一些商品,一会换一个一会换一个。 这些都可以用ViewPager来实现。


那么既然要用ViewPager的无线轮播 Adapter就得继承PagerAdapter,不能继承FragmentPagerAdapter,因为这个是用来管理Fragment的。 继承了P啊个人Adapter之后,重写它的构造方法。四个构造方法:

为了让ViewPager可以无限滑动,我们让getCount返回一个很大的值,例如Integer.MAX_VALUE,然后setCurrentItem把ViewPager显示的当前Page设置在总页数的中间位置。

当getCount返回一个不是很大的值的时候,ViewPager很快就会到达左右边界,就无法继续滑动了。
解决方式是在ViewPager快要切换到边界时,使用setCurrentItem把它重置回中间位置。


使用handler的sendEmptyMessageDelayed很容易让ViewPager以固定频率自带切换页面。这里强调下,使用线程当然也可以,就是性能上看,避免线程来完成这种“定时”效果——大材小用,Thread是为了不卡顿主线程执行耗时的操作,简单的定时操作handler消息轮询就可以了


Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
if(msg.what==AUTO_SCROLL){
// 获取当前viewPager所在索引值
int currentItem = viewPager.getCurrentItem();
   // 让索引++
currentItem++;
// 重新设置viewPager
viewPager.setCurrentItem(currentItem);

handler.sendEmptyMessageDelayed(AUTO_SCROLL, 2000);

}
};
};


1、要展示的view的个数、然后返回最大值

2、将view添加到容器中,如果是无限轮播那么就用当前对应的position取模于view集合的长度

3、当前的视图是否和instantItem所返回key对应的view是否一致

4销毁条目




// 要展示的view个数 
@Override
public int getCount() {
return Integer.MAX_VALUE;
}


/**
* 将view添加到容器中
* 返回一个与view对应的key
*/

// 实例化view  并添加到容器中
@Override
public Object instantiateItem(ViewGroup container, int position) {
// 丛集合中根据索引获取当前要展示的视图
View view = viewList.get(position%viewList.size());
// 将view添加到容器中
container.addView(view);

return view;
}

/**
* 当前的视图是否和instantItem所返回key对应的view是否一致
*/

@Override
public boolean isViewFromObject(View view, Object object) {
return view==object;
}

/**
*  销毁条目
*  object 看instantiateItem所返回的是不是view 如果是,可以直接移除object
*/
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// super.destroyItem(container, position, object);
// 从容器中移除所添加的条目
//container.removeView(viewList.get(position));
container.removeView((View) object);
}


然后设置适配器、设置无线轮播、设置自动轮播

// 设置适配器
viewPager.setAdapter(new MyPagerAdapter(viewList));

// 无限轮播
viewPager.setCurrentItem(10000*viewList.size());

// 自动
handler.sendEmptyMessageDelayed(AUTO_SCROLL, 2000);


刚开始学的时候老是搞不懂几个步骤,老是忘了下一步该干嘛,慢慢的经常做的话· 会发现这么简单。 所以呢有些东西光看是没有用的,要经常的去练,才能掌握。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值