ProjectionActivity.java revision 6657a6c53930eb0ff8d03317eb10ea7ddb0c49b4
1package com.android.test.hwui;
2
3import android.content.Context;
4import android.graphics.Canvas;
5import android.graphics.Paint;
6import android.graphics.RectF;
7import android.os.Bundle;
8
9import android.app.Activity;
10import android.util.AttributeSet;
11import android.view.DisplayList;
12import android.view.View;
13import android.widget.LinearLayout;
14
15public class ProjectionActivity extends Activity {
16    /**
17     * The content from this view should be projected in between the background of the
18     * ProjecteeLayout and its children, unclipped.
19     *
20     * This view doesn't clip to its bounds (because its parent has clipChildren=false) so that
21     * when it is projected onto the ProjecteeLayout, it draws outside its view bounds.
22     */
23    public static class ProjectedView extends View {
24        private final Paint mPaint = new Paint();
25        private final RectF mRectF = new RectF();
26
27        public ProjectedView(Context context) {
28            this(context, null);
29        }
30
31        public ProjectedView(Context context, AttributeSet attrs) {
32            this(context, attrs, 0);
33        }
34
35        public ProjectedView(Context context, AttributeSet attrs, int defStyleAttr) {
36            super(context, attrs, defStyleAttr);
37
38            setOnClickListener(new OnClickListener() {
39                boolean toggle = false;
40                @Override
41                public void onClick(View v) {
42                    toggle = !toggle;
43                    setProject(toggle);
44                }
45            });
46        }
47
48        private void setProject(boolean value) {
49            DisplayList displayList = getDisplayList();
50            if (displayList != null) {
51                displayList.setProjectBackwards(value);
52            }
53            // NOTE: we can't invalidate ProjectedView for the redraw because:
54            // 1) the view won't preserve displayList properties that it doesn't know about
55            // 2) the damage rect won't be big enough
56
57            // instead, twiddle properties on the container, so that enough area of the screen is
58            // redrawn without rerecording any DisplayLists.
59            container.setTranslationX(100f);
60            container.setTranslationX(0.0f);
61        }
62
63        @Override
64        protected void onDraw(Canvas canvas) {
65            // TODO: set projection flag
66            final int w = getWidth();
67            final int h = getHeight();
68            mRectF.set(0, -h, w, 2 * h);
69            mPaint.setAntiAlias(true);
70            mPaint.setColor(0x5f00ff00);
71            canvas.drawOval(mRectF, mPaint);
72        }
73    }
74
75    public static class ProjecteeLayout extends LinearLayout {
76        private final Paint mPaint = new Paint();
77        private final RectF mRectF = new RectF();
78
79        public ProjecteeLayout(Context context) {
80            this(context, null);
81        }
82
83        public ProjecteeLayout(Context context, AttributeSet attrs) {
84            this(context, attrs, 0);
85        }
86
87        public ProjecteeLayout(Context context, AttributeSet attrs, int defStyle) {
88            super(context, attrs, defStyle);
89        }
90
91        @Override
92        protected void dispatchDraw(Canvas canvas) {
93            canvas.save(0x20); // secret save flag
94            mRectF.set(0, 0, getWidth(), getHeight());
95            mPaint.setColor(0x5f000000);
96            canvas.drawOval(mRectF, mPaint);
97            canvas.restore();
98            super.dispatchDraw(canvas);
99        }
100    }
101
102    static View container;
103
104    @Override
105    protected void onCreate(Bundle savedInstanceState) {
106        super.onCreate(savedInstanceState);
107        setContentView(R.layout.projection);
108        container = findViewById(R.id.container);
109    }
110}
111