两次渲染ViewGroup的内容

时间:2015-10-21 13:31:45

标签: android android-view google-cardboard android-viewgroup

我正试图为Google Cardboard创建一种HUD叠加层。

需要复制HUD(每只眼睛一个)。一个简单的解决方案是手动将所有XML元素复制到另一个视图中,但为它们提供不同的名称。这感觉就像一个糟糕的方法,因为它涉及大量的代码重复。

所以我为ViewGroup提出了以下解决方案,它应该两次渲染所有内容:

public class StereoView extends FrameLayout {


    private static final String TAG = StereoView.class.getSimpleName();

    public StereoView(Context context) {
        super(context);
        init(context);
    }

    private void init(Context context) {
        testPaint.setColor(Color.RED);
    }

    private Paint testPaint = new Paint(Paint.ANTI_ALIAS_FLAG);


    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right/2, bottom);
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {

        canvas.save();
        canvas.translate(getWidth() / 2, 0);

        super.dispatchDraw(canvas);

        canvas.restore();
        super.dispatchDraw(canvas);

    }

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

    public StereoView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }


    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public StereoView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context);
    }
}

第一个问题是除了一两次调用dispatchDraw或onDraw之外。当子视图无效时,不会调用它。

第二个问题是具有MATCH_PARENT的元素的背景渲染到ViewGroups内部边界之外:

200DP宽度 enter image description here

MATCH_PARENT enter image description here

这种方法是否希望过多,或者我认为错了?创建一个完全自定义的视图来处理复杂的布局和图像似乎很多工作,而复制我的布局似乎是糟糕的设计。

2 个答案:

答案 0 :(得分:2)

你说:

  

一个简单的解决方案是手动复制所有XML元素   进入另一个视图但给他们不同的名字。这感觉就像一个   糟糕的方法,因为它涉及大量的代码重复。

实际上,您可以继续使用<include>标记。您需要做的就是创建一个包含您将要show to a single eye的所有视图的布局。然后在你的主要布局中你必须<include>这个布局两次,一个用于左眼,另一个用于右眼。

您可能想知道,如果是这种情况,那么我如何在此主布局上使用findViewById(),因为现在将有两个具有相同ID的视图。好吧,你可以通过以下方式解决这个问题。假设您已创建eye.xml布局。然后,您的main_layout应如下所示。

<LinearLayout 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:orientation="horizontal">

     <include
         android:id="@+id/leftEye"
         layout="@layout/eye" />

     <include
         android:id="@+id/rightEye"
         layout="@layout/eye" />

</LinearLayout>

当您在代码中执行findViewById()时,可以执行以下操作:

 RelativeLayout leftEye = (RelativeLayout)findViewById(R.id.leftEye);
 ImageView iv = (ImageView)leftEye.findViewById(R.id.something);

您需要在活动中编写一个简单的方法,只需将leftEyerightEye作为参数传递,然后执行此方法中的所有代码。这样,您就可以同时在leftEyerightEye中执行UI更改。

将来,您可以编写一个自定义视图,您可以在其中充气eye.xml。这将模块化你的想法。

答案 1 :(得分:0)

这是我对你的问题的看法。

ViewGroup个主机View;任何xml布局都是View s,因此请扩展您选择的ViewGroupLinearLayoutFramelayout - (我更喜欢),并在初始化过程中,扩展您的布局两次,然后将其添加为View以后您可以研究如何使用onLayout()View置于首选位置。

你所谓的View 1,View 2需要在板上,你可以使用你想要的任何方法,接口或bean来绑定两者

注意

您创建一个布局并将其充气两次。这将为您提供两个单独的View个对象,因此这不会是代码重复,因为它更多的是

Elltz _20yearElltz = new Elltz(20),_21yearElltz = new Elltz(21);

希望有所帮助