【问题标题】:Center objects inside a RelativeLayout Inside Viewgroup在相对布局内部视图组中居中对象
【发布时间】:2016-07-05 01:35:42
【问题描述】:

我花了几个小时试图修复一个愚蠢的小错误(从我的角度来看)。
它就像我无法以相对布局(在视图组内)2 Textviews 为中心。
这是一个能够旋转容器的自定义 ViewGroup。
我已经检查了很多其他类似问题的帖子,但没有任何解决方案有效。

我尝试使用重力、alignText 以及我找到的所有组合。
希望有人能看到代码中的错误!

这是我的 XML:

  <com.android.ui.common.RotatableContainer
    android:id="@+id/preview_undo_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginTop="@dimen/module_indicator_height"
    android:background="@android:color/holo_blue_light"
    android:padding="@dimen/content_padding_small"
    >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/holo_red_light"
        android:padding="@dimen/content_padding_small"
        android:gravity="center">

        <TextView
            android:id="@+id/undo_info_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="La foto se ha eliminado."
            android:textColor="@android:color/white"
            android:layout_centerInParent="true"

            />

        <TextView
            android:id="@+id/delete_undo_bottom"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="@dimen/content_margin_normal"
            android:layout_toEndOf="@id/undo_info_text"
            android:text="Deshacer"
            android:textAllCaps="true"
            android:textColor="@android:color/white" />

    </RelativeLayout>

</com.android.ui.common.RotatableContainer>

这是我的 CustomContainer 的代码:

 * Rotates first view in this layout by multiple of 90 mAngle.
 * <p/>
 * This layout is supposed to have only one view. Behaviour of the views after the first one
 * is not defined.
 * <p/>
 * Rotate angles can be only multiple of 90.
 * If mAngle is not multiple of 90 it will be reduced to the multiple of 90.
 * For example 89 will be reduced to 0, 91 will be reduced to 90.
 */
public class RotatableContainer extends ViewGroup {

    private int mAngle;

    private final Matrix mRotateMatrix = new Matrix();

    private final Rect mViewRectRotated = new Rect();

    private final RectF mTempRectF1 = new RectF();
    private final RectF mTempRectF2 = new RectF();

    private final float[] mViewTouchPoint = new float[2];
    private final float[] mChildTouchPoint = new float[2];

    private boolean mAngleChanged = true;

    public RotatableContainer(Context context) {
        this(context, null);
    }

    public RotatableContainer(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RotatableContainer(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs);

        final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RotatableContainer);
        final int angleFromAttrs = a.getInt(R.styleable.RotatableContainer_angle, 0);
        mAngle = fixAngle(angleFromAttrs);
        a.recycle();

        setWillNotDraw(false);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final View view = getView();
        if (view != null) {
            if (Math.abs(mAngle % 180) == 90) {
                //noinspection SuspiciousNameCombination
                measureChild(view, heightMeasureSpec, widthMeasureSpec);
                setMeasuredDimension(
                        resolveSize(view.getMeasuredHeight(), widthMeasureSpec),
                        resolveSize(view.getMeasuredWidth(), heightMeasureSpec));
            } else {
                measureChild(view, widthMeasureSpec, heightMeasureSpec);
                setMeasuredDimension(
                        resolveSize(view.getMeasuredWidth(), widthMeasureSpec),
                        resolveSize(view.getMeasuredHeight(), heightMeasureSpec));
            }
        } else {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        if (mAngleChanged || changed) {
            final RectF layoutRect = mTempRectF1;
            final RectF layoutRectRotated = mTempRectF2;
            layoutRect.set(0, 0, r - l, b - t);
            mRotateMatrix.setRotate(mAngle, layoutRect.centerX(), layoutRect.centerY());
            mRotateMatrix.mapRect(layoutRectRotated, layoutRect);
            layoutRectRotated.round(mViewRectRotated);
            mAngleChanged = false;
        }

        final View view = getView();
        if (view != null) {
            view.layout(mViewRectRotated.left, mViewRectRotated.top, mViewRectRotated.right, mViewRectRotated.bottom);
        }
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        canvas.save();
        canvas.rotate(-mAngle, getWidth() / 2f, getHeight() / 2f);
        super.dispatchDraw(canvas);
        canvas.restore();
    }

