FragmentPagerAdapter 实现tab切换时 直接点击底部 tab按钮时,跨度大出现界面空白怎么回事?

rtcw2001 2016-07-14 03:43:50
首先,大家都知道 FragmentPagerAdapter和 FragmentStatePagerAdapter不同,只要Fragment被加载(回调了onAttach和onCreate),就不会被销毁(不会调用onDestroy和 onDetach),我用ViewPager和FragmentPagerAdapter构建了一个tab切换应用,底部的按钮用的TextView,一共四个按钮,但是问题来了:

我没有调用 ViewPager的 setOffscreenPageLimit方法,也就是说是默认值 1,只要Fragment被加载后,ViewPager只会显示当前页左右各一页,其他的页不会显示(不会销毁),我先从第一个到第四个标签依次点击,让所有Fragment都加载完毕,然后当我从第一个标签直接切换到第四个时,第四页出现空白,但是从第四个直接切换到第一个就不会出现空白,这是怎么回事?

不要说什么没被加载之类的, FragmentPagerAdapter只要被加载过就不会被销毁,我已经试验过,setOffscreenPageLimit没有设置默认为1只不过是不显示其他的而已(不会调用onCreateView而已),所有的Fragment都已经加载过了,不明白的是从第四个标签切换到第一个就是正常的,但是从第一个标签切换到第四个第四个就会显示空白,请求大侠指点迷津。

此时四个Fragment都已加载完毕,第一个Tab的界面

从第一个直接点击底部按钮切换到第四个出现空白,但是从第四个直接点击底部按钮切换到第一个界面正常显示


附上代码:

主Activity

package com.example.viewpagertabtest;

import java.util.*;

import android.app.*;
import android.graphics.*;
import android.os.*;
import android.support.v13.app.*;
import android.support.v4.view.*;
import android.support.v4.view.ViewPager.*;
import android.view.*;
import android.view.View.*;
import android.widget.*;

public class MainActivity extends Activity implements OnClickListener {

private ViewPager mPager;
private FragmentPagerAdapter mAdapter;
private TextView mTab1, mTab2, mTab3, mTab4;
private List<Fragment> mList;

@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);

initView();
initEvent();

// 设置切换监听器
mPager.setOnPageChangeListener(new OnPageChangeListener()
{
@Override
public void onPageSelected(int position)
{
resetAllTab();
selector(position);
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
{
}
@Override
public void onPageScrollStateChanged(int state)
{
}
});


// 设置ViewPager的切换动画,3.0以上版本有效
mPager.setPageTransformer(false, new PageTransformer()
{
private static final float MIN_SCALE = 0.2f;

@Override
public void transformPage(View page, float position)
{
int pageWidth = page.getWidth();

//左侧不可见Pager
if(position < -1)
{
page.setAlpha(0);
page.setRotationY(0);
}

//左侧可见Pager
else if(position <= 0)
{
page.setAlpha(1);
page.setTranslationX(0);
page.setScaleX(1);
page.setScaleY(1);
page.setRotationY(0);
}

//右侧可见Pager
else if(position <= 1)
{
page.setAlpha(1 - position);
page.setPivotX(page.getMeasuredWidth()/2);
page.setPivotY(page.getMeasuredHeight()/2);
page.setRotationY(position * 180);
page.setTranslationX(pageWidth * -position);
float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));
page.setScaleX(scaleFactor);
page.setScaleY(scaleFactor);
}

//右侧不可见Pager
else
{
page.setAlpha(0);
page.setRotationY(180);
}
}
});

}

//初始化 View
private void initView()
{
mTab1 = (TextView)findViewById(R.id.weixin);
mTab2 = (TextView)findViewById(R.id.friend);
mTab3 = (TextView)findViewById(R.id.address);
mTab4 = (TextView)findViewById(R.id.setting);

mList = new ArrayList<Fragment>();
mList.add(new Fragment1());
mList.add(new Fragment2());
mList.add(new Fragment3());
mList.add(new Fragment4());

mAdapter = new MyAdapter(getFragmentManager(), mList);
mPager = (ViewPager)findViewById(R.id.view_pager);
mPager.setAdapter(mAdapter);
//mPager.setOffscreenPageLimit(3);
}

//初始化监听事件
private void initEvent()
{
mTab1.setOnClickListener(this);
mTab2.setOnClickListener(this);
mTab3.setOnClickListener(this);
mTab4.setOnClickListener(this);
}

