为什么ImageView在填充上绘制?

时间:2014-08-12 16:54:38

标签: android imageview pinchzoom

我实现了一个ImageView扩展视图,通过手势监听器进行缩放和平移。它工作得很好,但我的问题是我需要在这个视图周围有一个白色边框。

我尝试添加填充并将位图背景设置为白色,但它没有正常工作:视图右侧和顶部有白色边框但是朝向它们缩放。

将视图放置到布局中可以正常工作(我尝试过),但这样会使其布局代码变得复杂。

我试图在图像后面绘制矩形,但它没有正常工作。事实上,我试过的方式根本没有用。

所以我想知道有没有办法拥有(绘制或填充)视图周围的白色边框,可以缩放和平移

我认为这个问题在onMeasure中存在,但我真的不知道从哪里开始。

我的视图被放置在布局中,覆盖了onMeasure(顺便说一下如何使它更好?它现在很难看:():

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    int myWidth = MeasureSpec.getSize(widthMeasureSpec);
    int myHeight = MeasureSpec.getSize(heightMeasureSpec);

    float leftHeight = myHeight * 12f / 15f;

    int count = getChildCount();

    for (int i = 0; i < count; i++) {
        View child = getChildAt(i);
        if (child != null) {
            switch (child.getId()) {
                case R.id.llButtons:
                    child.measure(MeasureSpec.makeMeasureSpec(myWidth - 20,
                                    MeasureSpec.UNSPECIFIED),
                            MeasureSpec.makeMeasureSpec((int) (myHeight / 15f), MeasureSpec.AT_MOST)
                    );
                    break;
                case R.id.hsvFilters:
                    child.measure(myWidth, MeasureSpec.makeMeasureSpec((int) (myHeight * 2f /
                                    15f),
                            MeasureSpec.AT_MOST
                    ));

                    break;
                case R.id.flFrame:
                    child.measure(myWidth - 20,
                            (int) leftHeight);
                    break;
            }
        }
    }
}

布局:

<com.project.android.views.FluidContainer          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"
                                    android:id="@+id/fdAdjustImage"
                                    android:orientation="vertical"
          tools:context="com.project.android.dialogs.AdjustImageFragment">

<LinearLayout
    android:weightSum="100"
    android:id="@+id/llButtons"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_margin="10dp"
    android:layout_height="wrap_content">

    <com.inkly.android.views.ButtonFont
        android:id="@+id/bChangePhoto"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginRight="15dp"
        android:textSize="19sp"
        android:layout_weight="45"
        android:text="@string/change_photo"
        android:background="@drawable/btn_blue"
        style="@style/RegularButton"/>

    <View
        android:layout_weight="10"
        android:layout_width="0dp"
        android:layout_height="wrap_content"/>

    <com.inkly.android.views.ButtonFont
        android:id="@+id/bDone"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="15dp"
        android:gravity="center"
        android:textSize="19sp"
        android:layout_weight="45"
        android:text="@string/done"
        android:background="@drawable/btn_green"
        style="@style/RegularButton"/>

</LinearLayout>


<com.inkly.android.views.FluidCard
    android:background="#fff"
    android:layout_gravity="center"
    android:padding="10dp"
    android:id="@+id/flFrame"
    android:layout_centerInParent="true"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

<ProgressBar
    android:id="@+id/progress"
    android:layout_centerInParent="true"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:indeterminateOnly="true"
    android:layout_gravity="center"
    style="@android:style/Widget.Holo.Light.ProgressBar.Large"/>


<HorizontalScrollView
    android:layout_width="match_parent"
    android:scrollbars="none"
    android:id="@+id/hsvFilters"
    android:background="#fff"
    android:layout_alignParentBottom="true"
    android:layout_height="wrap_content">

    <LinearLayout
        android:layout_width="wrap_content"
        android:orientation="horizontal"
        android:id="@+id/llFilters"
        android:layout_height="wrap_content"/>

</HorizontalScrollView>

和我的观点:

缩放:

public FluidCard(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);

    setScaleType(ScaleType.MATRIX);

    mScaleDetector = new ScaleGestureDetector(context, new ScaleGestureDetector.SimpleOnScaleGestureListener() {
        float mFocusX;
        float mFocusY;
        float mScaleMoveX = 0;
        float mScaleMoveY = 0;

        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            mFocusX = detector.getFocusX();
            mFocusY = detector.getFocusY();
            mScaleMoveX = mFocusX * (1f - mScaleFactor);
            mScaleMoveY = mFocusY * (1f - mScaleFactor);
            return true;
        }

        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            float newScaleFactor = mScaleFactor * detector.getScaleFactor();
            if (newScaleFactor < mScaleFactor) {
                newScaleFactor *= 0.94f;
            }
            newScaleFactor = Math.max(1f, Math.min(newScaleFactor, 10.0f));
            boolean isDecrease = newScaleFactor < mScaleFactor;
            mScaleFactor = newScaleFactor;

            float newScaleMoveX = mFocusX * (1f - mScaleFactor);
            float newScaleMoveY = mFocusY * (1f - mScaleFactor);

            if (newScaleMoveX != mScaleMoveX || newScaleMoveY != mScaleMoveY) {
                float dx = newScaleMoveX - mScaleMoveX;
                float dy = newScaleMoveY - mScaleMoveY;
                if (isDecrease) {
                    float minOffsX = getMeasuredWidth() - 10 - mScaledWidth * mScaleFactor;
                    if (mMoveX + dx < minOffsX) {
                        mMoveX = minOffsX;
                    } else {
                        if (mMoveX + dx <= 0) {
                            mMoveX += dx;
                        } else {
                            mMoveX = 0;
                        }
                    }
                    float minOffsY = getMeasuredHeight() - 10 - mScaledHeight * mScaleFactor;
                    if (mMoveY + dy < minOffsY) {
                        mMoveY = minOffsY;
                    } else {
                        if (mMoveY + dy <= 0) {
                            mMoveY += dx;
                        } else {
                            mMoveY = 0;
                        }
                    }
                } else {
                    mMoveX += dx;
                    mMoveY += dy;
                }
                mScaleMoveX = newScaleMoveX;
                mScaleMoveY = newScaleMoveY;

                mForceInvalidate = true;
            }

            return true;
        }
    });
    mMoveDetector = new MoveGestureDetector(context, new MoveGestureDetector.SimpleOnMoveGestureListener() {
        @Override
        public boolean onMoveBegin(MoveGestureDetector detector) {
            return true;
        }

        @Override
        public boolean onMove(MoveGestureDetector detector) {
            PointF focusDelta = detector.getFocusDelta();

            float newX = mMoveX + focusDelta.x;
            if (newX <= 0 && newX + mScaledWidth * mScaleFactor >= getMeasuredWidth() - 10) {
                mMoveX = newX;
                mForceInvalidate = true;
            }
            float newY = mMoveY + focusDelta.y;
            if (newY <= 0 && newY + mScaledHeight * mScaleFactor >= getMeasuredHeight() - 10) {
                mMoveY = newY;
                mForceInvalidate = true;
            }
            return true;
        }
    });
    mPaint.setFilterBitmap(false);
    mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));

    rectPaint.setColor(Color.WHITE);

    mBackground = new Rect();
}

onMeasure:

 @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    if (w == 0 && h == 0) {
        int oldWidth = MeasureSpec.getSize(widthMeasureSpec);
        int oldHeight = MeasureSpec.getSize(heightMeasureSpec);

        double width, height;

        if (mAspectRatio > 1f) {
            height = oldHeight;
            width = Math.ceil(oldHeight / mAspectRatio);
        } else {
            width = oldWidth;
            height = Math.ceil(oldWidth * mAspectRatio);
        }

        if (height > oldHeight || width > oldWidth) {
            float k = 1.1f;
            while (height > oldHeight || width > oldWidth) {
                height /= k;
                width /= k;
                k += 0.01f;
            }
        }
        w = (int) Math.ceil(width);
        h = (int) Math.ceil(height);
    }

    if (getDrawable() != null) {
        setupMatrix(w, h);


    }

    setMeasuredDimension(w, h);
}

onTouch:

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (mEditEnabled) {
        mScaleDetector.onTouchEvent(event);
        boolean isScaling = mScaleDetector.isInProgress();
        if (!isScaling) mMoveDetector.onTouchEvent(event);

        if (mForceInvalidate) {
            mForceInvalidate = false;
            mMatrix.reset();
            mMatrix.setScale(mScale, mScale);

            if (mScaleFactor > 1) {
                mMatrix.postScale(mScaleFactor, mScaleFactor);
            }
            mMatrix.postTranslate(mMoveX, mMoveY);
            invalidate();
        }
        return true;
    }
    return super.onTouchEvent(event);
}

拉​​伸:

@Override
public void draw(Canvas canvas) {
    int sc = canvas.saveLayer(10, 10, getWidth() - 10, getHeight() - 10, null,
            Canvas.CLIP_TO_LAYER_SAVE_FLAG);// | Canvas.FULL_COLOR_LAYER_SAVE_FLAG ?

    canvas.save(Canvas.MATRIX_SAVE_FLAG);
    canvas.setMatrix(mMatrix);
    super.draw(canvas);
    canvas.restore();

    canvas.restoreToCount(sc);
}

UPD:

android:cropToPadding="true"没有按照我需要的方式工作,虽然结果图片现在变小了(但这并不好)。

0 个答案:

没有答案