首先看下效果图:
我们平时在使用手机的时候,比如用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);
刚开始学的时候老是搞不懂几个步骤,老是忘了下一步该干嘛,慢慢的经常做的话· 会发现这么简单。 所以呢有些东西光看是没有用的,要经常的去练,才能掌握。