Доброго времени суток.. Ситуация следующая: есть компонент наследованный от ViewGroup в котором реализовано pinch-to-zoom, внутри размещаются еще несколько TextView и ImageView. В приложении 3 Fragments в каждом из которых должен быть этот компонент.. Пример:
<?xml version="1.0" encoding="utf-8"?>
<name.launcher.view.ZoomableViewGroup
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
>
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/ll2"
>
<ImageView
android:src="@drawable/diff"
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:scaleType="centerCrop"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true" />
<TextView
android:text="TextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tvPage" />
<TextView
android:text="TextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tvPage1" />
<Button
android:text="Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="16dp"
android:layout_y="193dp"
android:id="@+id/btnUpdate" />
</AbsoluteLayout>
</name.launcher.view.ZoomableViewGroup>
Первый фрагмент создается правильно(отображается содержимое, можно нажимать на кнопки ).., при листании другие отображаются пустыми, только после нескольких операций уменьшение масштаба появляются из одного края содержимое компонента и тогда его можно двигать по фрагменту..если не использовать данный компонент то содержимое всех фрагментов отображается нормально.. Подскажите в чем загвоздка? Куда нужно смотреть ?
Код компонента:
public class ZoomableViewGroup extends ViewGroup {
private enum Mode {
NONE,
DRAG,
ZOOM
}
private ZoomableViewGroup.Mode mode = ZoomableViewGroup.Mode.NONE;
private float scale = 1.0f;
private float lastScaleFactor = 0f;
private float mFocusY;
private float mFocusX;
private ScaleGestureDetector mScaleDetector;
private static final float MIN_ZOOM = 1.0f;
private static final float MAX_ZOOM = 3.5f;
private float startX = 0f;
private float startY = 0f;
// How much to translate the canvas
private float dx = 0f;
private float dy = 0f;
private float prevDx = 0f;
private float prevDy = 0f;
private Matrix mScaleMatrix = new Matrix();
private Matrix mScaleMatrixInverse = new Matrix();
private Matrix mTranslateMatrix = new Matrix();
private Matrix mTranslateMatrixInverse = new Matrix();
private float[] mInvalidateWorkingArray = new float[6];
private float[] mDispatchTouchEventWorkingArray = new float[2];
private float[] mOnTouchEventWorkingArray = new float[2];
public ZoomableViewGroup(Context context) {
super(context);
}
public ZoomableViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public ZoomableViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
mTranslateMatrix.setTranslate(0, 0);
mScaleMatrix.setScale(1, 1);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
Log.i("CUSTOM", "Width: " + child.getWidth());
if (child.getVisibility() != GONE) {
child.layout(l, t, l + child.getMeasuredWidth(), t + child.getMeasuredHeight());
}
}
}
@Override
protected void dispatchDraw(Canvas canvas) {
canvas.save();
//canvas.translate(startX, startY);
//canvas.scale(scale, scale);
super.dispatchDraw(canvas);
postInvalidate();
canvas.restore();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
if (child.getVisibility() != GONE) {
measureChild(child, widthMeasureSpec, heightMeasureSpec);
}
}
}
@Override
public boolean onTouchEvent(MotionEvent motionEvent) {
switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
Log.i("CUSTOM", "DOWN");
if (scale > MIN_ZOOM) {
mode = Mode.DRAG;
startX = motionEvent.getX() - prevDx;
startY = motionEvent.getY() - prevDy;
}
break;
case MotionEvent.ACTION_MOVE:
if (mode == Mode.DRAG) {
dx = motionEvent.getX() - startX;
dy = motionEvent.getY() - startY;
}
mTranslateMatrix.preTranslate(dx, dy);
mTranslateMatrix.invert(mTranslateMatrixInverse);
break;
case MotionEvent.ACTION_POINTER_DOWN:
mode = Mode.ZOOM;
break;
case MotionEvent.ACTION_POINTER_UP:
mode = Mode.DRAG;
break;
case MotionEvent.ACTION_UP:
Log.i("CUSTOM", "UP");
mode = Mode.NONE;
prevDx = dx;
prevDy = dy;
break;
}
mScaleDetector.onTouchEvent(motionEvent);
if ((mode == Mode.DRAG && scale >= MIN_ZOOM) || mode == Mode.ZOOM) {
getParent().requestDisallowInterceptTouchEvent(true);
float maxDx = (child().getWidth() - (child().getWidth() / scale)) / 2 * scale;
float maxDy = (child().getHeight() - (child().getHeight() / scale)) / 2 * scale;
dx = Math.min(Math.max(dx, -maxDx), maxDx);
dy = Math.min(Math.max(dy, -maxDy), maxDy);
Log.i("CUSTOM", "Width: " + child().getWidth() + ", scale " + scale + ", dx " + dx
+ ", max " + maxDx);
applyScaleAndTranslation();
}
invalidate();
return true;
}
private void applyScaleAndTranslation() {
int childCount = getChildCount();
child().setScaleX(scale);
child().setScaleY(scale);
child().setTranslationX(dx);
child().setTranslationY(dy);
}
private View child() {
return getChildAt(0);
}
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScaleBegin(ScaleGestureDetector scaleDetector) {
Log.i("CUSTOM", "onScaleBegin");
return true;
}
@Override
public boolean onScale(ScaleGestureDetector detector) {
float scaleFactor = detector.getScaleFactor();
Log.i("CUSTOM", "onScale" + scaleFactor);
if (detector.isInProgress()) {
mFocusX = detector.getFocusX();
mFocusY = detector.getFocusY();
}
if (lastScaleFactor == 0 || (Math.signum(scaleFactor) == Math.signum(lastScaleFactor))) {
scale *= scaleFactor;
scale = Math.max(MIN_ZOOM, Math.min(scale, MAX_ZOOM));
lastScaleFactor = scaleFactor;
} else {
lastScaleFactor = 0;
}
invalidate();
requestLayout();
return true;
}
}
}