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