diff options
| author | Dianne Hackborn <hackbod@google.com> | 2013-12-05 10:08:56 -0800 |
|---|---|---|
| committer | Android Git Automerger <android-git-automerger@android.com> | 2013-12-05 10:08:56 -0800 |
| commit | 59e6f5d9c99d216db6db7e5e56648daaf909d328 (patch) | |
| tree | 09165872f2d33ffe03e5e63e7999790d26961d6a /samples | |
| parent | aa198e6cd531c5c069c8f5bff94f8c889ad6c59a (diff) | |
| parent | 18159037a4f6a6b539736f6b8c0bdab4d26e3bd7 (diff) | |
| download | android_development-59e6f5d9c99d216db6db7e5e56648daaf909d328.tar.gz android_development-59e6f5d9c99d216db6db7e5e56648daaf909d328.tar.bz2 android_development-59e6f5d9c99d216db6db7e5e56648daaf909d328.zip | |
am 18159037: Add API demo for game style system UI interaction.
* commit '18159037a4f6a6b539736f6b8c0bdab4d26e3bd7':
Add API demo for game style system UI interaction.
Diffstat (limited to 'samples')
4 files changed, 292 insertions, 12 deletions
diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml index d7bda3125..f202d595d 100644 --- a/samples/ApiDemos/AndroidManifest.xml +++ b/samples/ApiDemos/AndroidManifest.xml @@ -2469,6 +2469,16 @@ </intent-filter> </activity> + <activity android:name=".view.GameActivity" + android:label="Views/System UI Visibility/Game" + android:theme="@android:style/Theme.Holo.NoActionBar" + android:enabled="@bool/atLeastKitKat"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.SAMPLE_CODE" /> + </intent-filter> + </activity> + <activity android:name=".view.Switches" android:label="Views/Switches"> <intent-filter> <action android:name="android.intent.action.MAIN" /> diff --git a/samples/ApiDemos/res/layout/game.xml b/samples/ApiDemos/res/layout/game.xml new file mode 100644 index 000000000..809a253c1 --- /dev/null +++ b/samples/ApiDemos/res/layout/game.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2013 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<!-- BEGIN_INCLUDE(complete) --> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" android:layout_height="match_parent" + > + <!-- This is the outer area of the entire game screen, extending out under + system UI elements. --> + <view class="com.example.android.apis.view.GameActivity$Content" + android:id="@+id/content" + android:src="@drawable/frantic" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:scaleType="center" + /> + <!-- This is the inner area of the game, not covered by system UI elements. + Any UI elements that need to be accessible when the game is paused or other + states where the system UI is shown (such as in menus) should go here. --> + <FrameLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:fitsSystemWindows="true" + android:animateLayoutChanges="true" + > + <Button + android:id="@+id/play" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="top|right" + android:textSize="28dp" + /> + </FrameLayout> +</FrameLayout> +<!-- END_INCLUDE(complete) --> diff --git a/samples/ApiDemos/src/com/example/android/apis/graphics/TouchPaint.java b/samples/ApiDemos/src/com/example/android/apis/graphics/TouchPaint.java index c3c8a6cc3..a86301415 100644 --- a/samples/ApiDemos/src/com/example/android/apis/graphics/TouchPaint.java +++ b/samples/ApiDemos/src/com/example/android/apis/graphics/TouchPaint.java @@ -26,6 +26,7 @@ import android.graphics.RectF; import android.os.Bundle; import android.os.Handler; import android.os.Message; +import android.util.AttributeSet; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; @@ -87,9 +88,6 @@ public class TouchPaint extends GraphicsActivity { /** Is fading mode enabled? */ boolean mFading; - /** The index of the current color to use. */ - int mColorIndex; - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -104,10 +102,10 @@ public class TouchPaint extends GraphicsActivity { // the contents of the bitmap. if (savedInstanceState != null) { mFading = savedInstanceState.getBoolean("fading", true); - mColorIndex = savedInstanceState.getInt("color", 0); + mView.mColorIndex = savedInstanceState.getInt("color", 0); } else { mFading = true; - mColorIndex = 0; + mView.mColorIndex = 0; } } @@ -161,7 +159,7 @@ public class TouchPaint extends GraphicsActivity { // Save away the fading state to restore if needed later. Note that // we do not currently save the contents of the display. outState.putBoolean("fading", mFading); - outState.putInt("color", mColorIndex); + outState.putInt("color", mView.mColorIndex); } @Override @@ -225,9 +223,9 @@ public class TouchPaint extends GraphicsActivity { * * It handles all of the input events and drawing functions. */ - class PaintView extends View { + public static class PaintView extends View { private static final int FADE_ALPHA = 0x06; - private static final int MAX_FADE_STEPS = 256 / FADE_ALPHA + 4; + private static final int MAX_FADE_STEPS = 256 / (FADE_ALPHA/2) + 4; private static final int TRACKBALL_SCALE = 10; private static final int SPLAT_VECTORS = 40; @@ -235,21 +233,31 @@ public class TouchPaint extends GraphicsActivity { private final Random mRandom = new Random(); private Bitmap mBitmap; private Canvas mCanvas; - private final Paint mPaint; - private final Paint mFadePaint; + private final Paint mPaint = new Paint(); + private final Paint mFadePaint = new Paint(); private float mCurX; private float mCurY; private int mOldButtonState; private int mFadeSteps = MAX_FADE_STEPS; + /** The index of the current color to use. */ + int mColorIndex; + public PaintView(Context c) { super(c); + init(); + } + + public PaintView(Context c, AttributeSet attrs) { + super(c, attrs); + init(); + } + + private void init() { setFocusable(true); - mPaint = new Paint(); mPaint.setAntiAlias(true); - mFadePaint = new Paint(); mFadePaint.setColor(BACKGROUND_COLOR); mFadePaint.setAlpha(FADE_ALPHA); } @@ -273,6 +281,31 @@ public class TouchPaint extends GraphicsActivity { } } + public void text(String text) { + if (mBitmap != null) { + final int width = mBitmap.getWidth(); + final int height = mBitmap.getHeight(); + mPaint.setColor(COLORS[mColorIndex]); + mPaint.setAlpha(255); + int size = height; + mPaint.setTextSize(size); + Rect bounds = new Rect(); + mPaint.getTextBounds(text, 0, text.length(), bounds); + int twidth = bounds.width(); + twidth += (twidth/4); + if (twidth > width) { + size = (size*width)/twidth; + mPaint.setTextSize(size); + mPaint.getTextBounds(text, 0, text.length(), bounds); + } + Paint.FontMetrics fm = mPaint.getFontMetrics(); + mCanvas.drawText(text, (width-bounds.width())/2, + ((height-size)/2) - fm.ascent, mPaint); + mFadeSteps = 0; + invalidate(); + } + } + @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { int curW = mBitmap != null ? mBitmap.getWidth() : 0; diff --git a/samples/ApiDemos/src/com/example/android/apis/view/GameActivity.java b/samples/ApiDemos/src/com/example/android/apis/view/GameActivity.java new file mode 100644 index 000000000..a02542707 --- /dev/null +++ b/samples/ApiDemos/src/com/example/android/apis/view/GameActivity.java @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.android.apis.view; + +import android.app.ActionBar; +import android.app.ActionBar.Tab; +import android.app.Activity; +import android.app.FragmentTransaction; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.util.AttributeSet; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.SearchView; +import android.widget.SeekBar; +import android.widget.ShareActionProvider; +import android.widget.TextView; +import android.widget.Toast; +import android.widget.SearchView.OnQueryTextListener; + +import com.example.android.apis.R; +import com.example.android.apis.graphics.TouchPaint; + +/** + * This activity demonstrates how to use the system UI flags to + * implement an immersive game. + */ +public class GameActivity extends Activity { + + /** + * Implementation of a view for the game, filling the entire screen. + */ +//BEGIN_INCLUDE(content) + public static class Content extends TouchPaint.PaintView implements + View.OnSystemUiVisibilityChangeListener, View.OnClickListener { + Activity mActivity; + Button mPlayButton; + boolean mPaused; + int mLastSystemUiVis; + boolean mUpdateSystemUi; + + Runnable mFader = new Runnable() { + @Override public void run() { + fade(); + if (mUpdateSystemUi) { + updateNavVisibility(); + } + if (!mPaused) { + getHandler().postDelayed(mFader, 1000/30); + } + } + }; + + public Content(Context context, AttributeSet attrs) { + super(context, attrs); + setOnSystemUiVisibilityChangeListener(this); + } + + public void init(Activity activity, Button playButton) { + // This called by the containing activity to supply the surrounding + // state of the game that it will interact with. + mActivity = activity; + mPlayButton = playButton; + mPlayButton.setOnClickListener(this); + setGamePaused(true); + } + + @Override public void onSystemUiVisibilityChange(int visibility) { + // Detect when we go out of nav-hidden mode, to reset back to having + // it hidden; our game wants those elements to stay hidden as long + // as it is being played and stay shown when paused. + int diff = mLastSystemUiVis ^ visibility; + mLastSystemUiVis = visibility; + if (!mPaused && (diff&SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0 + && (visibility&SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) { + // We are running and the system UI navigation has become + // shown... we want it to remain hidden, so update our system + // UI state at the next game loop. + mUpdateSystemUi = true; + } + } + + @Override protected void onWindowVisibilityChanged(int visibility) { + super.onWindowVisibilityChanged(visibility); + + // When we become visible or invisible, play is paused. + setGamePaused(true); + } + + @Override + public void onWindowFocusChanged(boolean hasWindowFocus) { + super.onWindowFocusChanged(hasWindowFocus); + + // When we become visible or invisible, play is paused. + // Optional: pause game when window loses focus. This will cause it to + // pause, for example, when the notification shade is pulled down. + if (!hasWindowFocus) { + //setGamePaused(true); + } + } + + @Override public void onClick(View v) { + if (v == mPlayButton) { + // Clicking on the play/pause button toggles its state. + setGamePaused(!mPaused); + } + } + + void setGamePaused(boolean paused) { + mPaused = paused; + mPlayButton.setText(paused ? R.string.play : R.string.pause); + setKeepScreenOn(!paused); + updateNavVisibility(); + Handler h = getHandler(); + if (h != null) { + getHandler().removeCallbacks(mFader); + if (!paused) { + mFader.run(); + text("Draw!"); + } + } + } + + void updateNavVisibility() { + int newVis = SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | SYSTEM_UI_FLAG_LAYOUT_STABLE; + if (!mPaused) { + newVis |= SYSTEM_UI_FLAG_LOW_PROFILE | SYSTEM_UI_FLAG_FULLSCREEN + | SYSTEM_UI_FLAG_HIDE_NAVIGATION | SYSTEM_UI_FLAG_IMMERSIVE_STICKY; + } + + // Set the new desired visibility. + setSystemUiVisibility(newVis); + mUpdateSystemUi = false; + } + } +//END_INCLUDE(content) + + Content mContent; + + public GameActivity() { + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.game); + mContent = (Content)findViewById(R.id.content); + mContent.init(this, (Button)findViewById(R.id.play)); + } + + @Override + public void onAttachedToWindow() { + super.onAttachedToWindow(); + } + + @Override + protected void onPause() { + super.onPause(); + + // Pause game when its activity is paused. + mContent.setGamePaused(true); + } +} |
