我想做以下事情,
使用ViewLager内ScrollVIew内的GridLayout创建图像网格,假设我有图片页面,第1页是动物,第2页植物等等。我希望能够向上和向下滚动查看图像,第1页上的动物,并使用PageTransformer向右和向左滚动以使用动画更改页面。我还需要按照here所述的方式查看左侧和右侧的页面。现在我完成了所有这些,但触摸事件中存在一些我无法解决的冲突,这就是我需要你帮助的地方。
现在当我使用pager.setPageTransformer(true, new ZoomOutPageTransformer());
时,我丢失了ScrollView上下滚动,我得到了很酷的动画。当我不使用它时,除了动画,我得到了我需要的一切,我怎么能得到它们呢?
这是我的主要活动,
public class MainActivity extends Activity {
PagerContainer mContainer;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContainer = (PagerContainer) findViewById(R.id.pager_container);
final ViewPager pager = mContainer.getViewPager();
PagerAdapter adapter = new MyPagerAdapter();
pager.setAdapter(adapter);
//Necessary or the pager will only have one extra page to show
// make this at least however many pages you can see
pager.setOffscreenPageLimit(adapter.getCount());
//A little space between pages
pager.setPageMargin(20);
//If hardware acceleration is enabled, you should also remove
// clipping on the pager for its children.
pager.setClipChildren(false);
pager.setPageTransformer(true, new ZoomOutPageTransformer());
}
//Nothing special about this adapter, just throwing up colored views for demo
private class MyPagerAdapter extends PagerAdapter {
@Override
public Object instantiateItem(ViewGroup container, int position) {
LinearLayout layout = new LinearLayout(container.getContext());
layout.setOrientation(LinearLayout.VERTICAL);
layout.setLayoutParams(new LinearLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT));
ScrollView sv=new ScrollView(container.getContext());
GridLayout gl = new GridLayout(container.getContext());
gl.setLayoutParams(new ViewGroup.LayoutParams ( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
gl.setOrientation(GridLayout.HORIZONTAL);
gl.setColumnCount(3);
gl.setRowCount(3);
for(int i=0;i<9;i++) {
ImageView imgView = new ImageView(container.getContext());
imgView.setImageResource(R.drawable.ic_launcher);
gl.addView( imgView);
}
sv.setVerticalScrollBarEnabled(false);
sv.addView(gl);
container.addView(sv);
return sv;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View)object);
}
@Override
public int getCount() {
return 5;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return (view == object);
}
}
}
我的页面转换器就是这个,
public class ZoomOutPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.85f;
private static final float MIN_ALPHA = 0.5f;
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
int pageHeight = view.getHeight();
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(MIN_ALPHA);
view.setScaleX(MIN_SCALE);
view.setScaleY(MIN_SCALE);
} else if (position <= 1) { // [-1,1]
// Modify the default slide transition to shrink the page as well
float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
float vertMargin = pageHeight * (1 - scaleFactor) / 2;
float horzMargin = pageWidth * (1 - scaleFactor) / 2;
if (position < 0) {
view.setTranslationX(horzMargin - vertMargin / 2);
} else {
view.setTranslationX(-horzMargin + vertMargin / 2);
}
// Scale the page down (between MIN_SCALE and 1)
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
// Fade the page relative to its size.
view.setAlpha(MIN_ALPHA + (scaleFactor - MIN_SCALE) / (1 - MIN_SCALE) * (1 - MIN_ALPHA));
view.clearAnimation();
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(MIN_ALPHA);
view.setScaleX(MIN_SCALE);
view.setScaleY(MIN_SCALE);
}
}
}
最后我的页面容器就是这个,
public class PagerContainer extends FrameLayout implements ViewPager.OnPageChangeListener {
private ViewPager mPager;
boolean mNeedsRedraw = false;
public PagerContainer(Context context) {
super(context);
init();
}
public PagerContainer(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public PagerContainer(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
//Disable clipping of children so non-selected pages are visible
setClipChildren(false);
//Child clipping doesn't work with hardware acceleration in Android 3.x/4.x
//You need to set this value here if using hardware acceleration in an
// application targeted at these releases.
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
@Override
protected void onFinishInflate() {
try {
mPager = (ViewPager) getChildAt(0);
mPager.setOnPageChangeListener(this);
} catch (Exception e) {
throw new IllegalStateException("The root child of PagerContainer must be a ViewPager");
}
}
public ViewPager getViewPager() {
return mPager;
}
private Point mCenter = new Point();
private Point mInitialTouch = new Point();
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mCenter.x = w / 2;
mCenter.y = h / 2;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
//We capture any touches not already handled by the ViewPager
// to implement scrolling from a touch outside the pager bounds.
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
mInitialTouch.x = (int)ev.getX();
mInitialTouch.y = (int)ev.getY();
default:
ev.offsetLocation(mCenter.x - mInitialTouch.x, mCenter.y - mInitialTouch.y);
break;
}
return mPager.dispatchTouchEvent(ev);
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//Force the container to redraw on scrolling.
//Without this the outer pages render initially and then stay static
if (mNeedsRedraw) invalidate();
}
@Override
public void onPageSelected(int position) { }
@Override
public void onPageScrollStateChanged(int state) {
mNeedsRedraw = (state != ViewPager.SCROLL_STATE_IDLE);
}
}
答案 0 :(得分:1)
我在查看this之后发现了这个问题,我认为你不需要使用这个pager.setPageTransformer(true, new ZoomOutPageTransformer());
,并从我之前提到的链接中复制一些东西,然后放{ {1}}作为容器中的函数,因为您将在其中进行转换,最终代码如下所示。
ZoomOutPageTransformer
仅使用上面的PagerContainer和MainActivity,并且不要使用forger来禁用它上面的setPageTransformer。