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.view.RenderNode;
12 import android.view.View;
13 import android.widget.LinearLayout;
14 
15 public 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 
ProjectedView(Context context)27         public ProjectedView(Context context) {
28             this(context, null);
29         }
30 
ProjectedView(Context context, AttributeSet attrs)31         public ProjectedView(Context context, AttributeSet attrs) {
32             this(context, attrs, 0);
33         }
34 
ProjectedView(Context context, AttributeSet attrs, int defStyleAttr)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 
setProject(boolean value)48         private void setProject(boolean value) {
49             RenderNode renderNode = updateDisplayListIfDirty();
50             if (renderNode != null) {
51                 renderNode.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
onDraw(Canvas canvas)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     static View container;
76 
77     @Override
onCreate(Bundle savedInstanceState)78     protected void onCreate(Bundle savedInstanceState) {
79         super.onCreate(savedInstanceState);
80         setContentView(R.layout.projection);
81         container = findViewById(R.id.container);
82     }
83 }
84