ViewPager的简介:
必定开发者已经使用过viewPager,例如多张图片结合的新手引导页,或者现在普遍应用的主界面都是Fragment+viewPager来实现。它是support-v4下的一个类,直接继承ViewGroup。最大的作用是使界面左右滑动。使用很简单:
在布局界面实现:
<RelativeLayout 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.support.v4.view.ViewPager
android:id="@+id/main_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
</RelativeLayout>
下一步就要建立适配器adapter,PagerAdapter主要是viewpager的适配器,也是support-v4下的控件,首先要继承PagerAdapter,然后必须实现4个方法:
public class Myadapter extends PagerAdapter {
//需要加载的view集合
private List<View> views;
public Myadapter(List<View> views){
this.views = views;
}
/**
*view得个数,也就是滑动的数量
* @return
*/
@Override
public int getCount() {
return views.size();
}
/**
*
* 判断是否同一个view,确认view与实例对象是否一致
* @param view viewpager显示的view
* @param object 在instantiateItem中提交给viewPager进行保存的实例对象
* @return
*/
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
/**
* 为给定的位置创建相应的view,创建view之后,在本方法添加到viewGroup中
* @param container viewpager本身
* @param position 指定的位置
* @return
*/
@Override
public Object instantiateItem(ViewGroup container, int position){
// View v = views.get(position);
// ViewGroup parent = (ViewGroup)v.getParent();
// if(parent !=null){
// parent.removeAllViews();
// }
(container).addView(views.get(position));
return views.get(position);
}
/**
* 为给定的位置移除相应的view
* @param container viewPager本身
* @param position 指定的位置
* @param object 提交给viewpager进行保存的实例对象
*/
@Override
public void destroyItem(ViewGroup container, int position,Object object){
container.removeView(views.get(position));
}
}
主界面如下:
public class MainActivity extends AppCompatActivity {
//填充界面
private List<View> views;
private ViewPager mainViewPager;
//适配器 绑定数据
private Myadapter myAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainViewPager = (ViewPager)findViewById(R.id.main_viewpager);
//初始化界面
initview();
//加载数据
initdata();
}
private void initdata(){
myAdapter = new Myadapter(views);
mainViewPager.setAdapter(myAdapter);
}
private void initview(){
views = new ArrayList<View>();
View view1 = View.inflate(this,R.layout.viewpager_one,null);
View view2 = View.inflate(this,R.layout.viewpager_two,null);
View view3 = View.inflate(this,R.layout.viewpager_three,null);
views.add(view1);
views.add(view2);
views.add(view3);
}
}
效果图如下:
下面介绍fragment的使用:
什么是fragment,当初它的出现是为了适应大屏幕的平板电脑,fragment占用内存低,同样的界面activity比fragment占用得多。具体不多说:
1.首先建几个Fragment,下面建三个,先建立基Fragment:
public abstract class BaseFragment extends Fragment {
protected View view;//当前界面的根
private int layoutId;//当前界面对应的布局
public BaseFragment(int layoutId){
super();
this.layoutId = layoutId;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
view = View.inflate(getActivity(),layoutId,null);
initView();//初始化当前界面的主要内容
initData();//初始化空间位置
return view;
}
/**
* 显示和隐藏
*
*/
@Override
public void setUserVisibleHint(boolean isVisibleToUser){
super.setUserVisibleHint(isVisibleToUser);
}
/**
* 初始化当前界面的主要内容,即除了头部以外的其他部分
*
*/
protected abstract void initView();
/**
* fragment可见
*
*/
protected abstract void isShow();
/**
*
* 初始化控件位置
*/
protected abstract void initData();
/**
*
* fragment不可见
*/
protected abstract void isGone();
@Override
public void onDestroy(){
super.onDestroy();
//检测内存泄漏的代码
}
@Override
public void onDetach(){
super.onDetach();
Field childFragmentManager;
try {
childFragmentManager = Fragment.class
.getDeclaredField("mChildFragmentManager");
childFragmentManager.setAccessible(true);
childFragmentManager.set(this, null);
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class OneFragment extends BaseFragment {
private TextView textFragmentOne;
public OneFragment(){
super(R.layout.fragment_one);
}
@Override
protected void initView() {
textFragmentOne = (TextView)view.findViewById(R.id.text_fragment_one);
}
@Override
protected void isShow() {
}
@Override
protected void initData() {
}
@Override
protected void isGone() {
}
}
首先介绍不可滑动的fragment切换:
布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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.support.v4.view.ViewPager-->
<!--android:id="@+id/main_viewpager"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent">-->
<!--</android.support.v4.view.ViewPager>-->
<LinearLayout
android:id="@+id/ll_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
<LinearLayout
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/text_one"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="第一个"
android:textColor="@color/black"
android:layout_weight="1"
android:gravity="center"/>
<TextView
android:id="@+id/text_two"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="第二个"
android:textColor="@color/black"
android:layout_weight="1"
android:gravity="center"/>
<TextView
android:id="@+id/text_three"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="第三个"
android:textColor="@color/black"
android:gravity="center"
/>
</LinearLayout>
</RelativeLayout>
主界面:
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
//填充界面
private List<View> views;
private Fragment[] fragments;
private OneFragment oneFragment;
private TwoFragment twoFragment;
private ThreeFragment threeFragment;
private ViewPager mainViewPager;
//适配器 绑定数据
private Myadapter myAdapter;
private TextView text_one;
private TextView text_two;
private TextView text_three;
private int currentTabIndex = 0;//当前页
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// mainViewPager = (ViewPager)findViewById(R.id.main_viewpager);
//初始化界面
initview();
//加载数据
initdata();
}
private void initdata(){
// myAdapter = new Myadapter(views);
// mainViewPager.setAdapter(myAdapter);
}
private void initview(){
// views = new ArrayList<View>();
// View view1 = View.inflate(this,R.layout.viewpager_one,null);
// View view2 = View.inflate(this,R.layout.viewpager_two,null);
// View view3 = View.inflate(this,R.layout.viewpager_three,null);
// views.add(view1);
// views.add(view2);
// views.add(view3);
// fragments = new ArrayList<Fragment>();
text_one = (TextView)findViewById(R.id.text_one);
text_two = (TextView)findViewById(R.id.text_two);
text_three = (TextView)findViewById(R.id.text_three);
text_one.setOnClickListener(this);
text_two.setOnClickListener(this);
text_three.setOnClickListener(this);
oneFragment = new OneFragment();//创建实例对象
twoFragment = new TwoFragment();
threeFragment = new ThreeFragment();
fragments = new Fragment[]{oneFragment,twoFragment,threeFragment};
//添加显示第一个fragment
getSupportFragmentManager().beginTransaction()
.add(R.id.ll_main,oneFragment)
.add(R.id.ll_main,twoFragment)
.add(R.id.ll_main,threeFragment)
.hide(twoFragment)
.hide(threeFragment)
.show(oneFragment).commit();
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.text_one:
onTabselect(0);
break;
case R.id.text_two:
onTabselect(1);
break;
case R.id.text_three:
onTabselect(2);
break;
}
}
private void onTabselect(int index){
if(currentTabIndex != index){
FragmentTransaction trx = getSupportFragmentManager().beginTransaction();
trx.hide(fragments[currentTabIndex]);
if(!fragments[index].isAdded()){
trx.add(R.id.ll_main,fragments[index]).commit();
}
trx.show(fragments[index]).commitAllowingStateLoss();
currentTabIndex = index;
}
}
}
打印log发现,三个fragment是一起创建的,如果每个fragment有大量的图片资源加载,很容易出现内存溢出,那么这时候进行优化:
这时候想办法,能不能一开始不要同时创建三个fragment,就是点击哪个页面,这时候想要显示的页面才创建。
修改后的主界面:
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
//填充界面
private List<View> views;
private Fragment[] fragments;
private OneFragment oneFragment;
private TwoFragment twoFragment;
private ThreeFragment threeFragment;
private ViewPager mainViewPager;
//适配器 绑定数据
private Myadapter myAdapter;
private TextView text_one;
private TextView text_two;
private TextView text_three;
private FragmentManager fragmentManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// mainViewPager = (ViewPager)findViewById(R.id.main_viewpager);
//初始化界面
initview();
//加载数据
initdata();
}
private void initdata(){
// myAdapter = new Myadapter(views);
// mainViewPager.setAdapter(myAdapter);
}
private void initview(){
fragmentManager = getSupportFragmentManager();
showFragment(0);
// views = new ArrayList<View>();
// View view1 = View.inflate(this,R.layout.viewpager_one,null);
// View view2 = View.inflate(this,R.layout.viewpager_two,null);
// View view3 = View.inflate(this,R.layout.viewpager_three,null);
// views.add(view1);
// views.add(view2);
// views.add(view3);
// fragments = new ArrayList<Fragment>();
text_one = (TextView)findViewById(R.id.text_one);
text_two = (TextView)findViewById(R.id.text_two);
text_three = (TextView)findViewById(R.id.text_three);
text_one.setOnClickListener(this);
text_two.setOnClickListener(this);
text_three.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.text_one:
showFragment(0);
break;
case R.id.text_two:
showFragment(1);
break;
case R.id.text_three:
showFragment(2);
break;
}
}
private void showFragment(int page){
FragmentTransaction ft = fragmentManager.beginTransaction();
hideFragment(ft);
switch (page){
case 0:
if(oneFragment!=null){
ft.show(oneFragment);
}else{
oneFragment =new OneFragment();
ft.add(R.id.ll_main,oneFragment);
}
break;
case 1:
if(twoFragment != null){
ft.show(twoFragment);
}else{
twoFragment = new TwoFragment();
ft.add(R.id.ll_main,twoFragment);
}
break;
case 2:
if(threeFragment!=null){
ft.show(threeFragment);
}else{
threeFragment = new ThreeFragment();
ft.add(R.id.ll_main,threeFragment);
}
break;
}
ft.commit();
}
private void hideFragment(FragmentTransaction ft){
if(oneFragment != null){
ft.hide(oneFragment);
}
if(twoFragment !=null){
ft.hide(twoFragment);
}
if(threeFragment!=null){
ft.hide(threeFragment);
}
}
}
一开始进入app的时候:
log的打印是:
当点击第二个页面:
由此可见,当点击哪个页面时,页面才创建。
下面介绍viewPager+Fragment的使用:
布局文件就一个viewpager,就不贴了。
主界面:
public class MainActivity extends AppCompatActivity {
//填充界面
private List<Fragment> fragments;
private ViewPager mainViewPager;
//适配器 绑定数据
private Myadapter myAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainViewPager = (ViewPager)findViewById(R.id.main_viewpager);
//初始化界面
initview();
//加载数据
initdata();
}
private void initdata(){
// myAdapter = new Myadapter(views);
// mainViewPager.setAdapter(myAdapter);
}
private void initview(){
fragments = new ArrayList<Fragment>();
OneFragment oneFragment =new OneFragment();
TwoFragment twoFragment =new TwoFragment();
ThreeFragment threeFragment = new ThreeFragment();
//添加到集合
fragments.add(oneFragment);
fragments.add(twoFragment);
fragments.add(threeFragment);
mainViewPager.setAdapter(new Myadapter(getSupportFragmentManager(),fragments));
mainViewPager.setCurrentItem(0);
}
}
public class Myadapter extends FragmentPagerAdapter {
//需要加载的view集合
private List<Fragment> fragments;
public Myadapter(FragmentManager fm,List<Fragment>fragments){
super(fm);
this.fragments = fragments;
}
/**
*view得个数,也就是滑动的数量
* @return
*/
@Override
public int getCount() {
return fragments.size();
}
/**
*
* 判断是否同一个view,确认view与实例对象是否一致
* @param view viewpager显示的view
* @param object 在instantiateItem中提交给viewPager进行保存的实例对象
* @return
*/
// @Override
// public boolean isViewFromObject(View view, Object object) {
// return view == object;
// }
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
/**
* 为给定的位置创建相应的view,创建view之后,在本方法添加到viewGroup中
* @param container viewpager本身
* @param position 指定的位置
* @return
*/
}
这样就实现了,注意:iewPager是一开始就加载所有的页面。另外:setOffscreenPageLimit()这个方法是用来控制fragment不重新走生命周期的个数,如果一共有三个页面。如果设置setOffscreenPagerLimit(2),就只会走一遍生命周期,如果没有设置,是被强赋值为1.