Sync sample prebuilts for mnc-preview-docs (DO NOT MERGE)

Synced to //developers/samples/android commit 535025bac7.

Change-Id: If65e90f25cebb8d774d9c581dbcbb2ba2a8bce51
This commit is contained in:
Trevor Johns
2015-06-19 20:58:13 -07:00
parent a40b0ba48a
commit 4fe2d03358
43 changed files with 459 additions and 289 deletions

View File

@@ -33,7 +33,6 @@ import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.data.FreezableUtils;
import com.google.android.gms.wearable.DataApi;
import com.google.android.gms.wearable.DataItem;
import com.google.android.gms.wearable.DataItemBuffer;
@@ -96,28 +95,29 @@ public class MainActivity extends Activity implements NodeApi.NodeListener, Conn
.setResultCallback(new ResultCallback<DataItemBuffer>() {
@Override
public void onResult(DataItemBuffer result) {
if (result.getStatus().isSuccess()) {
deleteDataItems(result);
} else {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "onDeleteEventsClicked(): failed to get Data Items");
try {
if (result.getStatus().isSuccess()) {
deleteDataItems(result);
} else {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG,"onDeleteEventsClicked(): failed to get Data "
+ "Items");
}
}
} finally {
result.release();
}
result.close();
}
});
} else {
Log.e(TAG, "Failed to delete data items"
+ " - Client disconnected from Google Play Services");
+ " - Client disconnected from Google Play Services");
}
}
private void deleteDataItems(DataItemBuffer dataItems) {
private void deleteDataItems(final DataItemBuffer dataItemList) {
if (mGoogleApiClient.isConnected()) {
// Store the DataItem URIs in a List and close the buffer. Then use these URIs
// to delete the DataItems.
final List<DataItem> dataItemList = FreezableUtils.freezeIterable(dataItems);
dataItems.close();
for (final DataItem dataItem : dataItemList) {
final Uri dataItemUri = dataItem.getUri();
// In a real calendar application, this might delete the corresponding calendar

View File

@@ -75,7 +75,6 @@ public class HomeListenerService extends WearableListenerService {
UpdateNotificationForDataItem(event.getDataItem());
}
}
dataEvents.close();
}
@Override

View File

@@ -15,16 +15,14 @@
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.camera2basic"
android:versionCode="1"
android:versionName="1.0">
package="com.example.android.camera2basic">
<!-- Min/target SDK versions (<uses-sdk>) managed by build.gradle -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<application android:allowBackup="true"
android:label="@string/app_name"
android:icon="@drawable/ic_launcher"

View File

@@ -26,14 +26,14 @@
android:layout_alignParentTop="true" />
<FrameLayout
android:id="@+id/control"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_below="@id/texture"
android:layout_toRightOf="@id/texture"
android:background="#4285f4"
android:background="@color/control_background"
android:orientation="horizontal">
<Button

View File

@@ -25,12 +25,12 @@
android:layout_alignParentTop="true" />
<FrameLayout
android:id="@+id/control"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="112dp"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
android:layout_below="@id/texture"
android:background="#4285f4">
android:background="@color/control_background">
<Button
android:id="@+id/picture"

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2015 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.
-->
<resources>
<color name="control_background">#cc4285f4</color>
</resources>

View File

@@ -55,7 +55,6 @@ import android.view.ViewGroup;
import android.widget.Toast;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
@@ -264,14 +263,16 @@ public class Camera2BasicFragment extends Fragment implements View.OnClickListen
break;
}
case STATE_WAITING_LOCK: {
int afState = result.get(CaptureResult.CONTROL_AF_STATE);
if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState ||
Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
if (afState == null) {
captureStillPicture();
} else if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState ||
CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState) {
// CONTROL_AE_STATE can be null on some devices
Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
if (aeState == null ||
aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) {
mState = STATE_WAITING_NON_PRECAPTURE;
mState = STATE_PICTURE_TAKEN;
captureStillPicture();
} else {
runPrecaptureSequence();
@@ -636,6 +637,8 @@ public class Camera2BasicFragment extends Fragment implements View.OnClickListen
(float) viewWidth / mPreviewSize.getWidth());
matrix.postScale(scale, scale, centerX, centerY);
matrix.postRotate(90 * (rotation - 2), centerX, centerY);
} else if (Surface.ROTATION_180 == rotation) {
matrix.postRotate(180, centerX, centerY);
}
mTextureView.setTransform(matrix);
}
@@ -657,7 +660,7 @@ public class Camera2BasicFragment extends Fragment implements View.OnClickListen
CameraMetadata.CONTROL_AF_TRIGGER_START);
// Tell #mCaptureCallback to wait for the lock.
mState = STATE_WAITING_LOCK;
mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), mCaptureCallback,
mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
@@ -794,8 +797,6 @@ public class Camera2BasicFragment extends Fragment implements View.OnClickListen
try {
output = new FileOutputStream(mFile);
output.write(bytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {

View File

@@ -216,8 +216,8 @@ public class MainActivity extends Activity implements DataApi.DataListener,
@Override //DataListener
public void onDataChanged(DataEventBuffer dataEvents) {
LOGD(TAG, "onDataChanged: " + dataEvents);
// Need to freeze the dataEvents so they will exist later on the UI thread
final List<DataEvent> events = FreezableUtils.freezeIterable(dataEvents);
dataEvents.close();
runOnUiThread(new Runnable() {
@Override
public void run() {

View File

@@ -22,7 +22,6 @@ import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.data.FreezableUtils;
import com.google.android.gms.wearable.DataEvent;
import com.google.android.gms.wearable.DataEventBuffer;
import com.google.android.gms.wearable.MessageEvent;
@@ -59,8 +58,6 @@ public class DataLayerListenerService extends WearableListenerService {
@Override
public void onDataChanged(DataEventBuffer dataEvents) {
LOGD(TAG, "onDataChanged: " + dataEvents);
final List<DataEvent> events = FreezableUtils.freezeIterable(dataEvents);
dataEvents.close();
if (!mGoogleApiClient.isConnected() || !mGoogleApiClient.isConnecting()) {
ConnectionResult connectionResult = mGoogleApiClient
.blockingConnect(30, TimeUnit.SECONDS);
@@ -72,7 +69,7 @@ public class DataLayerListenerService extends WearableListenerService {
}
// Loop through the events and send a message back to the node that created the data item.
for (DataEvent event : events) {
for (DataEvent event : dataEvents) {
Uri uri = event.getDataItem().getUri();
String path = uri.getPath();
if (COUNT_PATH.equals(path)) {

View File

@@ -42,7 +42,6 @@ import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.data.FreezableUtils;
import com.google.android.gms.wearable.Asset;
import com.google.android.gms.wearable.CapabilityApi;
import com.google.android.gms.wearable.CapabilityInfo;
@@ -151,9 +150,7 @@ public class MainActivity extends Activity implements ConnectionCallbacks,
public void onDataChanged(DataEventBuffer dataEvents) {
LOGD(TAG, "onDataChanged(): " + dataEvents);
final List<DataEvent> events = FreezableUtils.freezeIterable(dataEvents);
dataEvents.close();
for (DataEvent event : events) {
for (DataEvent event : dataEvents) {
if (event.getType() == DataEvent.TYPE_CHANGED) {
String path = event.getDataItem().getUri().getPath();
if (DataLayerListenerService.IMAGE_PATH.equals(path)) {

View File

@@ -55,11 +55,12 @@ public class MainActivity extends Activity {
}
};
mHistoryView = (TextView) findViewById(R.id.history);
startResponderService();
startResponderService(ResponderService.ACTION_INCOMING);
}
private void startResponderService() {
Intent serviceIntent = new Intent(ResponderService.ACTION_INCOMING);
private void startResponderService(String action) {
Intent serviceIntent = new Intent(this, ResponderService.class);
serviceIntent.setAction(action);
startService(serviceIntent);
}
@@ -69,9 +70,7 @@ public class MainActivity extends Activity {
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver,
new IntentFilter(ACTION_NOTIFY));
mHistoryView.setText("");
Intent serviceIntent = new Intent(ACTION_GET_CONVERSATION);
startService(serviceIntent);
startResponderService(ACTION_GET_CONVERSATION);
}
@Override

View File

@@ -95,7 +95,6 @@ public class SoundAlarmListenerService extends WearableListenerService {
}
}
}
dataEvents.close();
}
}

View File

@@ -73,19 +73,22 @@ public class FindPhoneService extends IntentService implements GoogleApiClient.C
if (intent.getAction().equals(ACTION_TOGGLE_ALARM)) {
// Get current state of the alarm.
DataItemBuffer result = Wearable.DataApi.getDataItems(mGoogleApiClient).await();
if (result.getStatus().isSuccess()) {
if (result.getCount() == 1) {
alarmOn = DataMap.fromByteArray(result.get(0).getData())
.getBoolean(FIELD_ALARM_ON, false);
} else {
Log.e(TAG, "Unexpected number of DataItems found.\n"
+ "\tExpected: 1\n"
+ "\tActual: " + result.getCount());
try {
if (result.getStatus().isSuccess()) {
if (result.getCount() == 1) {
alarmOn = DataMap.fromByteArray(result.get(0).getData())
.getBoolean(FIELD_ALARM_ON, false);
} else {
Log.e(TAG, "Unexpected number of DataItems found.\n"
+ "\tExpected: 1\n"
+ "\tActual: " + result.getCount());
}
} else if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "onHandleIntent: failed to get current alarm state");
}
} else if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "onHandleIntent: failed to get current alarm state");
} finally {
result.release();
}
result.close();
// Toggle alarm.
alarmOn = !alarmOn;
// Change notification text based on new value of alarmOn.

View File

@@ -79,7 +79,6 @@ public class HomeListenerService extends WearableListenerService {
postNotificationForGeofenceId(geofenceId, event.getDataItem().getUri());
}
}
dataEvents.close();
}
/**

View File

@@ -37,13 +37,17 @@
<service android:name=".MessagingService">
</service>
<receiver android:name=".MessageReadReceiver">
<receiver
android:name=".MessageReadReceiver"
android:exported="false">
<intent-filter>
<action android:name="com.example.android.messagingservice.ACTION_MESSAGE_READ"/>
</intent-filter>
</receiver>
<receiver android:name=".MessageReplyReceiver">
<receiver
android:name=".MessageReplyReceiver"
android:exported="false">
<intent-filter>
<action android:name="com.example.android.messagingservice.ACTION_MESSAGE_REPLY"/>
</intent-filter>

View File

@@ -21,7 +21,8 @@
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
android:paddingTop="@dimen/activity_vertical_margin"
android:baselineAligned="false">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"

View File

@@ -14,7 +14,6 @@
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"

View File

@@ -16,8 +16,6 @@
-->
<resources>
<string name="app_name">Messaging Sample</string>
<string name="action_settings">Settings</string>
<string name="title">Messaging Sample</string>
<string name="notification_reply">Reply by Voice</string>
<string name="send_2_conversations">Send 2 conversations with 1 message</string>
<string name="send_1_conversation">Send 1 conversation with 1 message</string>

View File

@@ -17,7 +17,6 @@
package com.example.android.messagingservice;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

View File

@@ -19,6 +19,7 @@ package com.example.android.messagingservice;
import android.content.Context;
import android.content.SharedPreferences;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
@@ -27,13 +28,13 @@ import java.util.Date;
* and replies. Don't use this in a real world application. This logger is only
* used for displaying the messages in the text view.
*/
public class MessageLogger {
class MessageLogger {
private static final String PREF_MESSAGE = "MESSAGE_LOGGER";
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private static final DateFormat DATE_FORMAT = SimpleDateFormat.getDateTimeInstance();
private static final String LINE_BREAKS = "\n\n";
public static final String LOG_KEY = "message_data";
public static final String LINE_BREAKS = "\n\n";
public static void logMessage(Context context, String message) {
SharedPreferences prefs = getPrefs(context);

View File

@@ -16,7 +16,6 @@
package com.example.android.messagingservice;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -35,8 +34,8 @@ public class MessageReadReceiver extends BroadcastReceiver {
if (conversationId != -1) {
Log.d(TAG, "Conversation " + conversationId + " was read");
MessageLogger.logMessage(context, "Conversation " + conversationId + " was read.");
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
notificationManager.cancel(conversationId);
NotificationManagerCompat.from(context)
.cancel(conversationId);
}
}
}

View File

@@ -51,7 +51,7 @@ public class MessagingFragment extends Fragment implements View.OnClickListener
private Messenger mService;
private boolean mBound;
private ServiceConnection mConnection = new ServiceConnection() {
private final ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder service) {
mService = new Messenger(service);
@@ -67,7 +67,7 @@ public class MessagingFragment extends Fragment implements View.OnClickListener
}
};
private SharedPreferences.OnSharedPreferenceChangeListener listener =
private final SharedPreferences.OnSharedPreferenceChangeListener listener =
new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {

View File

@@ -31,41 +31,24 @@ import android.support.v4.app.NotificationManagerCompat;
import android.support.v4.app.RemoteInput;
import android.util.Log;
import java.lang.ref.WeakReference;
import java.util.Iterator;
public class MessagingService extends Service {
private static final String TAG = MessagingService.class.getSimpleName();
public static final String READ_ACTION =
private static final String EOL = "\n";
private static final String READ_ACTION =
"com.example.android.messagingservice.ACTION_MESSAGE_READ";
public static final String REPLY_ACTION =
"com.example.android.messagingservice.ACTION_MESSAGE_REPLY";
public static final String CONVERSATION_ID = "conversation_id";
public static final String EXTRA_VOICE_REPLY = "extra_voice_reply";
public static final int MSG_SEND_NOTIFICATION = 1;
public static final String EOL = "\n";
private NotificationManagerCompat mNotificationManager;
private final Messenger mMessenger = new Messenger(new IncomingHandler());
/**
* Handler of incoming messages from clients.
*/
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SEND_NOTIFICATION:
int howManyConversations = msg.arg1 <= 0 ? 1 : msg.arg1;
int messagesPerConv = msg.arg2 <= 0 ? 1 : msg.arg2;
sendNotification(howManyConversations, messagesPerConv);
break;
default:
super.handleMessage(msg);
}
}
}
private final Messenger mMessenger = new Messenger(new IncomingHandler(this));
@Override
public void onCreate() {
@@ -79,18 +62,6 @@ public class MessagingService extends Service {
return mMessenger.getBinder();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand");
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
}
// Creates an intent that will be triggered when a message is marked as read.
private Intent getMessageReadIntent(int id) {
return new Intent()
@@ -171,4 +142,31 @@ public class MessagingService extends Service {
mNotificationManager.notify(conversation.getConversationId(), builder.build());
}
/**
* Handler for incoming messages from clients.
*/
private static class IncomingHandler extends Handler {
private final WeakReference<MessagingService> mReference;
IncomingHandler(MessagingService service) {
mReference = new WeakReference<>(service);
}
@Override
public void handleMessage(Message msg) {
MessagingService service = mReference.get();
switch (msg.what) {
case MSG_SEND_NOTIFICATION:
int howManyConversations = msg.arg1 <= 0 ? 1 : msg.arg1;
int messagesPerConversation = msg.arg2 <= 0 ? 1 : msg.arg2;
if (service != null) {
service.sendNotification(howManyConversations, messagesPerConversation);
}
break;
default:
super.handleMessage(msg);
}
}
}
}

View File

@@ -325,8 +325,8 @@ public class MainActivity extends Activity implements DataApi.DataListener,
@Override
public void onDataChanged(DataEventBuffer dataEvents) {
// Need to freeze the dataEvents so they will exist later on the UI thread
final List<DataEvent> events = FreezableUtils.freezeIterable(dataEvents);
dataEvents.close();
runOnUiThread(new Runnable() {
@Override
public void run() {
@@ -445,16 +445,17 @@ public class MainActivity extends Activity implements DataApi.DataListener,
.setResultCallback(new ResultCallback<DataItemBuffer>() {
@Override
public void onResult(DataItemBuffer result) {
if (result.getStatus().isSuccess()) {
List<DataItem> dataItemList = FreezableUtils.freezeIterable(result);
result.close();
resetDataItems(dataItemList);
} else {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Reset quiz: failed to get Data Items to reset");
try {
if (result.getStatus().isSuccess()) {
resetDataItems(result);
} else {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Reset quiz: failed to get Data Items to reset");
}
}
} finally {
result.release();
}
result.close();
}
});
} else {
@@ -467,7 +468,7 @@ public class MainActivity extends Activity implements DataApi.DataListener,
mNumSkipped = 0;
}
private void resetDataItems(List<DataItem> dataItemList) {
private void resetDataItems(DataItemBuffer dataItemList) {
if (mGoogleApiClient.isConnected()) {
for (final DataItem dataItem : dataItemList) {
final Uri dataItemUri = dataItem.getUri();
@@ -521,19 +522,23 @@ public class MainActivity extends Activity implements DataApi.DataListener,
.setResultCallback(new ResultCallback<DataItemBuffer>() {
@Override
public void onResult(DataItemBuffer result) {
if (result.getStatus().isSuccess()) {
List<Uri> dataItemUriList = new ArrayList<Uri>();
for (final DataItem dataItem : result) {
dataItemUriList.add(dataItem.getUri());
}
result.close();
deleteDataItems(dataItemUriList);
} else {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Clear quiz: failed to get Data Items for deletion");
try {
if (result.getStatus().isSuccess()) {
List<Uri> dataItemUriList = new ArrayList<Uri>();
for (final DataItem dataItem : result) {
dataItemUriList.add(dataItem.getUri());
}
deleteDataItems(dataItemUriList);
} else {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Clear quiz: failed to get Data Items for "
+ "deletion");
}
}
} finally {
result.release();
}
result.close();
}
});
} else {

View File

@@ -40,7 +40,6 @@ import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.data.FreezableUtils;
import com.google.android.gms.wearable.DataEvent;
import com.google.android.gms.wearable.DataEventBuffer;
import com.google.android.gms.wearable.DataItem;
@@ -80,9 +79,6 @@ public class QuizListenerService extends WearableListenerService {
@Override
public void onDataChanged(DataEventBuffer dataEvents) {
final List<DataEvent> events = FreezableUtils.freezeIterable(dataEvents);
dataEvents.close();
GoogleApiClient googleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.build();
@@ -94,7 +90,7 @@ public class QuizListenerService extends WearableListenerService {
return;
}
for (DataEvent event : events) {
for (DataEvent event : dataEvents) {
if (event.getType() == DataEvent.TYPE_CHANGED) {
DataItem dataItem = event.getDataItem();
DataMap dataMap = DataMapItem.fromDataItem(dataItem).getDataMap();

View File

@@ -14,6 +14,7 @@
limitations under the License.
-->
<resources>
<color name="digital_date">#aaaaaa</color>
<color name="digital_am_pm">#aaaaa0</color>
<color name="digital_colons">#aaaaa0</color>
<color name="config_activity_background">#ffffff</color>

View File

@@ -16,11 +16,13 @@
<resources>
<dimen name="digital_text_size">40dp</dimen>
<dimen name="digital_text_size_round">45dp</dimen>
<dimen name="digital_date_text_size">20dp</dimen>
<dimen name="digital_am_pm_size">25dp</dimen>
<dimen name="digital_am_pm_size_round">30dp</dimen>
<dimen name="digital_x_offset">15dp</dimen>
<dimen name="digital_x_offset_round">25dp</dimen>
<dimen name="digital_y_offset">90dp</dimen>
<dimen name="digital_y_offset">80dp</dimen>
<dimen name="digital_line_height">25dp</dimen>
<dimen name="digital_config_color_picker_item_margin">32dp</dimen>
<dimen name="content_padding_start">12dp</dimen>
</resources>

View File

@@ -212,6 +212,17 @@ public class AnalogWatchFaceService extends CanvasWatchFaceService {
}
}
@Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (mBackgroundScaledBitmap == null
|| mBackgroundScaledBitmap.getWidth() != width
|| mBackgroundScaledBitmap.getHeight() != height) {
mBackgroundScaledBitmap = Bitmap.createScaledBitmap(mBackgroundBitmap,
width, height, true /* filter */);
}
super.onSurfaceChanged(holder, format, width, height);
}
@Override
public void onDraw(Canvas canvas, Rect bounds) {
mCalendar.setTimeInMillis(System.currentTimeMillis());
@@ -220,12 +231,6 @@ public class AnalogWatchFaceService extends CanvasWatchFaceService {
int height = bounds.height();
// Draw the background, scaled to fit.
if (mBackgroundScaledBitmap == null
|| mBackgroundScaledBitmap.getWidth() != width
|| mBackgroundScaledBitmap.getHeight() != height) {
mBackgroundScaledBitmap = Bitmap.createScaledBitmap(mBackgroundBitmap,
width, height, true /* filter */);
}
canvas.drawBitmap(mBackgroundScaledBitmap, 0, 0, null);
// Find the center. Ignore the window insets so that, on round watches with a

View File

@@ -46,7 +46,10 @@ import com.google.android.gms.wearable.DataMap;
import com.google.android.gms.wearable.DataMapItem;
import com.google.android.gms.wearable.Wearable;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
@@ -123,16 +126,26 @@ public class DigitalWatchFaceService extends CanvasWatchFaceService {
.addApi(Wearable.API)
.build();
final BroadcastReceiver mTimeZoneReceiver = new BroadcastReceiver() {
/**
* Handles time zone and locale changes.
*/
final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
mCalendar.setTimeZone(TimeZone.getDefault());
initFormats();
invalidate();
}
};
boolean mRegisteredTimeZoneReceiver = false;
/**
* Unregistering an unregistered receiver throws an exception. Keep track of the
* registration state to prevent that.
*/
boolean mRegisteredReceiver = false;
Paint mBackgroundPaint;
Paint mDatePaint;
Paint mHourPaint;
Paint mMinutePaint;
Paint mSecondPaint;
@@ -140,10 +153,16 @@ public class DigitalWatchFaceService extends CanvasWatchFaceService {
Paint mColonPaint;
float mColonWidth;
boolean mMute;
Calendar mCalendar;
Date mDate;
SimpleDateFormat mDayOfWeekFormat;
java.text.DateFormat mDateFormat;
boolean mShouldDrawColons;
float mXOffset;
float mYOffset;
float mLineHeight;
String mAmString;
String mPmString;
int mInteractiveBackgroundColor =
@@ -175,11 +194,13 @@ public class DigitalWatchFaceService extends CanvasWatchFaceService {
.build());
Resources resources = DigitalWatchFaceService.this.getResources();
mYOffset = resources.getDimension(R.dimen.digital_y_offset);
mLineHeight = resources.getDimension(R.dimen.digital_line_height);
mAmString = resources.getString(R.string.digital_am);
mPmString = resources.getString(R.string.digital_pm);
mBackgroundPaint = new Paint();
mBackgroundPaint.setColor(mInteractiveBackgroundColor);
mDatePaint = createTextPaint(resources.getColor(R.color.digital_date));
mHourPaint = createTextPaint(mInteractiveHourDigitsColor, BOLD_TYPEFACE);
mMinutePaint = createTextPaint(mInteractiveMinuteDigitsColor);
mSecondPaint = createTextPaint(mInteractiveSecondDigitsColor);
@@ -187,6 +208,8 @@ public class DigitalWatchFaceService extends CanvasWatchFaceService {
mColonPaint = createTextPaint(resources.getColor(R.color.digital_colons));
mCalendar = Calendar.getInstance();
mDate = new Date();
initFormats();
}
@Override
@@ -219,8 +242,9 @@ public class DigitalWatchFaceService extends CanvasWatchFaceService {
registerReceiver();
// Update time zone in case it changed while we weren't visible.
// Update time zone and date formats, in case they changed while we weren't visible.
mCalendar.setTimeZone(TimeZone.getDefault());
initFormats();
} else {
unregisterReceiver();
@@ -235,21 +259,29 @@ public class DigitalWatchFaceService extends CanvasWatchFaceService {
updateTimer();
}
private void initFormats() {
mDayOfWeekFormat = new SimpleDateFormat("EEEE", Locale.getDefault());
mDayOfWeekFormat.setCalendar(mCalendar);
mDateFormat = DateFormat.getDateFormat(DigitalWatchFaceService.this);
mDateFormat.setCalendar(mCalendar);
}
private void registerReceiver() {
if (mRegisteredTimeZoneReceiver) {
if (mRegisteredReceiver) {
return;
}
mRegisteredTimeZoneReceiver = true;
mRegisteredReceiver = true;
IntentFilter filter = new IntentFilter(Intent.ACTION_TIMEZONE_CHANGED);
DigitalWatchFaceService.this.registerReceiver(mTimeZoneReceiver, filter);
filter.addAction(Intent.ACTION_LOCALE_CHANGED);
DigitalWatchFaceService.this.registerReceiver(mReceiver, filter);
}
private void unregisterReceiver() {
if (!mRegisteredTimeZoneReceiver) {
if (!mRegisteredReceiver) {
return;
}
mRegisteredTimeZoneReceiver = false;
DigitalWatchFaceService.this.unregisterReceiver(mTimeZoneReceiver);
mRegisteredReceiver = false;
DigitalWatchFaceService.this.unregisterReceiver(mReceiver);
}
@Override
@@ -269,6 +301,7 @@ public class DigitalWatchFaceService extends CanvasWatchFaceService {
float amPmSize = resources.getDimension(isRound
? R.dimen.digital_am_pm_size_round : R.dimen.digital_am_pm_size);
mDatePaint.setTextSize(resources.getDimension(R.dimen.digital_date_text_size));
mHourPaint.setTextSize(textSize);
mMinutePaint.setTextSize(textSize);
mSecondPaint.setTextSize(textSize);
@@ -321,6 +354,7 @@ public class DigitalWatchFaceService extends CanvasWatchFaceService {
if (mLowBitAmbient) {
boolean antiAlias = !inAmbientMode;
mDatePaint.setAntiAlias(antiAlias);
mHourPaint.setAntiAlias(antiAlias);
mMinutePaint.setAntiAlias(antiAlias);
mSecondPaint.setAntiAlias(antiAlias);
@@ -335,7 +369,7 @@ public class DigitalWatchFaceService extends CanvasWatchFaceService {
}
private void adjustPaintColorToCurrentMode(Paint paint, int interactiveColor,
int ambientColor) {
int ambientColor) {
paint.setColor(isInAmbientMode() ? ambientColor : interactiveColor);
}
@@ -353,6 +387,7 @@ public class DigitalWatchFaceService extends CanvasWatchFaceService {
if (mMute != inMuteMode) {
mMute = inMuteMode;
int alpha = inMuteMode ? MUTE_ALPHA : NORMAL_ALPHA;
mDatePaint.setAlpha(alpha);
mHourPaint.setAlpha(alpha);
mMinutePaint.setAlpha(alpha);
mColonPaint.setAlpha(alpha);
@@ -409,7 +444,9 @@ public class DigitalWatchFaceService extends CanvasWatchFaceService {
@Override
public void onDraw(Canvas canvas, Rect bounds) {
mCalendar.setTimeInMillis(System.currentTimeMillis());
long now = System.currentTimeMillis();
mCalendar.setTimeInMillis(now);
mDate.setTime(now);
boolean is24Hour = DateFormat.is24HourFormat(DigitalWatchFaceService.this);
// Show colons for the first half of each second so the colons blink on when the time
@@ -430,9 +467,6 @@ public class DigitalWatchFaceService extends CanvasWatchFaceService {
hour = 12;
}
hourString = String.valueOf(hour);
if (hour < 10) {
x += mHourPaint.measureText("0");
}
}
canvas.drawText(hourString, x, mYOffset, mHourPaint);
x += mHourPaint.measureText(hourString);
@@ -463,6 +497,19 @@ public class DigitalWatchFaceService extends CanvasWatchFaceService {
canvas.drawText(getAmPmString(
mCalendar.get(Calendar.AM_PM)), x, mYOffset, mAmPmPaint);
}
// Only render the day of week and date if there is no peek card, so they do not bleed
// into each other in ambient mode.
if (getPeekCardPosition().isEmpty()) {
// Day of week
canvas.drawText(
mDayOfWeekFormat.format(mDate),
mXOffset, mYOffset + mLineHeight, mDatePaint);
// Date
canvas.drawText(
mDateFormat.format(mDate),
mXOffset, mYOffset + mLineHeight * 2, mDatePaint);
}
}
/**
@@ -522,27 +569,23 @@ public class DigitalWatchFaceService extends CanvasWatchFaceService {
@Override // DataApi.DataListener
public void onDataChanged(DataEventBuffer dataEvents) {
try {
for (DataEvent dataEvent : dataEvents) {
if (dataEvent.getType() != DataEvent.TYPE_CHANGED) {
continue;
}
DataItem dataItem = dataEvent.getDataItem();
if (!dataItem.getUri().getPath().equals(
DigitalWatchFaceUtil.PATH_WITH_FEATURE)) {
continue;
}
DataMapItem dataMapItem = DataMapItem.fromDataItem(dataItem);
DataMap config = dataMapItem.getDataMap();
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Config DataItem updated:" + config);
}
updateUiForConfigDataMap(config);
for (DataEvent dataEvent : dataEvents) {
if (dataEvent.getType() != DataEvent.TYPE_CHANGED) {
continue;
}
} finally {
dataEvents.close();
DataItem dataItem = dataEvent.getDataItem();
if (!dataItem.getUri().getPath().equals(
DigitalWatchFaceUtil.PATH_WITH_FEATURE)) {
continue;
}
DataMapItem dataMapItem = DataMapItem.fromDataItem(dataItem);
DataMap config = dataMapItem.getDataMap();
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Config DataItem updated:" + config);
}
updateUiForConfigDataMap(config);
}
}

View File

@@ -170,6 +170,17 @@ public class SweepWatchFaceService extends CanvasWatchFaceService {
}
}
@Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (mBackgroundScaledBitmap == null
|| mBackgroundScaledBitmap.getWidth() != width
|| mBackgroundScaledBitmap.getHeight() != height) {
mBackgroundScaledBitmap = Bitmap.createScaledBitmap(mBackgroundBitmap,
width, height, true /* filter */);
}
super.onSurfaceChanged(holder, format, width, height);
}
@Override
public void onDraw(Canvas canvas, Rect bounds) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
@@ -182,12 +193,6 @@ public class SweepWatchFaceService extends CanvasWatchFaceService {
int height = bounds.height();
// Draw the background, scaled to fit.
if (mBackgroundScaledBitmap == null
|| mBackgroundScaledBitmap.getWidth() != width
|| mBackgroundScaledBitmap.getHeight() != height) {
mBackgroundScaledBitmap = Bitmap.createScaledBitmap(mBackgroundBitmap,
width, height, true /* filter */);
}
canvas.drawBitmap(mBackgroundScaledBitmap, 0, 0, null);
// Find the center. Ignore the window insets so that, on round watches with a

View File

@@ -45,7 +45,7 @@ public class TiltWatchFaceService extends Gles2WatchFaceService {
private static final long FPS = 60;
/** Z distance from the camera to the watchface. */
private static final float EYE_Z = 2.3f;
private static final float EYE_Z = -2.3f;
/** How long each frame is displayed at expected frame rate. */
private static final long FRAME_PERIOD_MS = TimeUnit.SECONDS.toMillis(1) / FPS;

View File

@@ -16,67 +16,86 @@
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="100">
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="50"
android:scaleType="centerCrop"
android:transitionName="image" />
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?colorPrimary"
android:orientation="vertical"
android:paddingStart="@dimen/keyline2"
android:paddingEnd="@dimen/keyline3"
android:paddingTop="@dimen/standard_margin"
android:paddingBottom="@dimen/standard_margin"
android:elevation="2dp">
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="100">
<TextView
android:id="@+id/nameTextView"
<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="50"
android:scaleType="centerCrop"
android:transitionName="image" />
<LinearLayout
android:id="@+id/textLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="2"
android:ellipsize="end"
android:textIsSelectable="true"
style="@style/TextAppearance.AppCompat.Title.Inverse"
android:transitionName="title" />
android:background="?colorPrimary"
android:orientation="vertical"
android:paddingStart="@dimen/keyline2"
android:paddingEnd="@dimen/keyline3"
android:paddingTop="@dimen/standard_margin"
android:paddingBottom="@dimen/standard_margin"
android:elevation="2dp">
<TextView
android:id="@+id/distanceTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/TextAppearance.AppCompat.Subhead.Inverse" />
<TextView
android:id="@+id/nameTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="2"
android:ellipsize="end"
android:textIsSelectable="true"
style="@style/TextAppearance.AppCompat.Title.Inverse" />
<TextView
android:id="@+id/distanceTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/TextAppearance.AppCompat.Subhead.Inverse" />
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="50"
android:paddingTop="@dimen/standard_margin"
android:paddingBottom="@dimen/standard_margin"
android:scrollbarStyle="outsideOverlay"
android:clipToPadding="false">
<TextView
android:id="@+id/descriptionTextView"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:textIsSelectable="true"
style="@style/TextAppearance.AppCompat.Body1"
android:paddingStart="@dimen/keyline2"
android:paddingEnd="@dimen/keyline3" />
</ScrollView>
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="50"
android:paddingTop="@dimen/standard_margin"
android:paddingBottom="@dimen/standard_margin"
android:scrollbarStyle="outsideOverlay"
android:clipToPadding="false">
<TextView
android:id="@+id/descriptionTextView"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:textIsSelectable="true"
style="@style/TextAppearance.AppCompat.Body1"
android:paddingStart="@dimen/keyline2"
android:paddingEnd="@dimen/keyline3" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/mapFab"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/ic_action_map"
app:layout_anchor="@id/textLayout"
app:layout_anchorGravity="bottom|start"
app:rippleColor="@color/colorFabRipple"
android:layout_marginStart="@dimen/small_margin"
android:clickable="true" />
</ScrollView>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>

View File

@@ -49,21 +49,20 @@
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@android:id/icon"
android:layout_toEndOf="@android:id/icon"
android:paddingTop="@dimen/small_margin"
android:paddingLeft="@dimen/small_margin"
android:paddingRight="@dimen/small_margin"
android:maxLines="1"
android:ellipsize="end"
style="?android:textAppearanceMedium"
tools:text="Title 1"
android:transitionName="image" />
tools:text="Title 1" />
<TextView
android:id="@android:id/text2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@android:id/icon"
android:layout_toEndOf="@android:id/icon"
android:layout_below="@android:id/text1"
android:padding="@dimen/small_margin"
android:ellipsize="end"

View File

@@ -1,28 +0,0 @@
<!--
Copyright 2015 Google Inc. All rights reserved.
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.
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity" >
<item android:id="@+id/map"
android:title="@string/action_map"
android:orderInCategory="100"
android:icon="@drawable/ic_action_map"
app:showAsAction="ifRoom" />
</menu>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 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.
-->
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
android:startDelay="@android:integer/config_shortAnimTime">
<changeBounds>
<arcMotion />
</changeBounds>
<changeTransform/>
<changeClipBounds/>
<changeImageTransform/>
</transitionSet>

View File

@@ -14,7 +14,8 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
android:transitionOrdering="sequential">
<explode>
<targets>
@@ -25,4 +26,11 @@
</targets>
</explode>
<transition class="com.example.android.xyztouristattractions.ui.ScaleTransition"
android:interpolator="@android:interpolator/overshoot">
<targets>
<target android:targetId="@id/mapFab" />
</targets>
</transition>
</transitionSet>

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2015 Google Inc. All rights reserved.
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.
-->
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
android:transitionOrdering="sequential">
<transition class="com.example.android.xyztouristattractions.ui.ScaleTransition"
android:interpolator="@android:interpolator/fast_out_linear_in"
android:duration="@android:integer/config_shortAnimTime">
<targets>
<target android:targetId="@id/mapFab" />
</targets>
</transition>
<explode>
<targets>
<target android:targetClass="android.widget.TextView" />
<target android:targetClass="android.widget.FrameLayout" />
<target android:targetClass="android.widget.LinearLayout" />
<target android:targetClass="android.widget.ImageView" />
<target android:excludeId="@id/mapFab" />
</targets>
</explode>
</transitionSet>

View File

@@ -21,8 +21,10 @@
<item name="android:windowActivityTransitions">true</item>
<item name="android:windowExitTransition">@transition/fade</item>
<item name="android:windowReenterTransition">@transition/fade</item>
<item name="android:windowEnterTransition">@transition/explode</item>
<item name="android:windowReturnTransition">@transition/explode</item>
<item name="android:windowEnterTransition">@transition/window_enter</item>
<item name="android:windowReturnTransition">@transition/window_return</item>
<item name="android:windowSharedElementEnterTransition">@transition/shared_move</item>
<item name="android:windowSharedElementExitTransition">@transition/shared_move</item>
<item name="android:windowAllowEnterTransitionOverlap">false</item>
<item name="android:windowAllowReturnTransitionOverlap">false</item>
<item name="android:windowSharedElementsUseOverlay">false</item>

View File

@@ -216,7 +216,7 @@ public class AttractionListFragment extends Fragment {
@Override
public void onClick(View v) {
mItemClickListener.onItemClick(v, getPosition());
mItemClickListener.onItemClick(v, getAdapterPosition());
}
}

View File

@@ -21,12 +21,11 @@ import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.Fragment;
import android.support.v4.app.NavUtils;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
@@ -83,6 +82,7 @@ public class DetailFragment extends Fragment {
TextView descTextView = (TextView) view.findViewById(R.id.descriptionTextView);
TextView distanceTextView = (TextView) view.findViewById(R.id.distanceTextView);
ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
FloatingActionButton mapFab = (FloatingActionButton) view.findViewById(R.id.mapFab);
LatLng location = Utils.getLocation(getActivity());
String distance = Utils.formatDistanceBetween(location, mAttraction.location);
@@ -102,13 +102,18 @@ public class DetailFragment extends Fragment {
.placeholder(R.color.lighter_gray)
.override(imageSize, imageSize)
.into(imageView);
return view;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.detail, menu);
super.onCreateOptionsMenu(menu, inflater);
mapFab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(Constants.MAPS_INTENT_URI +
Uri.encode(mAttraction.name + ", " + mAttraction.city)));
startActivity(intent);
}
});
return view;
}
@Override
@@ -139,12 +144,6 @@ public class DetailFragment extends Fragment {
// Otherwise let the system handle navigating "up"
return false;
case R.id.map:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(Constants.MAPS_INTENT_URI +
Uri.encode(mAttraction.name + ", " + mAttraction.city)));
startActivity(intent);
return true;
}
return super.onOptionsItemSelected(item);
}

View File

@@ -0,0 +1,42 @@
package com.example.android.xyztouristattractions.ui;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.transition.TransitionValues;
import android.transition.Visibility;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class ScaleTransition extends Visibility {
public ScaleTransition(Context context, AttributeSet attrs) {
super(context, attrs);
}
public Animator createAnimation(View view, float startScale, float endScale, boolean appear) {
view.setScaleX(startScale);
view.setScaleY(startScale);
PropertyValuesHolder holderX = PropertyValuesHolder.ofFloat("scaleX", startScale, endScale);
PropertyValuesHolder holderY = PropertyValuesHolder.ofFloat("scaleY", startScale, endScale);
ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(view, holderX, holderY);
return animator;
}
@Override
public Animator onAppear(ViewGroup sceneRoot, View view, TransitionValues startValues,
TransitionValues endValues) {
return createAnimation(view, 0, 1, true);
}
@Override
public Animator onDisappear(ViewGroup sceneRoot, View view, TransitionValues startValues,
TransitionValues endValues) {
return createAnimation(view, 1, 0, false);
}
}

View File

@@ -20,5 +20,6 @@
<color name="colorPrimary">#4e6cef</color>
<color name="colorPrimaryDark">#2a36b1</color>
<color name="colorAccent">#ff7043</color>
<color name="colorFabRipple">#D84315</color>
</resources>

View File

@@ -30,7 +30,6 @@ import com.example.android.xyztouristattractions.common.Utils;
import com.example.android.xyztouristattractions.ui.AttractionsActivity;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.data.FreezableUtils;
import com.google.android.gms.wearable.DataEvent;
import com.google.android.gms.wearable.DataEventBuffer;
import com.google.android.gms.wearable.DataMap;
@@ -54,9 +53,7 @@ public class ListenerService extends WearableListenerService {
public void onDataChanged(DataEventBuffer dataEvents) {
Log.d(TAG, "onDataChanged: " + dataEvents);
final List<DataEvent> events = FreezableUtils.freezeIterable(dataEvents);
for (DataEvent event : events) {
for (DataEvent event : dataEvents) {
if (event.getType() == DataEvent.TYPE_CHANGED
&& event.getDataItem() != null
&& Constants.ATTRACTION_PATH.equals(event.getDataItem().getUri().getPath())) {