如何在绝对布局上实现“捏缩放”?

时间:2014-07-22 09:42:44

标签: android pinchzoom absolutelayout

我想在Absolute布局上实现“捏拉缩放”功能,但遗憾的是宽度和高度都是固定的。我使用绝对布局绝对位置。请不要问我为什么使用不推荐使用的绝对布局。你可以在文本视图中捏缩放第二个图像时的行为吗?

MyAbsolutelayout.java

wall

wall2

public class MyAbsoluteLayout extends ViewGroup {
public MyAbsoluteLayout(Context context) {
    super(context);
}

public MyAbsoluteLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
}

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

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int childCount = getChildCount();
    measureChildren(getMeasuredWidthAndState(),getMeasuredHeightAndState());
    int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
    int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
    int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
    int width = 0;
    int height = 0;
    int childState = 0;


    // Measure Width
    if (widthSpecMode == MeasureSpec.EXACTLY) {
        width = widthSpecSize;
    } else {
        for (int i = 0; i < childCount; i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() != GONE) {
                measureChild(child, widthMeasureSpec, heightMeasureSpec);
                width += child.getMeasuredWidth();
            }
        }
    }
    if (widthSpecMode == MeasureSpec.AT_MOST) {
        width = Math.min(width, widthSpecSize);
    }

    // Measure Height
    if (heightSpecMode == MeasureSpec.EXACTLY) {
        height = heightSpecSize;
    } else {
        for (int i = 0; i < childCount; i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() != GONE) {
                height = Math.max(height, child.getMeasuredHeight());
            }
        }
    }
    if (heightSpecMode == MeasureSpec.AT_MOST) {
        height = Math.min(height, heightSpecSize);
    }

    // Combine child states
    for (int i = 0; i < childCount; i++) {
        final View child = getChildAt(i);
        if (child.getVisibility() != GONE) {
            childState = combineMeasuredStates(childState, child.getMeasuredState());
        }
    }

    // Check against minimum width and height
    width = Math.max(width, getSuggestedMinimumWidth());
    height = Math.max(height, getSuggestedMinimumHeight());

    // Report final dimensions
    setMeasuredDimension(resolveSizeAndState(width, widthMeasureSpec, childState),
            resolveSizeAndState(height, heightMeasureSpec, childState << MEASURED_HEIGHT_STATE_SHIFT));
}

/**
 * Returns a set of layout parameters with a width of
 * {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT},
 * a height of {@link android.view.ViewGroup.LayoutParams#WRAP_CONTENT}
 * and with the coordinates (0, 0).
 */
@Override
protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
    return new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT, 0, 0);
}

@Override
protected void onLayout(boolean changed, int l, int t,
        int r, int b) {
    int count = getChildCount();

    int paddingL = getPaddingLeft ();
    int paddingT = getPaddingTop ();
    for (int i = 0; i < count; i++) {
        View child = getChildAt(i);
        if (child.getVisibility() != GONE) {

            LayoutParams lp =
                    (LayoutParams) child.getLayoutParams();

            int childLeft = paddingL + lp.x;
            int childTop = paddingT + lp.y;
            /*
            int childLeft = mPaddingLeft + lp.x;
            int childTop = mPaddingTop + lp.y;
            */
            child.layout(childLeft, childTop,
                    childLeft + child.getMeasuredWidth(),
                    childTop + child.getMeasuredHeight());

        }
    }
}

@Override
public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
    return new LayoutParams(getContext(), attrs);
}

// Override to allow type-checking of LayoutParams. 
@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
    return p instanceof LayoutParams;
}

@Override
protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
    return new LayoutParams(p);
}

/**
 * Per-child layout information associated with MyAbsoluteLayout.
 * See

 * for a list of all child view attributes that this class supports.
 */
public static class LayoutParams extends ViewGroup.LayoutParams {
    /**
     * The horizontal, or X, location of the child within the view group.
     */
    public int x;
    /**
     * The vertical, or Y, location of the child within the view group.
     */
    public int y;

    /**
     * Creates a new set of layout parameters with the specified width,
     * height and location.
     *
     * @param width the width, either {@link #MATCH_PARENT},
              {@link #WRAP_CONTENT} or a fixed size in pixels
     * @param height the height, either {@link #MATCH_PARENT},
              {@link #WRAP_CONTENT} or a fixed size in pixels
     * @param x the X location of the child
     * @param y the Y location of the child
     */
    public LayoutParams(int width, int height, int x, int y) {
        super(width, height);
        this.x = x;
        this.y = y;
    }

    /**
     * Creates a new set of layout parameters. The values are extracted from
     * the supplied attributes set and context. The XML attributes mapped
     * to this set of layout parameters are:
     *
     * <ul>
     *   <li><code>layout_x</code>: the X location of the child</li>
     *   <li><code>layout_y</code>: the Y location of the child</li>
     *   <li>All the XML attributes from
     *   {@link android.view.ViewGroup.LayoutParams}</li>
     * </ul>
     *
     * @param c the application environment
     * @param attrs the set of attributes from which to extract the layout
     *              parameters values
     */
    public LayoutParams(Context c, AttributeSet attrs) {
        super(c, attrs);
        /* FIX THIS eventually. Without this, I don't think you can put x and y in layout xml files.
        TypedArray a = c.obtainStyledAttributes(attrs,
                com.android.internal.R.styleable.AbsoluteLayout_Layout);
        x = a.getDimensionPixelOffset(
                com.android.internal.R.styleable.AbsoluteLayout_Layout_layout_x, 0);
        y = a.getDimensionPixelOffset(
                com.android.internal.R.styleable.AbsoluteLayout_Layout_layout_y, 0);
        a.recycle();
        */
    }

    /**
     * {@inheritDoc}
     */
    public LayoutParams(ViewGroup.LayoutParams source) {
        super(source);
    }

    public String debug(String output) {
        return output + "Absolute.LayoutParams={width="
                + sizeToString(width) + ", height=" + sizeToString(height)
                + " x=" + x + " y=" + y + "}";
    }

  /**
     * Converts the specified size to a readable String.
     *
     * @param size the size to convert
     * @return a String instance representing the supplied size
     *
     * @hide
     */
    protected static String sizeToString(int size) {
        if (size == WRAP_CONTENT) {
            return "wrap-content";
        }
        if (size == MATCH_PARENT) {
            return "match-parent";
        }
        return String.valueOf(size);
    }
   } 

}

0 个答案:

没有答案