我正在为
Android的简单的书籍阅读器应用程序工作.我已经使用列表视图为此.
我正在做的是将远程图像从服务器加载到我的Listview(使用Picasso库),并且正常工作.
我也想在我的阅读器中缩放功能,我用ZoomListView类来实现这一点.
public class ZoomListView extends ListView { private static final int INVALID_POINTER_ID = -1; private int mActivePointerId = INVALID_POINTER_ID; private ScaleGestureDetector mScaleDetector; private float mScaleFactor = 1.f; private float maxWidth = 0.0f; private float maxHeight = 0.0f; private float mLastTouchX; private float mLastTouchY; private float mPosX; private float mPosY; private float width; private float height; public ZoomListView(Context context) { super(context); mScaleDetector = new ScaleGestureDetector(getContext(),new ScaleListener()); } public ZoomListView(Context context,AttributeSet attrs) { super(context,attrs); mScaleDetector = new ScaleGestureDetector(getContext(),AttributeSet attrs,int defStyleAttr) { super(context,attrs,defStyleAttr); mScaleDetector = new ScaleGestureDetector(getContext(),new ScaleListener()); } @Override protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec) { width = MeasureSpec.getSize(widthMeasureSpec); height = MeasureSpec.getSize(heightMeasureSpec); super.onMeasure(widthMeasureSpec,heightMeasureSpec); } @Override public boolean onTouchEvent(@NonNull MotionEvent ev) { super.onTouchEvent(ev); final int action = ev.getAction(); mScaleDetector.onTouchEvent(ev); switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: { final float x = ev.getX(); final float y = ev.getY(); mLastTouchX = x; mLastTouchY = y; mActivePointerId = ev.getPointerId(0); break; } case MotionEvent.ACTION_MOVE: { final int pointerIndex = ev.findPointerIndex(mActivePointerId); final float x = ev.getX(pointerIndex); final float y = ev.getY(pointerIndex); final float dx = x - mLastTouchX; final float dy = y - mLastTouchY; mPosX += dx; mPosY += dy; if (mPosX > 0.0f) mPosX = 0.0f; else if (mPosX < maxWidth) mPosX = maxWidth; if (mPosY > 0.0f) mPosY = 0.0f; else if (mPosY < maxHeight) mPosY = maxHeight; mLastTouchX = x; mLastTouchY = y; invalidate(); break; } case MotionEvent.ACTION_UP: { mActivePointerId = INVALID_POINTER_ID; break; } case MotionEvent.ACTION_CANCEL: { mActivePointerId = INVALID_POINTER_ID; break; } case MotionEvent.ACTION_POINTER_UP: { final int pointerIndex = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; final int pointerId = ev.getPointerId(pointerIndex); if (pointerId == mActivePointerId) { final int newPointerIndex = pointerIndex == 0 ? 1 : 0; mLastTouchX = ev.getX(newPointerIndex); mLastTouchY = ev.getY(newPointerIndex); mActivePointerId = ev.getPointerId(newPointerIndex); } break; } } return true; } @Override public void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.save(Canvas.MATRIX_SAVE_FLAG); canvas.translate(mPosX,mPosY); canvas.scale(mScaleFactor,mScaleFactor); canvas.restore(); } @Override protected void dispatchDraw(@NonNull Canvas canvas) { canvas.save(Canvas.MATRIX_SAVE_FLAG); if (mScaleFactor == 1.0f) { mPosX = 0.0f; mPosY = 0.0f; } canvas.translate(mPosX,mScaleFactor); super.dispatchDraw(canvas); canvas.restore(); invalidate(); } private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { @Override public boolean onScale(ScaleGestureDetector detector) { mScaleFactor *= detector.getScaleFactor(); mScaleFactor = Math.max(1.0f,Math.min(mScaleFactor,4.0f)); maxWidth = width - (width * mScaleFactor); maxHeight = height - (height * mScaleFactor); invalidate(); return true; } } }
这是我的XML布局(我已经只显示了ZoomListView):
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" android:gravity="top" android:visibility="visible" > <libraries.ZoomListView android:id="@+id/lstv_book_reader" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="0dp" android:paddingTop="0dp" > </libraries.ZoomListView> </RelativeLayout> </RelativeLayout>
这使我能够放大我的书籍阅读器.我的书籍读者看起来像
问题:
我在捏捏缩放中遇到问题.当我捏捏缩放从列表视图的左上角开始.
让我用图像描述
1捏
2电流输出
注意:这放大了从topleft角落的列表
3推荐输出
解决方法
这意味着您要更改缩放(缩放)的默认属性始终从(0,0)开始,即:
_____________ |0,0 x | |y | | | Suppose this the device screen | | | | ______________
而且你想将它从
_____________ | | | | | | Suppose this the device screen | y | | X 0,0| ______________
所以要实现这个:
从此更改您的代码:
canvas.scale(mScaleFactor,mScaleFactor);
到这个:
canvas.scale(mScaleFactor,-mScaleFactor);
也看到这个与你的问题有关的问题:
Android: Drawing to canvas,way to make bottom left correspond to (0,0)?我有我从这个例子和代码片段中得到你的解决方案.