//点击事件处理
@Override
public void onClick(View v)
{
resetAllTab();
switch(v.getId())
{
case R.id.weixin:
selector(0);
mPager.setCurrentItem(0, false);
break;
case R.id.friend:
selector(1);
mPager.setCurrentItem(1, false);
break;
case R.id.address:
selector(2);
mPager.setCurrentItem(2, false);
break;
case R.id.setting:
selector(3);
mPager.setCurrentItem(3, false);
break;
}
}

//复位所有底部按钮状态
private void resetAllTab()
{
mTab1.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.tab_weixin_normal, 0, 0);
mTab1.setTextColor(Color.WHITE);
mTab2.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.tab_find_frd_normal, 0, 0);
mTab2.setTextColor(Color.WHITE);
mTab3.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.tab_address_normal, 0, 0);
mTab3.setTextColor(Color.WHITE);
mTab4.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.tab_settings_normal, 0, 0);
mTab4.setTextColor(Color.WHITE);
}

//底部按钮状态选择器
private void selector(int position)
{
switch(position)
{
case 0:
mTab1.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.tab_weixin_pressed, 0, 0);
mTab1.setTextColor(Color.GREEN);
break;
case 1:
mTab2.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.tab_find_frd_pressed, 0, 0);
mTab2.setTextColor(Color.GREEN);
break;
case 2:
mTab3.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.tab_address_pressed, 0, 0);
mTab3.setTextColor(Color.GREEN);
break;
case 3:
mTab4.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.tab_settings_pressed, 0, 0);
mTab4.setTextColor(Color.GREEN);
break;
}
}

}



Fragment

package com.example.viewpagertabtest;

import android.os.*;
import android.util.*;
import android.view.*;
import android.app.*;

public class Fragment1 extends Fragment {

@Override
public void onAttach(Activity activity)
{
Log.i("Fragment1", "绑定");
super.onAttach(activity);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
Log.i("Fragment1", "显示");
return inflater.inflate(R.layout.fragment1, container, false);
}

@Override
public void onDestroyView()
{
Log.i("Fragment1", "不显示");
super.onDestroyView();
}

@Override
public void onDestroy()
{
Log.i("Fragment1", "销毁");
super.onDestroy();
}

@Override
public void onDetach()
{
Log.i("Fragment1", "解绑定");
super.onDetach();
}
}



适配器

package com.example.viewpagertabtest;

import java.util.*;

import android.app.*;
import android.support.v13.app.*;


public class MyAdapter extends FragmentPagerAdapter {

private List<Fragment> mList;

public MyAdapter(FragmentManager fm, List<Fragment> list)
{
super(fm);
mList = list;
}

@Override
public Fragment getItem(int position)
{
return mList.get(position);
}

@Override
public int getCount()
{
return mList.size();
}


}


...全文
375 11 打赏 收藏 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
dinjay 2016-07-15
  • 打赏
  • 举报
回复
引用 7 楼 kokoromiro 的回复:
[quote=引用 3 楼 dinjay 的回复:] 还真没看出来哪儿有问题。 你可以重写Fragment里的setUserVisibleHint函数,看看点完设置后切换到第一个tab后再进入设置,这个函数里的状态对不对

@Override
	public void setUserVisibleHint(boolean isVisibleToUser) {
		super.setUserVisibleHint(isVisibleToUser);
		if (isVisibleToUser) {
			//相当于Fragment的onResume
			Log.e(TAG, "[MainFragment] setUserVisibleHint Resume");
		} else {
			//相当于Fragment的onPause
			Log.e(TAG, "[MainFragment] setUserVisibleHint Pause");
		}
	}
我试了下,状态都是true,但是就是不显示....是不是有BUG啊[/quote] 那有问题啊,当你首次切换到设置时,设置的fragment里isVisibleToUser应该是true,然后你再切到微信的fragment时,此时设置里的isVisibleToUser应该会收到false才对。
rtcw2001 2016-07-15
  • 打赏
  • 举报
回复
引用 3 楼 dinjay 的回复:
还真没看出来哪儿有问题。 你可以重写Fragment里的setUserVisibleHint函数,看看点完设置后切换到第一个tab后再进入设置,这个函数里的状态对不对

