我正在使用动态数量的片段实现ViewPager
+ FragmentPagerAdapter
。 ViewPager本身效果很好。我可以在两边添加碎片。我的ViewPager在启动时加载了一些片段,可以在“需要时”添加新片段,并且可以获得数据。
加载开始时?想象一下这是viewpager中的页码:
0 1 2 3 4 5 6 7 8
_____ _____
当我们到达下划线页面之一时,我们会在侧面加载新页面。接近边缘=加载更多页面。
当添加新片段并且正在滚动时,真正困扰我的是 SlidingTabLayout的小滞后。你可以在this video看到它(youtube会低估一点问题)。
我使用了一点修饰SlidingTabLayout
。我刚刚添加了重装子的方法:
public void notifyDataSetChanged() {
final PagerAdapter adapter = mViewPager.getAdapter();
final OnClickListener tabClickListener = new TabClickListener();
int childViewsCount = mTabStrip.getChildCount();
int adapterChildCount = adapter.getCount();
// get correct views count
if(childViewsCount < adapterChildCount) { // need to add new views
int missingViews = adapterChildCount - childViewsCount;
for (int i = 0; i < missingViews; i++) {
View tabView = null;
if (mTabViewLayoutId != 0) {
// If there is a custom tab view layout id set, try and inflate it
tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip,
false);
}
if (tabView == null) {
tabView = createDefaultTabView(getContext());
}
tabView.setOnClickListener(tabClickListener);
mTabStrip.addView(tabView);
}
} else if(childViewsCount > adapterChildCount) { // need to delete some views
int uselessViews = childViewsCount - adapterChildCount;
for(int i = 0; i < uselessViews; i++) {
mTabStrip.removeViewAt(0);
}
}
for(int i = 0; i < adapterChildCount; i++) { // fill views with data
View tabView = mTabStrip.getChildAt(i);
TextView tabTitleView = null;
if (mTabViewLayoutId != 0) {
// If there is a custom tab view layout id set, try and inflate it
tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip,
false);
tabTitleView = (TextView) tabView.findViewById(mTabViewTextViewId);
}
if (tabTitleView == null && TextView.class.isInstance(tabView)) {
tabTitleView = (TextView) tabView;
}
tabTitleView.setText(adapter.getPageTitle(i));
}
getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
int currentPosition = mViewPager.getCurrentItem();
smoothScrollToTab(currentPosition, 0);
}
});
}
OnPageChangeListener实现。添加新片段的位置:
ViewPager.SimpleOnPageChangeListener pageL = new ViewPager.SimpleOnPageChangeListener() {
private int mState = -1;
boolean pageSelected = false;
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// figure out if we really scrolled to *new* position
if (pageSelected &&
(mState == ViewPager.SCROLL_STATE_SETTLING || mState == ViewPager.SCROLL_STATE_IDLE)) {
currentPage = position;
pageSelected = false;
int addedFragmentsCount = 0;
CalendarPA adapter = (CalendarPA) mPager.getAdapter();
if(currentPage >= 0 && currentPage < PAGE_LIMIT_TO_LOAD) {
int limit = PAGES_TO_LOAD - currentPage; // number of pages loaded depends on page we're at
for(int i = 0; i < limit; i++) {
addedFragmentsCount += adapter.addFragmentLeft(defaultDataPos + (defaultPage + currentPage) +
(currentPage == 0 ? 1 : 0)); // currentPage == 0 -> we must not look for data at pos + 1
}
adapter.moveToRight(addedFragmentsCount); // rotate right
}
int offset = mPager.getAdapter().getCount() - currentPage;
if(offset > 0 && offset < PAGE_LIMIT_TO_LOAD) {
int limit = PAGES_TO_LOAD - offset; // number of pages loaded depends on page we're at
for(int i = 0; i < limit; i++) {
adapter.addFragmentRight(defaultPage - currentPage + defaultDataPos - offset - i);
}
}
}
}
@Override
public void onPageScrollStateChanged(int state) {
mState = state;
}
@Override
public void onPageSelected(int position) {
currentPage = position;
pageSelected = true; // page has been selected
}
};
FragmentPagerAdapter
:
公共类CalendarPA扩展了FragmentStatePagerAdapter {
ArrayList<DummyFragment> mPagerFragments;
ViewPager mPager;
public CalendarPA(FragmentManager fm, ViewPager viewPager) {
super(fm);
mPager = viewPager;
mPagerFragments = new ArrayList<DummyFragment>(); // first - pos 0 fragment
mPagerFragments.add(new DummyFragment());
}
@Override
public Fragment getItem(int pos) {
DummyFragment df = mPagerFragments.get(pos);
df.setData(data.getMyString(positionToDataPosition(pos)));
return df;
}
@Override
public int getCount() {
return mPagerFragments.size();
}
public void moveToRight(int offset) {
mPager.setCurrentItem(mPager.getCurrentItem() + offset, false);
}
@Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
mSlidingTabLayout.notifyDataSetChanged();
}
public int addFragmentLeft(int dataPos) {
String text = data.getMyString(dataPos);
if(text == null) return 0; // no data
DummyFragment df = new DummyFragment();
df.setData(text);
mPagerFragments.add(0, df);
defaultPage++;
notifyDataSetChanged();
return 1; // fragment added
}
public int addFragmentRight(int dataPos) {
String text = data.getMyString(dataPos);
if(text == null) return 0; // no data
DummyFragment df = new DummyFragment();
df.setData(text);
mPagerFragments.add(mPagerFragments.size(), df);
notifyDataSetChanged();
return 1; // fragment added
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
/**
* Method to translate viewpager page position to data position
* @param position page
* @return return data position
*/
public int positionToDataPosition(int position) {
int temp = defaultPage - position;
return defaultDataPos + temp;
}
@Override
public CharSequence getPageTitle(int position) {
return "POS :::::" + String.valueOf(positionToDataPosition(position));
}
}
github上的其余实施。有人可以建议如何在没有平滑过渡的情况下正确更新SlidingTabLayout内容吗?提前谢谢。