Skip to content
Snippets Groups Projects
Commit a75ae310 authored by Andrej Rasevic's avatar Andrej Rasevic
Browse files

updating for fall 2018 semester

parents
No related branches found
No related tags found
No related merge requests found
Showing
with 1082 additions and 0 deletions
# built application files
*.apk
*.ap_
# files for the dex VM
*.dex
# Java class files
*.class
# Mac files
.DS_Store
# generated files
bin/
gen/
# Ignore gradle files
.gradle/
build/
# Local configuration file (sdk path, etc)
local.properties
# Proguard folder generated by Eclipse
proguard/
# Eclipse prefs files
.prefs
# Android Studio
*.iml
.idea
.gradle
build/
#NDK
obj/
File added
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
buildToolsVersion '27.0.3'
defaultConfig {
applicationId "course.labs.gestureslab"
minSdkVersion 21
targetSdkVersion 26
testApplicationId "course.labs.gestureslab.test"
testInstrumentationRunner "android.test.InstrumentationTestRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
}
dependencies {
androidTestImplementation 'com.jayway.android.robotium:robotium-solo:5.2.1'
}
File added
package course.labs.gestureslab.test;
import course.labs.gestureslab.BubbleActivity;
import com.robotium.solo.*;
import android.test.ActivityInstrumentationTestCase2;
import android.view.WindowManager;
public class BubbleActivityFling extends
ActivityInstrumentationTestCase2<BubbleActivity> {
private Solo solo;
public BubbleActivityFling() {
super(BubbleActivity.class);
}
public void setUp() throws Exception {
solo = new Solo(getInstrumentation(), getActivity());
getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
getActivity().getWindow().addFlags(
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
}
});
}
@Override
public void tearDown() throws Exception {
solo.finishOpenedActivities();
}
public void testRun() {
int delay = 2000;
// Wait for activity: 'course.labs.TouchLab.BubbleActivity'
solo.waitForActivity(course.labs.gestureslab.BubbleActivity.class,
delay);
solo.clickOnActionBarItem(course.labs.gestureslab.R.id.menu_still_mode);
solo.sleep(delay);
// Click to create a bubble
solo.clickOnScreen(100, 100);
solo.sleep(delay);
// Assert that a bubble was displayed
assertEquals(
"Bubble hasn't appeared",
1,
solo.getCurrentViews(
course.labs.gestureslab.BubbleActivity.BubbleView.class)
.size());
// Fling the bubble
solo.drag(100, 500, 100, 500, 3);
// Give bubble time to leave screen
solo.sleep(delay);
// Assert that the bubble has left the screen
assertEquals(
"Bubble hasn't left the screen",
0,
solo.getCurrentViews(
course.labs.gestureslab.BubbleActivity.BubbleView.class)
.size());
}
}
package course.labs.gestureslab.test;
import course.labs.gestureslab.BubbleActivity;
import com.robotium.solo.*;
import android.test.ActivityInstrumentationTestCase2;
import android.view.WindowManager;
public class BubbleActivityFloatOffScreen extends
ActivityInstrumentationTestCase2<BubbleActivity> {
private Solo solo;
public BubbleActivityFloatOffScreen() {
super(BubbleActivity.class);
}
public void setUp() throws Exception {
solo = new Solo(getInstrumentation(), getActivity());
getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
getActivity().getWindow().addFlags(
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
}
});
}
@Override
public void tearDown() throws Exception {
solo.finishOpenedActivities();
}
public void testRun() {
int shortDelay = 300, delay = 2000, delay2 = 3000;
// Wait for activity: 'course.labs.TouchLab.BubbleActivity'
solo.waitForActivity(course.labs.gestureslab.BubbleActivity.class,
delay);
// Click on action bar item
solo.clickOnActionBarItem(course.labs.gestureslab.R.id.menu_single_speed);
solo.sleep(delay);
// Click to create a bubble
solo.clickOnScreen(350.0f, 350.0f);
// Check whether bubble appears
boolean bubbleAppeared = solo.getCurrentViews(
course.labs.gestureslab.BubbleActivity.BubbleView.class).size() > 0;
for (int i = 0; i < 10 && !bubbleAppeared; i++) {
solo.sleep(shortDelay);
bubbleAppeared = solo.getCurrentViews(
course.labs.gestureslab.BubbleActivity.BubbleView.class)
.size() > 0;
}
// Assert that a bubble was displayed
assertTrue("Bubble hasn't appeared", bubbleAppeared);
solo.sleep(delay2);
// Assert that the bubble has left the screen
assertEquals(
"Bubble hasn't left the screen",
0,
solo.getCurrentViews(
course.labs.gestureslab.BubbleActivity.BubbleView.class)
.size());
}
}
package course.labs.gestureslab.test;
import android.test.ActivityInstrumentationTestCase2;
import android.view.WindowManager;
import com.robotium.solo.Solo;
import course.labs.gestureslab.BubbleActivity;
public class BubbleActivityMenu extends ActivityInstrumentationTestCase2<BubbleActivity> {
private Solo solo;
public BubbleActivityMenu() {
super(BubbleActivity.class);
}
public void setUp() throws Exception {
solo = new Solo(getInstrumentation(), getActivity());
getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
getActivity().getWindow().addFlags(
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
}
});
}
@Override
public void tearDown() throws Exception {
solo.finishOpenedActivities();
}
public void testRun() {
int delay = 2000;
// Wait for activity: 'course.labs.TouchLab.BubbleActivity'
solo.waitForActivity(course.labs.gestureslab.BubbleActivity.class, 2000);
solo.clickOnActionBarItem(course.labs.gestureslab.R.id.menu_still_mode);
solo.sleep(delay);
//Gesture starting top left to open menu
solo.drag(0,300,300,350, 10);
solo.sleep(delay);
//checking if menu opened by clicking on a menu item
//without opening the menu.
assertTrue("Menu did not appear", solo.waitForText("Random Speed Mode"));
}
}
package course.labs.gestureslab.test;
import course.labs.gestureslab.BubbleActivity;
import com.robotium.solo.*;
import android.test.ActivityInstrumentationTestCase2;
import android.view.WindowManager;
public class BubbleActivityMultiple extends
ActivityInstrumentationTestCase2<BubbleActivity> {
private Solo solo;
public BubbleActivityMultiple() {
super(BubbleActivity.class);
}
public void setUp() throws Exception {
solo = new Solo(getInstrumentation(), getActivity());
getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
getActivity().getWindow().addFlags(
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
}
});
}
@Override
public void tearDown() throws Exception {
solo.finishOpenedActivities();
}
public void testRun() {
int delay = 2000;
// Wait for activity: 'course.labs.TouchLab.BubbleActivity'
solo.waitForActivity(course.labs.gestureslab.BubbleActivity.class,
delay);
// Set Still Mode
solo.clickOnActionBarItem(course.labs.gestureslab.R.id.menu_still_mode);
solo.sleep(delay);
// Click to create a bubble
solo.clickOnScreen(100, 100);
solo.sleep(delay);
// Assert that a bubble was displayed
assertEquals(
"Bubble hasn't appeared",
1,
solo.getCurrentViews(
course.labs.gestureslab.BubbleActivity.BubbleView.class)
.size());
// Click to create second bubble
solo.clickOnScreen(300, 300);
solo.sleep(delay);
// Assert that a bubble was displayed
assertEquals(
"Second bubble hasn't appeared",
2,
solo.getCurrentViews(
course.labs.gestureslab.BubbleActivity.BubbleView.class)
.size());
solo.sleep(delay);
// Give misbehaving bubbles a chance to move off screen
// Assert that there are two bubbles on the screen
assertEquals(
"There should be two bubbles on the screen",
2,
solo.getCurrentViews(
course.labs.gestureslab.BubbleActivity.BubbleView.class)
.size());
}
}
package course.labs.gestureslab.test;
import course.labs.gestureslab.BubbleActivity;
import com.robotium.solo.*;
import android.test.ActivityInstrumentationTestCase2;
import android.view.WindowManager;
public class BubbleActivityPop extends
ActivityInstrumentationTestCase2<BubbleActivity> {
private Solo solo;
public BubbleActivityPop() {
super(BubbleActivity.class);
}
public void setUp() throws Exception {
solo = new Solo(getInstrumentation(), getActivity());
getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
getActivity().getWindow().addFlags(
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
}
});
}
@Override
public void tearDown() throws Exception {
solo.finishOpenedActivities();
}
public void testRun() {
int delay = 2000;
// Wait for activity: 'course.labs.TouchLab.BubbleActivity'
solo.waitForActivity(course.labs.gestureslab.BubbleActivity.class,
delay);
// Set Still Mode
solo.clickOnActionBarItem(course.labs.gestureslab.R.id.menu_still_mode);
solo.sleep(delay);
// Click to create a bubble
solo.clickOnScreen(250, 250);
solo.sleep(delay);
// Assert that a bubble was displayed
assertEquals(
"Bubble hasn't appeared",
1,
solo.getCurrentViews(
course.labs.gestureslab.BubbleActivity.BubbleView.class)
.size());
// Click to remove the same bubble
solo.clickOnScreen(250, 250);
solo.sleep(delay);
// Assert that there are no more bubbles
assertEquals(
"The bubble was not popped",
0,
solo.getCurrentViews(
course.labs.gestureslab.BubbleActivity.BubbleView.class)
.size());
}
}
package course.labs.gestureslab.test;
import android.test.ActivityInstrumentationTestCase2;
import android.view.WindowManager;
import com.robotium.solo.Solo;
import course.labs.gestureslab.BubbleActivity;
public class BubbleActivityTen extends
ActivityInstrumentationTestCase2<BubbleActivity> {
private Solo solo;
public BubbleActivityTen() {
super(BubbleActivity.class);
}
public void setUp() throws Exception {
solo = new Solo(getInstrumentation(), getActivity());
getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
getActivity().getWindow().addFlags(
WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
}
});
}
@Override
public void tearDown() throws Exception {
solo.finishOpenedActivities();
}
public void testRun() {
int delay = 2000;
// Wait for activity: 'course.labs.TouchLab.BubbleActivity'
solo.waitForActivity(course.labs.gestureslab.BubbleActivity.class, 2000);
// Set Still Mode
solo.clickOnActionBarItem(course.labs.gestureslab.R.id.menu_still_mode);
solo.sleep(delay);
//Gesture starting in top right to add ten bubbles
solo.drag(300,0,200,300,10);
solo.sleep(delay);
// Give misbehaving bubbles a chance to move off screen
// Assert that there are two bubbles on the screen
assertEquals(
"There should be ten bubbles on the screen",
10,
solo.getCurrentViews(
course.labs.gestureslab.BubbleActivity.BubbleView.class)
.size());
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="course.labs.gestureslab"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="18" />
<application
android:allowBackup="false"
android:icon="@drawable/icon"
android:label="@string/app_name" >
<activity
android:name=".BubbleActivity"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
\ No newline at end of file
package course.labs.gestureslab;
import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import android.app.Activity;
import android.content.Context;
import android.gesture.Gesture;
import android.gesture.GestureLibraries;
import android.gesture.GestureLibrary;
import android.gesture.GestureOverlayView;
import android.gesture.GestureOverlayView.OnGesturePerformedListener;
import android.gesture.Prediction;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.SoundPool;
import android.media.SoundPool.OnLoadCompleteListener;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.FrameLayout;
import android.widget.Toast;
public class BubbleActivity extends Activity implements
OnGesturePerformedListener {
private static final double MIN_PRED_SCORE = 3.0;
// These variables are for testing purposes, do not modify
private final static int RANDOM = 0;
private final static int SINGLE = 1;
private final static int STILL = 2;
public static int speedMode = RANDOM;
private static final String TAG = "Lab-Gestures";
// The Main view
private FrameLayout mFrame;
// Bubble image's bitmap
private Bitmap mBitmap;
// Display dimensions
private int mDisplayWidth, mDisplayHeight;
// Sound variables
// AudioManager
private AudioManager mAudioManager;
// SoundPool
private SoundPool mSoundPool;
// ID for the bubble popping sound
private int mSoundID;
// Audio volume
private float mStreamVolume;
// Gesture Detector
private GestureDetector mGestureDetector;
// Gesture Library
private GestureLibrary mLibrary;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Set up user interface
mFrame = (FrameLayout) findViewById(R.id.frame);
// Load basic bubble Bitmap
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.b64);
// TODO - Fetch GestureLibrary from raw
GestureOverlayView gestureOverlay = (GestureOverlayView) findViewById(R.id.gestures_overlay);
// TODO - Make this the target of gesture detection callbacks
// TODO - implement OnTouchListener to pass all events received by the
// gestureOverlay to the basic gesture detector
gestureOverlay.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return true || false;
}
});
// Uncomment next line to turn off gesture highlights
// gestureOverlay.setUncertainGestureColor(Color.TRANSPARENT);
// Loads the gesture library
if (!mLibrary.load()) {
finish();
}
}
@Override
protected void onResume() {
super.onResume();
// Manage bubble popping sound
// Use AudioManager.STREAM_MUSIC as stream type
AudioAttributes musicAttribute = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build();
mSoundPool = new SoundPool.Builder()
.setMaxStreams(10)
.setAudioAttributes(musicAttribute)
.build();
// TODO - load the sound from res/raw/bubble_pop.wav
// TODO - Set a SoundPool OnLoadCompletedListener that calls
// setupGestureDetector()
// TODO - Load the sound from res/raw/bubble_pop.wav
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
// Get the size of the display so this View knows where borders are
mDisplayWidth = mFrame.getWidth();
mDisplayHeight = mFrame.getHeight();
}
}
// Set up GestureDetector
private void setupGestureDetector() {
mGestureDetector = new GestureDetector(this,
new GestureDetector.SimpleOnGestureListener() {
// If a fling gesture starts on a BubbleView then change the
// BubbleView's velocity
@Override
public boolean onFling(MotionEvent event1,
MotionEvent event2, float velocityX, float velocityY) {
// TODO - Implement onFling actions.
// You can get all Views in mFrame one at a time
// using the ViewGroup.getChildAt() method
return true || false;
}
// If a single tap intersects a BubbleView, then pop the
// BubbleView
// Otherwise, create a new BubbleView at the tap's location
// and add
// it to mFrame. You can get all views from mFrame with
// ViewGroup.getChildAt()
@Override
public boolean onSingleTapConfirmed(MotionEvent event) {
// TODO - Implement onSingleTapConfirmed actions.
// You can get all Views in mFrame using the
// ViewGroup.getChildCount() method
return true || false;
}
// Good practice to override this method because all
// gestures start with a ACTION_DOWN event
@Override
public boolean onDown(MotionEvent event) {
return true;
}
});
}
@Override
protected void onPause() {
// Release all SoundPool resources
mSoundPool.unload(mSoundID);
mSoundPool.release();
mSoundPool = null;
super.onPause();
}
public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
// TODO - Get gesture predictions
ArrayList<Prediction> predictions = null;
if (predictions.size() > 0) {
// Get highest-ranked prediction
Prediction prediction = predictions.get(0);
// TODO - Ignore predictions with a score of < MIN_PRED_SCORE and display a
// toast message informing the user that no prediction was made. If
// the prediction
// matches the openMenu gesture, open the menu. If the prediction
// matches
// the addTen gesture, add 10 bubbles to the screen.
} else {
}
}
// BubbleView is a View that displays a bubble.
// This class handles animating, drawing, and popping amongst other
// actions.
// A new BubbleView is created for each bubble on the display
public class BubbleView extends View {
private static final int BITMAP_SIZE = 64;
private static final int REFRESH_RATE = 40;
private final Paint mPainter = new Paint();
private ScheduledFuture<?> mMoverFuture;
private int mScaledBitmapWidth;
private Bitmap mScaledBitmap;
// location, speed and direction of the bubble
private float mXPos, mYPos, mDx, mDy, mRadius, mRadiusSquared;
private long mRotate, mDRotate;
BubbleView(Context context, float x, float y) {
super(context);
Log.i(TAG, "Creating Bubble at: x:" + x + " y:" + y);
// Create a new random number generator to
// randomize size, rotation, speed and direction
Random r = new Random();
// Creates the bubble bitmap for this BubbleView
createScaledBitmap(r);
// Radius of the Bitmap
mRadius = mScaledBitmapWidth / 2;
mRadiusSquared = mRadius * mRadius;
// Adjust position to center the bubble under user's finger
mXPos = x - mRadius;
mYPos = y - mRadius;
// Set the BubbleView's speed and direction
setSpeedAndDirection(r);
// Set the BubbleView's rotation
setRotation(r);
mPainter.setAntiAlias(true);
}
private void setRotation(Random r) {
if (speedMode == RANDOM) {
// Set rotation in range [1..3]
mDRotate = ((r.nextInt(3 * BITMAP_SIZE) + 1) / mScaledBitmapWidth);
} else {
mDRotate = 0;
}
}
private void setSpeedAndDirection(Random r) {
// Used by test cases
switch (speedMode) {
case SINGLE:
mDx = 20;
mDy = 20;
break;
case STILL:
// No speed
mDx = 0;
mDy = 0;
break;
default:
// Set movement direction and speed
// Limit movement speed in the x and y
// direction to [-3..3] pixels per movement.
mDx = (r.nextInt(mScaledBitmapWidth * 3) + 1)
/ (float) mScaledBitmapWidth;
mDx *= r.nextInt() % 2 == 0 ? 1 : -1;
mDy = (r.nextInt(mScaledBitmapWidth * 3) + 1)
/ (float) mScaledBitmapWidth;
mDy *= r.nextInt() % 2 == 0 ? 1 : -1;
}
}
private void createScaledBitmap(Random r) {
if (speedMode != RANDOM) {
mScaledBitmapWidth = BITMAP_SIZE * 3;
} else {
// Set scaled bitmap size in range [1..3] * BITMAP_SIZE
mScaledBitmapWidth = r.nextInt(2 * BITMAP_SIZE) + BITMAP_SIZE;
}
// Create the scaled bitmap using size set above
mScaledBitmap = Bitmap.createScaledBitmap(mBitmap,
mScaledBitmapWidth, mScaledBitmapWidth, false);
}
// Start moving the BubbleView & updating the display
private void start() {
// Creates a WorkerThread
ScheduledExecutorService executor = Executors
.newScheduledThreadPool(1);
// Execute the run() in Worker Thread every REFRESH_RATE
// milliseconds
// Save reference to this job in mMoverFuture
mMoverFuture = executor.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
// Implement movement logic.
// Each time this method is run the BubbleView should
// move one step. If the BubbleView exits the display,
// stop the BubbleView's Worker Thread.
// Otherwise, request that the BubbleView be redrawn.
if (moveWhileOnScreen()) {
postInvalidate();
} else
stop(false);
}
}, 0, REFRESH_RATE, TimeUnit.MILLISECONDS);
}
// Returns true if the BubbleView intersects position (x,y)
private synchronized boolean intersects(float x, float y) {
// Return true if the BubbleView intersects position (x,y)
float xDist = x - (mXPos + mRadius);
float yDist = y - (mYPos + mRadius);
return xDist * xDist + yDist * yDist <= mRadiusSquared;
}
// Cancel the Bubble's movement
// Remove Bubble from mFrame
// Play pop sound if the BubbleView was popped
private void stop(final boolean wasPopped) {
if (null != mMoverFuture) {
if (!mMoverFuture.isDone()) {
mMoverFuture.cancel(true);
}
// This work will be performed on the UI Thread
mFrame.post(new Runnable() {
@Override
public void run() {
// Remove the BubbleView from mFrame
mFrame.removeView(BubbleView.this);
// If the bubble was popped by user,
// play the popping sound
if (wasPopped) {
mSoundPool.play(mSoundID, mStreamVolume,
mStreamVolume, 1, 0, 1.0f);
}
}
});
}
}
// Change the Bubble's speed and direction
private synchronized void deflect(float velocityX, float velocityY) {
mDx = velocityX / REFRESH_RATE;
mDy = velocityY / REFRESH_RATE;
}
// Draw the Bubble at its current location
@Override
protected synchronized void onDraw(Canvas canvas) {
// save the canvas
canvas.save();
// Increase the rotation of the original image by mDRotate
mRotate += mDRotate;
// Rotate the canvas by current rotation
// Hint - Rotate around the bubble's center, not its position
canvas.rotate(mRotate, mXPos + mScaledBitmapWidth / 2, mYPos
+ mScaledBitmapWidth / 2);
// Draw the bitmap at it's new location
canvas.drawBitmap(mScaledBitmap, mXPos, mYPos, mPainter);
// Restore the canvas
canvas.restore();
}
// Returns true if the BubbleView is still on the screen after the move
// operation
private synchronized boolean moveWhileOnScreen() {
// Move the BubbleView
mXPos = mXPos += mDx;
mYPos = mYPos += mDy;
return !isOutOfView();
}
// Return true if the BubbleView is not on the screen after the move
// operation
private boolean isOutOfView() {
return (mXPos < 0 - mScaledBitmapWidth || mXPos > mDisplayWidth
|| mYPos < 0 - mScaledBitmapWidth || mYPos > mDisplayHeight);
}
}
@Override
public void onBackPressed() {
openOptionsMenu();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_still_mode:
speedMode = STILL;
return true;
case R.id.menu_single_speed:
speedMode = SINGLE;
return true;
case R.id.menu_random_mode:
speedMode = RANDOM;
return true;
case R.id.quit:
exitRequested();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void exitRequested() {
super.onBackPressed();
}
}
app/src/main/res/drawable-hdpi/b128.png

24.9 KiB

app/src/main/res/drawable-hdpi/b64.png

7.99 KiB

app/src/main/res/drawable-hdpi/icon.png

4.05 KiB

app/src/main/res/drawable-ldpi/icon.png

1.68 KiB

app/src/main/res/drawable-mdpi/icon.png

2.51 KiB

<?xml version="1.0" encoding="utf-8"?>
<android.gesture.GestureOverlayView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gestures_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gestureStrokeLengthThreshold="200.0" >
<FrameLayout
android:id="@+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true" >
</FrameLayout>
</android.gesture.GestureOverlayView>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/menu_still_mode" android:title="@string/still_mode_string"></item>
<item android:id="@+id/menu_single_speed" android:title="@string/single_speed_mode_string"></item>
<item android:id="@+id/menu_random_mode" android:title="@string/random_speed_mode_string"></item>
<item android:id="@+id/quit" android:title="@string/quit_string"></item>
</menu>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment