我正在使用 Mike Ortiz 的TouchImageView。
在其中,canScrollHorizontally
被覆盖:
@Override
public boolean canScrollHorizontally(int direction) {
matrix.getValues(m);
float x = m[Matrix.MTRANS_X];
float y = m[Matrix.MTRANS_Y];
if (getImageWidth() < viewWidth) {
return false;
} else if (x >= -1 && direction < 0) {
return false;
} else if (Math.abs(x) + viewWidth + 1 >= getImageWidth() && direction > 0) {
return false;
}
return true;
}
这按预期工作。我可以将 TouchImageView 放在 a 中ViewPager
,并在缩放的图像周围滚动,但当我到达图像的边缘时,也可以在 ViewPager 中向右/向左滑动。
但我想要的是嵌套在常规 ViewPager 中的垂直 ViewPager。垂直 ViewPager 是根据这个SO 帖子建模的:
public class VerticalViewPager extends ViewPager {
public VerticalViewPager(Context context) {
super(context);
init();
}
public VerticalViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
// The majority of the magic happens here
setPageTransformer(true, new VerticalPageTransformer());
// The easiest way to get rid of the overscroll drawing that happens on the left and right
setOverScrollMode(OVER_SCROLL_NEVER);
}
private class VerticalPageTransformer implements ViewPager.PageTransformer {
@Override
public void transformPage(View view, float position) {
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 1) { // [-1,1]
view.setAlpha(1);
// Counteract the default slide transition
view.setTranslationX(view.getWidth() * -position);
//set Y position to swipe in from top
float yPosition = position * view.getHeight();
view.setTranslationY(yPosition);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
/**
* Swaps the X and Y coordinates of your touch event.
*/
private MotionEvent swapXY(MotionEvent ev) {
float width = getWidth();
float height = getHeight();
float newX = (ev.getY() / height) * width;
float newY = (ev.getX() / width) * height;
ev.setLocation(newX, newY);
return ev;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev){
boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
swapXY(ev); // return touch coordinates to original reference frame for any child views
return intercepted;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
return super.onTouchEvent(swapXY(ev));
}
}
使用常规的 ImageViews,效果很好。我可以在水平 ViewPager 中向左/向右滑动,同时还可以根据需要在嵌套的 ViewPager 中垂直滚动。对垂直 ViewPager 的一种修改(允许从垂直 ViewPager 内的任何位置进行水平滚动)是:
@Override
public boolean canScrollHorizontally(int direction) {
return false;
}
小改动,效果很好。
当垂直 ViewPager 的内容是自定义的 TouchImageViews 时,问题就来了。向右/向左滑动仍然很有效,但垂直滑动仅在图像的右边缘与设备屏幕的右侧对齐时才有效。这是由于canScrollHorizontally
TouchImageView 类中的覆盖。
该int direction
参数不考虑 x 或 y。正 y 滑动与正 x 滑动无法区分。
我想做的是覆盖该canScrollVertically
方法,以检测何时发生垂直滑动,但该方法永远不会被调用。即使只是一个快速测试,例如:
@Override
public boolean canScrollVertically(int direction) {
matrix.getValues(m);
Toast.makeText(context, "vertical", Toast.LENGTH_SHORT).show();
return true;
}
永远不会被调用。在方法中放置相同的 Toast 消息会canScrollHorizontally
在每次滑动(水平或垂直)时显示该消息。
为什么canScrollVertically
从来不叫?
我想检测图像何时在视图中触底,以及用户何时向上滑动。当满足这两个条件时,我可以从中返回falsecanScrollHorizontally
并允许垂直 ViewPager 正确滚动。
提前感谢您的帮助。有谁认识迈克·奥尔蒂斯!?