我想向任何可能想要相同功能的人提供更新。到目前为止,在实现此功能方面已经取得了很大进展,现在视图正在完全按照我们的需要工作。
ViewPager 有一个名为 setPageMargin() 的方法。此方法可以接收一个负值,这将使片段/视图相互重叠。为了达到所需的布局,我们首先按屏幕百分比动态计算左右边距。这也可以静态完成,但由于我们将针对一系列不同的屏幕尺寸,这似乎是最好的方法。
稍后我们将 ViewPager 的页边距设置为侧边距大小的 2 倍。这使视图重新组合在一起。但是,此时 ViewPager 将显示多个视图。
您剩下要做的就是对左右视图(Android 3.0+)应用变换(缩放)或在它们周围添加更多边距以将它们缩小到正确的大小(3.0 之前)。
OnPageChangeListener.onPageScrolled() 可用于跟踪 ViewPager 的滚动。可以实现平滑的转换。代码如下所示:
private OnPageChangeListener onPageChangeListener = new OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// positionOffset varies from 0 to 1 and indicates how far the view is
// from the center of the ViewPager. When a view is selected (centered), this
// value is 0.
// Fades the text in an out while the ViewPager scrolls from one view to another.
// On our final design the text views are fixed to the center of the screen and
// do not scroll along with the views.
if (positionOffset < 0.5) {
setTextViewAlpha(1 - positionOffset * 2);
} else {
setTextViewAlpha((positionOffset - 0.5f) * 2);
}
// It's surprisingly complicated to get the current object being displayed by
// a ViewPager (there's no getCurrentObject method). ScaleableFragment is just
// a custom class to allow an adapter to cache it internally and also correctly
// manage a fragment's lifecycle and restore from a saved state.
ScaleableFragment sampleFragment = (ScaleableFragment) ((ShowHeroShotImageFragmentPagerAdapter) pager
.getAdapter()).getItem(position);
// Calculates by how much the current view will be scaled down. The RATIO_SCALE
// is 0.3 in our case, which makes the side views 70% of the size of the
// center view. When centered, the scale will be 1. When
// fully scrolled, the scale will be 0.7.
float scale = 1 - (positionOffset * RATIO_SCALE);
// Just a shortcut to findViewById(R.id.image).setScale(scale);
sampleFragment.scaleImage(scale);
// Now, if not in the last element, scale the next one up (in opposite direction).
if (position + 1 < pager.getAdapter().getCount()) {
sampleFragment = (ScaleableFragment) ((ShowHeroShotImageFragmentPagerAdapter) pager.getAdapter())
.getItem(position + 1);
scale = positionOffset * RATIO_SCALE + (1 - RATIO_SCALE);
sampleFragment.scaleImage(scale);
}
}
// Once scrolling is done. Make sure the views are in the right scale (1 for center,
// 0.7 for sides). Required as the onPageScrolled() method does not guarantee it
// will interpolate to 1.0 precisely.
@Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_IDLE) {
setTextViewAlpha(1);
ScaleableFragment sampleFragment = (ScaleableFragment) ((ShowHeroShotImageFragmentPagerAdapter) pager
.getAdapter()).getItem(pager.getCurrentItem());
sampleFragment.scaleImage(1);
sampleFragment.enableClicks();
if (pager.getCurrentItem() > 0) {
sampleFragment = (ScaleableFragment) ((ShowHeroShotImageFragmentPagerAdapter) pager.getAdapter())
.getItem(pager.getCurrentItem() - 1);
sampleFragment.scaleImage(1 - RATIO_SCALE);
sampleFragment.disableClicks();
}
if (pager.getCurrentItem() + 1 < pager.getAdapter().getCount()) {
sampleFragment = (ScaleableFragment) ((ShowHeroShotImageFragmentPagerAdapter) pager.getAdapter())
.getItem(pager.getCurrentItem() + 1);
sampleFragment.scaleImage(1 - RATIO_SCALE);
sampleFragment.disableClicks();
}
}
}
};
就是这个。我没有发布完整的解决方案,但我希望这足以让其他人开始。
PS On 3.0+ 启用硬件加速。没有它,三星 Galaxy Tab 10.1 上的滚动看起来很不稳定。