    @Override
    public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
        invalidate();
        return super.invalidateChildInParent(location, dirty);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        mViewTouchPoint[0] = event.getX();
        mViewTouchPoint[1] = event.getY();

        mRotateMatrix.mapPoints(mChildTouchPoint, mViewTouchPoint);

        event.setLocation(mChildTouchPoint[0], mChildTouchPoint[1]);
        boolean result = super.dispatchTouchEvent(event);
        event.setLocation(mViewTouchPoint[0], mViewTouchPoint[1]);

        return result;
    }

    /**
     * Returns current mAngle of this layout
     */
    public int getAngle() {
        return mAngle;
    }

    /**
     * Sets current mAngle of this layout.
     * If mAngle is not multiple of 90 it will be reduced to the multiple of 90.
     * For example 89 will be reduced to 0, 91 will be reduced to 90.
     */
    public void setAngle(int mAngle) {
        int fixedAngle = fixAngle(mAngle);
        if (this.mAngle != fixedAngle) {
            this.mAngle = fixedAngle;
            mAngleChanged = true;
            requestLayout();
        }
    }

    /**
     * Returns
     */
    public View getView() {
        if (getChildCount() > 0) {
            return getChildAt(0);
        } else {
            return null;
        }
    }

    /**
     * Takes any mAngle, makes it valid one for this view.
     * This means multiple of 90.
     */
    private static int fixAngle(int angle) {
        return (angle / 90) * 90;
    }

}

以及我对 View 的测量方法:

       public void positionUndoBarContainer(int orientation) {
        Size currentPreviewSize = CameraUtil.getPreviewSizeForAspectRatio(mContext, mAspectRatio);
        if (mUndoContainer.getAngle() != orientation)
            mUndoContainer.setAngle(orientation);

//       
        mUndoContainer.layout(getLeft(), getPreviewTop(), getLeft() + getWidth(), getPreviewTop() + currentPreviewSize.getHeight());
        Log.i(TAG, "measure" + mUndoContainer.getMeasuredHeight() + " normal" + mUndoContainer.getHeight());

        requestLayout();
    }

垂直看起来像:

像这样在水平方向:

如您所见,容器已正确旋转并位于中间,但里面的文字没有,我找不到原因>.

【问题讨论】:

    标签: android xml text view centering


    【解决方案1】:

    在RelativeLayout 的中心放置一个虚拟 视图(一个裸露的View,0dp 宽和高)。

    然后,对于 水平 对齐方式,将一个 TextView 对齐到它的右侧,另一个对齐到它的左侧。
    对于垂直对齐,将一个 TextView 对齐到它的顶部,另一个对齐到它的底部。

    【讨论】:

    • 嗨,伙计!好主意,但看起来它不起作用。问题不在于位置,就像我的相对布局没有正确到达中间一样。但在其他方面,全屏是蓝色的,而相对(红色)正确地位于我的可旋转布局的中间。但是当我居中时它总是无序的,我不知道为什么
    • 同时删除gravity 属性。 is not getting the middle correctly 对我来说没有多大意义。除非您自己没有绘制自定义 ViewGroup - 在这种情况下会出现一些计算错误。
    • 给我一分钟,我会上传一些照片。是的,我自己绘制视图。我现在就更新代码
    • 现在,在没有分析代码的情况下,我发现TextViews的相对定位还有一些问题。 1 - 我会给它们一个固定的宽度,而不是wrap_content,以 dp 为单位。 2 - 我不会设置 toEndOf 另一个 TextView。 3 - 我也会使用match_parent 作为RelativeLayout 的高度
    • 最后,我设法使用自定义视图的 onlayout() 和 onmeasure() 方法定位文本。你的回答对我帮助很大。非常感谢你!
    【解决方案2】:

    RotatableContainer中添加android:gravity="center"

    【讨论】:

    • 试过的伙伴,它没有将容器的内容居中
    猜你喜欢
    • 2017-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多