@Override
	public void setUserVisibleHint(boolean isVisibleToUser) {
		super.setUserVisibleHint(isVisibleToUser);
		if (isVisibleToUser) {
			//相当于Fragment的onResume
			Log.e(TAG, "[MainFragment] setUserVisibleHint Resume");
		} else {
			//相当于Fragment的onPause
			Log.e(TAG, "[MainFragment] setUserVisibleHint Pause");
		}
	}
我试了下,状态都是true,但是就是不显示....是不是有BUG啊
dinjay 2016-07-15
  • 打赏
  • 举报
回复
试试把4个fragment作为成员变量,而不是直接new完就add到list里, 另外,你的这几个fragment都是分别继承系统fragment重新的么?onCreateView里加载的layout id都是不通的layout吧?
rtcw2001 2016-07-15
  • 打赏
  • 举报
回复
引用 8 楼 dinjay 的回复:
[quote=引用 7 楼 kokoromiro 的回复:] [quote=引用 3 楼 dinjay 的回复:] 还真没看出来哪儿有问题。 你可以重写Fragment里的setUserVisibleHint函数,看看点完设置后切换到第一个tab后再进入设置,这个函数里的状态对不对

@Override
	public void setUserVisibleHint(boolean isVisibleToUser) {
		super.setUserVisibleHint(isVisibleToUser);
		if (isVisibleToUser) {
			//相当于Fragment的onResume
			Log.e(TAG, "[MainFragment] setUserVisibleHint Resume");
		} else {
			//相当于Fragment的onPause
			Log.e(TAG, "[MainFragment] setUserVisibleHint Pause");
		}
	}
我试了下,状态都是true,但是就是不显示....是不是有BUG啊[/quote] 那有问题啊,当你首次切换到设置时,设置的fragment里isVisibleToUser应该是true,然后你再切到微信的fragment时,此时设置里的isVisibleToUser应该会收到false才对。[/quote] 我没说清楚,你说的对,切到微信收到的是false,但是再次切换到设置,会收到true,但是依然显示空白。
adfldk 2016-07-15
  • 打赏
  • 举报
回复
根据楼上提供的方法,原因应该很快找到 标志位不对哦
rtcw2001 2016-07-14
  • 打赏
  • 举报
回复
引用 3 楼 dinjay 的回复:
还真没看出来哪儿有问题。 你可以重写Fragment里的setUserVisibleHint函数,看看点完设置后切换到第一个tab后再进入设置,这个函数里的状态对不对

@Override
	public void setUserVisibleHint(boolean isVisibleToUser) {
		super.setUserVisibleHint(isVisibleToUser);
		if (isVisibleToUser) {
			//相当于Fragment的onResume
			Log.e(TAG, "[MainFragment] setUserVisibleHint Resume");
		} else {
			//相当于Fragment的onPause
			Log.e(TAG, "[MainFragment] setUserVisibleHint Pause");
		}
	}
好的,我试试
rtcw2001 2016-07-14
  • 打赏
  • 举报
回复
引用 4 楼 adfldk 的回复:
从微信切换到通讯录是不是同样显示空白?
是的,但是从通讯录切换到微信就正常,真是奇怪了...
adfldk 2016-07-14
  • 打赏
  • 举报
回复
从微信切换到通讯录是不是同样显示空白?
dinjay 2016-07-14
  • 打赏
  • 举报
回复
还真没看出来哪儿有问题。 你可以重写Fragment里的setUserVisibleHint函数,看看点完设置后切换到第一个tab后再进入设置,这个函数里的状态对不对

@Override
	public void setUserVisibleHint(boolean isVisibleToUser) {
		super.setUserVisibleHint(isVisibleToUser);
		if (isVisibleToUser) {
			//相当于Fragment的onResume
			Log.e(TAG, "[MainFragment] setUserVisibleHint Resume");
		} else {
			//相当于Fragment的onPause
			Log.e(TAG, "[MainFragment] setUserVisibleHint Pause");
		}
	}
rtcw2001 2016-07-14
  • 打赏
  • 举报
回复
这个是动态图,就是依次从左到右点击下面的按钮,把四个Fragment都加载进来,然后直接点击第一个,没问题,正常显示,然后再直接点击第四个 空白...然后再直接点击第一个,正常,再点击第四个依然空白....
adfldk 2016-07-14
  • 打赏
  • 举报
回复
没发现哪不对哦。。。

80,490

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