Merge pull request #42 from alsutton/parameterised_keys
Parameterise keystore properties
diff --git a/.travis.yml b/.travis.yml
index 60d0d16..a64747a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -17,7 +17,7 @@
android:
components:
- build-tools-20.0.0
- - andorid-19
+ - android-19
- android-20
- extra-google-m2repository
- extra-android-m2repository
diff --git a/Wearable/build.gradle b/Wearable/build.gradle
index 3c37e6c..05a05a8 100644
--- a/Wearable/build.gradle
+++ b/Wearable/build.gradle
@@ -65,8 +65,8 @@
}
dependencies {
- compile 'com.android.support:support-v13:+'
+ compile 'com.android.support:support-v13:21.+'
compile 'com.google.android.support:wearable:+'
- compile 'com.google.android.gms:play-services-wearable:+'
+ compile 'com.google.android.gms:play-services-wearable:6.1.+'
}
diff --git a/Wearable/src/main/java/com/google/samples/apps/iosched/iowear/Utils/Utils.java b/Wearable/src/main/java/com/google/samples/apps/iosched/iowear/utils/Utils.java
similarity index 100%
rename from Wearable/src/main/java/com/google/samples/apps/iosched/iowear/Utils/Utils.java
rename to Wearable/src/main/java/com/google/samples/apps/iosched/iowear/utils/Utils.java
diff --git a/android/build.gradle b/android/build.gradle
index b570079..cc7937b 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-lpreview = hasProperty('lpreview')
-
apply plugin: 'com.android.application'
repositories {
@@ -26,15 +24,12 @@
}
android {
- compileSdkVersion lpreview ? "android-L" : 19
- buildToolsVersion "20.0.0"
+ compileSdkVersion 21
+ buildToolsVersion "21.0.0"
- productFlavors { lpreview ? lpreview{} : classic{} }
-
- defaultConfig lpreview ? {} : {
- // Non-L-preview configuration
+ defaultConfig {
minSdkVersion 14
- targetSdkVersion 19
+ targetSdkVersion 21
}
signingConfigs {
@@ -75,10 +70,10 @@
dependencies {
wearApp project(':Wearable')
- compile 'com.google.android.gms:play-services:5+'
- compile 'com.android.support:support-v13:20.+'
- compile 'com.android.support:support-v4:20.+'
- compile 'com.google.android.apps.dashclock:dashclock-api:+'
+ compile 'com.google.android.gms:play-services:6.1.+'
+ compile 'com.android.support:support-v13:21.+'
+ compile 'com.android.support:appcompat-v7:21.+'
+ compile 'com.android.support:cardview-v7:21.+'
compile 'com.google.code.gson:gson:2.+'
compile('com.google.api-client:google-api-client:1.+') {
exclude group: 'xpp3', module: 'shared'
diff --git a/android/src/classic/java/com/google/samples/apps/iosched/util/LPreviewUtils.java b/android/src/classic/java/com/google/samples/apps/iosched/util/LPreviewUtils.java
deleted file mode 100644
index e9b622d..0000000
--- a/android/src/classic/java/com/google/samples/apps/iosched/util/LPreviewUtils.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright 2014 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.
- */
-
-package com.google.samples.apps.iosched.util;
-
-import android.app.Activity;
-
-public class LPreviewUtils {
- private LPreviewUtils() {
- }
-
- public static LPreviewUtilsBase getInstance(Activity activity) {
- return new LPreviewUtilsBase(activity);
- }
-}
diff --git a/android/src/lpreview/java/com/google/samples/apps/iosched/util/LPreviewUtils.java b/android/src/lpreview/java/com/google/samples/apps/iosched/util/LPreviewUtils.java
deleted file mode 100644
index 6503430..0000000
--- a/android/src/lpreview/java/com/google/samples/apps/iosched/util/LPreviewUtils.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2014 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.
- */
-
-package com.google.samples.apps.iosched.util;
-
-import android.app.Activity;
-import android.os.Build;
-
-public class LPreviewUtils {
- private LPreviewUtils() {
- }
-
- public static LPreviewUtilsBase getInstance(Activity activity) {
- if ("L".equals(Build.VERSION.CODENAME)) {
- return new LPreviewUtilsImpl(activity);
- } else {
- return new LPreviewUtilsBase(activity);
- }
- }
-}
diff --git a/android/src/lpreview/java/com/google/samples/apps/iosched/util/LPreviewUtilsImpl.java b/android/src/lpreview/java/com/google/samples/apps/iosched/util/LPreviewUtilsImpl.java
deleted file mode 100644
index d1023d8..0000000
--- a/android/src/lpreview/java/com/google/samples/apps/iosched/util/LPreviewUtilsImpl.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright 2014 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.
- */
-
-package com.google.samples.apps.iosched.util;
-
-import android.annotation.TargetApi;
-import android.app.Activity;
-import android.app.ActivityOptions;
-import android.app.SharedElementListener;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.graphics.Typeface;
-import android.graphics.drawable.AnimatedStateListDrawable;
-import android.os.Build;
-import android.support.v4.widget.DrawerLayout;
-import android.text.TextUtils;
-import android.view.Gravity;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-import android.widget.Toolbar;
-
-import com.google.samples.apps.iosched.R;
-
-import java.lang.Override;
-import java.util.List;
-import java.util.Map;
-
-@TargetApi(Build.VERSION_CODES.L)
-public class LPreviewUtilsImpl extends LPreviewUtilsBase {
- private static final int[] STATE_CHECKED = new int[]{android.R.attr.state_checked};
- private static final int[] STATE_UNCHECKED = new int[]{};
-
- private static Typeface sMediumTypeface;
-
- private ActionBarDrawerToggleWrapper mDrawerToggleWrapper;
- private DrawerLayout mDrawerLayout;
- private Toolbar mActionBarToolbar;
-
- LPreviewUtilsImpl(Activity activity) {
- super(activity);
- }
-
- @Override
- public ActionBarDrawerToggleWrapper setupDrawerToggle(DrawerLayout drawerLayout, DrawerLayout.DrawerListener drawerListener) {
- // On L, use a different drawer indicator
- if (mActionBarToolbar != null) {
- mActionBarToolbar.setNavigationIcon(R.drawable.ic_drawer);
- mActionBarToolbar.setNavigationOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- if (mDrawerLayout.isDrawerOpen(Gravity.START)) {
- mDrawerLayout.closeDrawer(Gravity.START);
- } else {
- mDrawerLayout.openDrawer(Gravity.START);
- }
- }
- });
- } else {
- mActivity.getActionBar().setHomeAsUpIndicator(R.drawable.ic_drawer);
- }
- // On L, stub out the ActionBarDrawerToggle
- mDrawerLayout = drawerLayout;
- mDrawerLayout.setDrawerListener(drawerListener);
- mDrawerToggleWrapper = new ActionBarDrawerToggleWrapper();
- return mDrawerToggleWrapper;
- }
-
- public class ActionBarDrawerToggleWrapper extends LPreviewUtilsBase.ActionBarDrawerToggleWrapper {
- public void syncState() {
- }
-
- public void onConfigurationChanged(Configuration newConfig) {
- }
-
- public boolean onOptionsItemSelected(MenuItem item) {
- // Toggle drawer
- if (item.getItemId() == android.R.id.home) {
- if (mDrawerLayout.isDrawerOpen(Gravity.START)) {
- mDrawerLayout.closeDrawer(Gravity.START);
- } else {
- mDrawerLayout.openDrawer(Gravity.START);
- }
- return true;
- }
- return false;
- }
- }
-
- @Override
- public void setViewElevation(View v, float elevation) {
- v.setElevation(elevation);
- }
-
- @Override
- public void trySetActionBar() {
- mActionBarToolbar = (Toolbar) mActivity.findViewById(R.id.toolbar_actionbar);
- if (mActionBarToolbar != null) {
- mActivity.setActionBar(mActionBarToolbar);
- }
- }
-
- @Override
- public boolean hasLPreviewAPIs() {
- return true;
- }
-
- public void startActivityWithTransition(Intent intent, final View clickedView,
- final String sharedElementName) {
- ActivityOptions options = null;
- if (clickedView != null && !TextUtils.isEmpty(sharedElementName)) {
- options = ActivityOptions.makeSceneTransitionAnimation(
- mActivity, clickedView, sharedElementName);
- }
-
- mActivity.setExitSharedElementListener(new SharedElementListener() {
- @Override
- public void remapSharedElements(List<String> names, Map<String, View> sharedElements) {
- super.remapSharedElements(names, sharedElements);
- sharedElements.put(sharedElementName, clickedView);
- }
- });
-
- mActivity.startActivity(intent, (options != null) ? options.toBundle() : null);
- }
-
- @Override
- public void setViewName(View v, String viewName) {
- v.setViewName(viewName);
- }
-
- @Override
- public void postponeEnterTransition() {
- mActivity.postponeEnterTransition();
- }
-
- @Override
- public void startPostponedEnterTransition() {
- mActivity.startPostponedEnterTransition();
- }
-
- @Override
- public void showHideActionBarIfPartOfDecor(boolean show) {
- if (mActionBarToolbar != null) {
- // Action bar is part of the layout
- return;
- }
-
- // Action bar is part of window decor
- super.showHideActionBarIfPartOfDecor(show);
- }
-
- public boolean shouldChangeActionBarForDrawer() {
- return false;
- }
-
- @Override
- public void setMediumTypeface(TextView textView) {
- if (sMediumTypeface == null) {
- sMediumTypeface = Typeface.create("sans-serif-medium", Typeface.NORMAL);
- }
-
- textView.setTypeface(sMediumTypeface);
- }
-
- @Override
- public int getStatusBarColor() {
- return mActivity.getWindow().getStatusBarColor();
- }
-
- @Override
- public void setStatusBarColor(int color) {
- mActivity.getWindow().setStatusBarColor(color);
- }
-
- @Override
- public void setOrAnimatePlusCheckIcon(final ImageView imageView, boolean isCheck,
- boolean allowAnimate) {
- AnimatedStateListDrawable drawable = (AnimatedStateListDrawable)
- mActivity.getResources().getDrawable(R.drawable.add_schedule_fab_icon_anim);
- imageView.setImageDrawable(drawable);
- if (allowAnimate) {
- // TODO: figure out if there's a way to always animate from current state
- imageView.setImageState(isCheck ? STATE_UNCHECKED : STATE_CHECKED, false);
- drawable.jumpToCurrentState();
- imageView.setImageState(isCheck ? STATE_CHECKED : STATE_UNCHECKED, false);
- } else {
- imageView.setImageState(isCheck ? STATE_CHECKED : STATE_UNCHECKED, false);
- drawable.jumpToCurrentState();
- }
- }
-}
diff --git a/android/src/lpreview/res/anim-v21/add_schedule_fab_state_list_anim.xml b/android/src/lpreview/res/anim-v21/add_schedule_fab_state_list_anim.xml
deleted file mode 100644
index 4e1d87c..0000000
--- a/android/src/lpreview/res/anim-v21/add_schedule_fab_state_list_anim.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2014 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.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_enabled="true" android:state_pressed="true">
- <set>
- <objectAnimator android:duration="@android:integer/config_shortAnimTime"
- android:propertyName="translationZ"
- android:valueTo="@dimen/fab_press_translation_z"
- android:valueType="floatType"/>
- </set>
- </item>
- <item>
- <set>
- <objectAnimator android:duration="@android:integer/config_shortAnimTime"
- android:propertyName="translationZ"
- android:valueTo="0"
- android:valueType="floatType"/>
- </set>
- </item>
-</selector>
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_drawer.png b/android/src/lpreview/res/drawable-xxhdpi-v21/ic_drawer.png
deleted file mode 100644
index 19bae3e..0000000
--- a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_drawer.png
+++ /dev/null
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_launcher.png b/android/src/lpreview/res/drawable-xxhdpi-v21/ic_launcher.png
deleted file mode 100644
index 32502c3..0000000
--- a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_up.png b/android/src/lpreview/res/drawable-xxhdpi-v21/ic_up.png
deleted file mode 100644
index 3396894..0000000
--- a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_up.png
+++ /dev/null
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxxhdpi-v21/ic_launcher.png b/android/src/lpreview/res/drawable-xxxhdpi-v21/ic_launcher.png
deleted file mode 100644
index afae355..0000000
--- a/android/src/lpreview/res/drawable-xxxhdpi-v21/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/android/src/lpreview/res/layout-v21/toolbar_actionbar.xml b/android/src/lpreview/res/layout-v21/toolbar_actionbar.xml
deleted file mode 100644
index 04af731..0000000
--- a/android/src/lpreview/res/layout-v21/toolbar_actionbar.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!--
- Copyright 2014 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.
- -->
-
-<Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
- android:theme="@style/ActionBarThemeOverlay"
- android:id="@+id/toolbar_actionbar"
- android:layout_width="match_parent"
- android:layout_height="?android:actionBarSize" />
diff --git a/android/src/lpreview/res/values-sw600dp-v21/styles.xml b/android/src/lpreview/res/values-sw600dp-v21/styles.xml
deleted file mode 100644
index 8165a88..0000000
--- a/android/src/lpreview/res/values-sw600dp-v21/styles.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<!--
- Copyright 2014 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.
- -->
-
-<resources>
-
- <style name="Theme.IOSched.Sessions" parent="Theme.IOSched.Sessions.Base">
- <item name="actionBarInsetStart">@dimen/keyline_2_minus_16dp</item>
- <item name="spinnerBarInsetStart">@dimen/keyline_2_minus_16dp</item>
- <item name="android:windowActionBar">false</item> <!-- replaced by toolbar -->
- <item name="android:windowNoTitle">true</item>
- <item name="android:windowContentTransitions">false</item>
- </style>
-
- <style name="Theme.IOSched.SessionDetails" parent="Theme.IOSched.SessionDetails.Base">
- <item name="android:windowContentTransitions">false</item>
- <item name="android:actionBarStyle">@style/TransparentActionBar</item>
- <item name="android:windowBackground">@android:color/transparent</item>
- <item name="android:windowActionBarOverlay">true</item>
- <item name="android:homeAsUpIndicator">@drawable/ic_ab_close</item>
- </style>
-
-</resources>
diff --git a/android/src/lpreview/res/values-v21/attrs.xml b/android/src/lpreview/res/values-v21/attrs.xml
deleted file mode 100644
index 6661e6a..0000000
--- a/android/src/lpreview/res/values-v21/attrs.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<!--
- Copyright 2014 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.
- -->
-
-<resources>
- <declare-styleable name="ThemeLPreview">
- <attr name="actionBarIconColor" format="color" />
- </declare-styleable>
-</resources>
diff --git a/android/src/lpreview/res/values-v21/styles.xml b/android/src/lpreview/res/values-v21/styles.xml
deleted file mode 100644
index 4d00ccf..0000000
--- a/android/src/lpreview/res/values-v21/styles.xml
+++ /dev/null
@@ -1,140 +0,0 @@
-<!--
- Copyright 2014 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.
- -->
-
-<resources>
-
- <style name="FrameworkRoot.Theme" parent="android:Theme.Material.Light.DarkActionBar" />
- <style name="FrameworkRoot.ActionBar" parent="android:Widget.Material.ActionBar" />
- <style name="FrameworkRoot.ActionBar.TitleText" parent="android:TextAppearance.Material.Widget.ActionBar.Title" />
- <style name="FrameworkRoot.ActionBar.TabBar" parent="android:Widget.Material.ActionBar.TabBar" />
- <style name="FrameworkRoot.EditText" parent="android:Widget.Material.Light.EditText" />
- <style name="FrameworkRoot.Widget" parent="android:Theme.Material" />
- <style name="FrameworkRoot.Widget.ActionButton.Overflow" parent="android:Widget.Material.ActionButton.Overflow" />
- <style name="FrameworkRoot.Widget.Spinner" parent="android:Widget.Material.Light.Spinner" />
- <style name="FrameworkRoot.Widget.ListView.DropDown" parent="android:Widget.Material.Light.ListView.DropDown" />
- <style name="FrameworkRoot.Widget.PopupMenu" parent="android:Widget.Material.Light.PopupMenu" />
- <style name="FrameworkRoot.TextAppearance.Widget.PopupMenu.Large" parent="android:TextAppearance.Material.Widget.PopupMenu.Large" />
-
- <style name="Theme" parent="FrameworkRoot.Theme" /> <!-- doesn't contain the pre-L code from the values/styles.xml -->
-
- <style name="Theme.IOSched" parent="Theme.IOSched.Base">
- <item name="actionBarIconColor">#fff</item>
- <item name="actionBarOverlayTopOffset">0dp</item> <!-- action bars replaced by Toolbars -->
- <item name="actionBarInsetStart">@dimen/keyline_2</item>
- <item name="spinnerBarInsetStart">@dimen/keyline_2_minus_16dp</item>
- <item name="selectableItemBackgroundBorderless">?android:selectableItemBackgroundBorderless</item>
- <item name="popupItemBackground">@drawable/popup_item_background</item>
- <item name="photoItemForeground">@drawable/photo_item_foreground</item>
-
- <item name="android:colorPrimary">@color/theme_primary</item>
- <item name="android:colorPrimaryDark">@color/theme_primary_dark</item>
- <item name="android:colorAccent">@color/theme_accent_2</item>
- <item name="android:navigationBarColor">#000</item>
- <item name="android:actionBarTheme">@style/ActionBarThemeOverlay</item>
- <item name="android:homeAsUpIndicator">@drawable/ic_up</item>
-
- <!-- used only if windowContentTransitions is true -->
- <item name="android:windowSharedElementEnterTransition">@transition/shared_element</item>
- <item name="android:windowSharedElementExitTransition">@transition/shared_element</item>
- <item name="android:windowEnterTransition">@android:transition/no_transition</item>
- <item name="android:windowExitTransition">@android:transition/no_transition</item>
- <item name="android:windowAllowExitTransitionOverlap">true</item>
- <item name="android:windowAllowEnterTransitionOverlap">true</item>
- </style>
-
- <style name="Theme.IOSched.SessionDetails" parent="Theme.IOSched.SessionDetails.Base">
- <item name="android:actionBarStyle">@style/TransparentActionBar</item>
- <item name="android:windowActionBarOverlay">true</item>
- <!--<item name="android:windowContentTransitions">true</item>-->
- </style>
-
- <style name="Theme.IOSched.Sessions" parent="Theme.IOSched.Sessions.Base">
- <item name="actionBarInsetStart">@dimen/keyline_2_minus_16dp</item>
- <item name="android:windowActionBar">false</item> <!-- replaced by toolbar -->
- <item name="android:windowNoTitle">true</item>
- <!--<item name="android:windowContentTransitions">true</item>-->
- </style>
-
- <!-- Live stream -->
- <style name="Theme.IOSched.Livestream" parent="Theme.IOSched">
- <item name="android:windowBackground">@color/gray_background</item>
- <item name="actionBarInsetStart">@dimen/keyline_2_minus_16dp</item>
- </style>
-
- <style name="Theme.IOSched.WithElevatedHeader" parent="Theme.IOSched">
- <item name="android:actionBarStyle">@style/ElevatedActionBar</item>
- </style>
-
- <style name="Theme.IOSched.MySchedule" parent="Theme.IOSched">
- <item name="android:windowActionBar">false</item> <!-- replaced by toolbar -->
- <item name="android:windowNoTitle">true</item>
- </style>
-
- <style name="Theme.IOSched.Map" parent="Theme.IOSched">
- <item name="android:windowActionBar">false</item> <!-- replaced by toolbar -->
- <item name="android:windowNoTitle">true</item>
- </style>
-
- <style name="Theme.IOSched.PeopleIveMet" parent="Theme.IOSched">
- <item name="android:windowActionBar">false</item> <!-- replaced by toolbar -->
- <item name="android:windowNoTitle">true</item>
- </style>
-
- <style name="Theme.IOSched.ExpertsDirectory" parent="Theme.IOSched">
- <item name="android:windowActionBar">false</item> <!-- replaced by toolbar -->
- <item name="android:windowNoTitle">true</item>
- </style>
-
- <style name="Theme.IOSched.Social" parent="Theme.IOSched">
- <item name="android:windowActionBar">false</item> <!-- replaced by toolbar -->
- <item name="android:windowNoTitle">true</item>
- <item name="android:windowBackground">@color/gray_background</item>
- </style>
-
- <style name="Theme.IOSched.VideoLibrary" parent="Theme.IOSched">
- <item name="android:windowActionBar">false</item> <!-- replaced by toolbar -->
- <item name="android:windowNoTitle">true</item>
- <item name="android:windowActionBarOverlay">true</item>
- </style>
-
- <style name="Widget.IOSched.HeaderBar.Spinner" parent="Widget.IOSched.HeaderBar.Spinner.Base">
- <item name="android:theme">@style/ActionBarThemeOverlay</item>
- </style>
-
- <style name="ActionBar" parent="ActionBar.Base">
- <item name="android:displayOptions">homeAsUp|showTitle</item>
- <item name="android:contentInsetStart">?actionBarInsetStart</item>
- </style>
-
- <style name="ElevatedActionBar" parent="ActionBar">
- <item name="android:elevation">@dimen/headerbar_elevation</item>
- </style>
-
- <style name="TabIndicator">
- <item name="android:theme">@style/ActionBarThemeOverlay</item>
- </style>
-
- <style name="ActionBarThemeOverlay" parent="">
- <item name="android:textColorPrimary">#fff</item>
- <item name="android:colorControlNormal">?actionBarIconColor</item>
- <item name="android:colorControlHighlight">#3fff</item>
- </style>
-
- <style name="HeaderBar">
- <item name="android:elevation">@dimen/headerbar_elevation</item>
- <item name="android:background">?android:colorPrimary</item>
- </style>
-</resources>
diff --git a/android/src/main/AndroidManifest.xml b/android/src/main/AndroidManifest.xml
index 6c1bd36..beb8708 100644
--- a/android/src/main/AndroidManifest.xml
+++ b/android/src/main/AndroidManifest.xml
@@ -22,10 +22,9 @@
android:versionName="2.2.3"
android:installLocation="auto">
- <!-- targetSdkVersion set to 19 from build.gradle on non-L-preview builds -->
<uses-sdk
android:minSdkVersion="14"
- android:targetSdkVersion="L" />
+ android:targetSdkVersion="21" />
<permission
android:name="com.google.samples.apps.iosched.permission.WRITE_SCHEDULE"
@@ -80,7 +79,7 @@
<application
android:label="@string/app_name"
- android:icon="@drawable/ic_launcher"
+ android:icon="@mipmap/ic_launcher"
android:logo="@drawable/actionbar_logo"
android:theme="@style/Theme.IOSched"
android:hardwareAccelerated="true"
@@ -124,7 +123,6 @@
<activity
android:name=".ui.SettingsActivity"
android:label="@string/title_settings"
- android:theme="@style/Theme.IOSched.WithElevatedHeader"
android:parentActivityName=".ui.MyScheduleActivity" />
<activity
@@ -170,8 +168,7 @@
</activity>
<activity android:name=".ui.SessionFeedbackActivity"
- android:label="@string/title_session_feedback"
- android:theme="@style/Theme.IOSched.WithElevatedHeader">
+ android:label="@string/title_session_feedback">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
@@ -262,7 +259,7 @@
<!-- People I've Met -->
<activity android:name=".ui.PeopleIveMetActivity"
- android:label="@string/app_name"
+ android:label="@string/title_people_ive_met"
android:theme="@style/Theme.IOSched.PeopleIveMet"/>
<!-- Session alarm/calendar integrating components. -->
@@ -367,9 +364,6 @@
<intent-filter>
<action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
</intent-filter>
- <intent-filter>
- <action android:name="com.google.sample.apps.iosched.ACTION_NOTIFICATION_DISMISSAL"/>
- </intent-filter>
</service>
</application>
diff --git a/android/src/main/java/com/google/samples/apps/iosched/gcm/GCMRedirectedBroadcastReceiver.java b/android/src/main/java/com/google/samples/apps/iosched/gcm/GCMRedirectedBroadcastReceiver.java
index f928e6d..2340454 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/gcm/GCMRedirectedBroadcastReceiver.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/gcm/GCMRedirectedBroadcastReceiver.java
@@ -22,7 +22,6 @@
import android.content.Context;
/**
- * @author trevorjohns@google.com (Trevor Johns)
*/
public class GCMRedirectedBroadcastReceiver extends GCMBroadcastReceiver {
diff --git a/android/src/main/java/com/google/samples/apps/iosched/service/SessionAlarmService.java b/android/src/main/java/com/google/samples/apps/iosched/service/SessionAlarmService.java
index 948e97f..91a5af1 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/service/SessionAlarmService.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/service/SessionAlarmService.java
@@ -16,7 +16,11 @@
package com.google.samples.apps.iosched.service;
-import android.app.*;
+import android.app.AlarmManager;
+import android.app.IntentService;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -37,20 +41,21 @@
import com.google.android.gms.wearable.Wearable;
import com.google.samples.apps.iosched.R;
import com.google.samples.apps.iosched.provider.ScheduleContract;
+import com.google.samples.apps.iosched.ui.BaseMapActivity;
import com.google.samples.apps.iosched.ui.BrowseSessionsActivity;
-import com.google.samples.apps.iosched.ui.MapFragment;
import com.google.samples.apps.iosched.ui.MyScheduleActivity;
import com.google.samples.apps.iosched.ui.SessionFeedbackActivity;
-import com.google.samples.apps.iosched.ui.phone.MapActivity;
import com.google.samples.apps.iosched.util.FeedbackUtils;
import com.google.samples.apps.iosched.util.PrefUtils;
import com.google.samples.apps.iosched.util.UIUtils;
import java.util.ArrayList;
import java.util.Date;
+import java.util.List;
import java.util.concurrent.TimeUnit;
import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGE;
import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
/**
@@ -140,6 +145,10 @@
scheduleAllStarredBlocks();
scheduleAllStarredSessionFeedbacks();
return;
+ } else if (ACTION_NOTIFY_SESSION_FEEDBACK.equals(action)) {
+ LOGD(TAG, "Showing session feedback notification.");
+ notifySessionFeedback(DEBUG_SESSION_ID.equals(intent.getStringExtra(EXTRA_SESSION_ID)));
+ return;
}
final long sessionEnd = intent.getLongExtra(SessionAlarmService.EXTRA_SESSION_END,
@@ -155,30 +164,17 @@
LOGD(TAG, "Session alarm offset is: " + sessionAlarmOffset);
// Feedback notifications have a slightly different set of extras.
- if (ACTION_SCHEDULE_FEEDBACK_NOTIFICATION.equals(action) ||
- ACTION_NOTIFY_SESSION_FEEDBACK.equals(action)) {
+ if (ACTION_SCHEDULE_FEEDBACK_NOTIFICATION.equals(action)) {
final String sessionId = intent.getStringExtra(SessionAlarmService.EXTRA_SESSION_ID);
final String sessionTitle = intent.getStringExtra(
SessionAlarmService.EXTRA_SESSION_TITLE);
- final String sessionRoom = intent.getStringExtra(
- SessionAlarmService.EXTRA_SESSION_ROOM);
- final String sessionSpeakers = intent.getStringExtra(
- SessionAlarmService.EXTRA_SESSION_SPEAKERS);
if (sessionTitle == null || sessionEnd == UNDEFINED_VALUE ||
sessionId == null) {
- Log.e(TAG,
- "Attempted to schedule or notify for feedback without providing extras.");
+ LOGE(TAG, "Attempted to schedule for feedback without providing extras.");
return;
}
- if (ACTION_SCHEDULE_FEEDBACK_NOTIFICATION.equals(action)) {
- LOGD(TAG, "Scheduling feedback alarm for session: " + sessionTitle);
- scheduleFeedbackAlarm(sessionId, sessionEnd, sessionAlarmOffset, sessionTitle,
- sessionRoom, sessionSpeakers);
- } else {
- LOGD(TAG, "Notifying for feedback on session: " + sessionTitle);
- notifySessionFeedback(sessionId, sessionEnd, sessionTitle, sessionRoom,
- sessionSpeakers);
- }
+ LOGD(TAG, "Scheduling feedback alarm for session: " + sessionTitle);
+ scheduleFeedbackAlarm(sessionEnd, sessionAlarmOffset, sessionTitle);
return;
}
@@ -204,9 +200,8 @@
}
}
- public void scheduleFeedbackAlarm(final String sessionId, final long sessionEnd,
- final long alarmOffset, final String sessionTitle, String sessionRoom,
- String sessionSpeakers) {
+ public void scheduleFeedbackAlarm(final long sessionEnd,
+ final long alarmOffset, final String sessionTitle) {
// By default, feedback alarms fire 5 minutes before session end time. If alarm offset is
// provided, alarm is set to go off that much time from now (useful for testing).
long alarmTime;
@@ -219,24 +214,12 @@
LOGD(TAG, "Scheduling session feedback alarm for session '" + sessionTitle + "'");
LOGD(TAG, " -> end time: " + sessionEnd + " = " + (new Date(sessionEnd)).toString());
LOGD(TAG, " -> alarm time: " + alarmTime + " = " + (new Date(alarmTime)).toString());
- LOGD(TAG, " -> room name: " + sessionRoom);
- LOGD(TAG, " -> speakers: " + sessionSpeakers);
final Intent feedbackIntent = new Intent(
ACTION_NOTIFY_SESSION_FEEDBACK,
null,
this,
SessionAlarmService.class);
- feedbackIntent.setData(
- new Uri.Builder().authority("com.google.samples.apps.iosched")
- .path(sessionId).build()
- );
- feedbackIntent.putExtra(SessionAlarmService.EXTRA_SESSION_END, sessionEnd);
- feedbackIntent.putExtra(SessionAlarmService.EXTRA_SESSION_ALARM_OFFSET, alarmOffset);
- feedbackIntent.putExtra(SessionAlarmService.EXTRA_SESSION_ID, sessionId);
- feedbackIntent.putExtra(SessionAlarmService.EXTRA_SESSION_TITLE, sessionTitle);
- feedbackIntent.putExtra(SessionAlarmService.EXTRA_SESSION_SPEAKERS, sessionSpeakers);
- feedbackIntent.putExtra(SessionAlarmService.EXTRA_SESSION_ROOM, sessionRoom);
PendingIntent pi = PendingIntent.getService(
this, 1, feedbackIntent, PendingIntent.FLAG_CANCEL_CURRENT);
final AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
@@ -296,84 +279,116 @@
// A starred session is about to end; notify the user to provide session feedback.
// Constructs and triggers a system notification. Does nothing if the session has already
// concluded.
- private void notifySessionFeedback(final String sessionId, final long sessionEnd,
- final String sessionTitle, final String sessionRoom, final String sessionSpeakers) {
- LOGD(TAG, "Considering firing notification for feedback for session: " + sessionTitle);
- boolean isDebug = DEBUG_SESSION_ID.equals(sessionId);
+ private void notifySessionFeedback(boolean debug) {
+ LOGD(TAG, "Considering firing notification for session feedback.");
- if (isDebug) {
+ if (debug) {
LOGD(TAG, "Note: this is a debug notification.");
}
// Don't fire notification if this feature is disabled in settings
if (!PrefUtils.shouldShowSessionFeedbackReminders(this)) {
- LOGD(TAG, "Skipping session feedback notification for session " + sessionId + " ("
- + sessionTitle + "). Disabled in settings.");
+ LOGD(TAG, "Skipping session feedback notification. Disabled in settings.");
return;
}
- // Avoid repeated notifications.
- if (!isDebug && UIUtils.isFeedbackNotificationFiredForSession(this, sessionId)) {
- LOGD(TAG, "Skipping repeated session feedback notification for session '"
- + sessionTitle + "'");
- return;
- }
-
- // If the session is no longer is MY_SCHEDULE, don't notify for it.
- final Uri myScheduleUri = ScheduleContract.MySchedule.buildMyScheduleUri(this);
final Cursor c = getContentResolver().query(
- myScheduleUri, MySessionsExistenceQuery.PROJECTION,
- MySessionsExistenceQuery.WHERE_CLAUSE, new String[]{sessionId}, null);
- if (!isDebug && (c == null || !c.moveToFirst())) {
- // no longer in MY_SCHEDULE
+ ScheduleContract.Sessions.CONTENT_MY_SCHEDULE_URI,
+ SessionsNeedingFeedbackQuery.PROJECTION,
+ SessionsNeedingFeedbackQuery.WHERE_CLAUSE, null, null);
+ if (c == null) {
return;
}
- LOGD(TAG, "Going forward with session feedback notification for: " + sessionTitle);
- final Uri sessionUri = ScheduleContract.Sessions.buildSessionUri(sessionId);
+ List<String> needFeedbackIds = new ArrayList<String>();
+ List<String> needFeedbackTitles = new ArrayList<String>();
+ while (c.moveToNext()) {
+ String sessionId = c.getString(SessionsNeedingFeedbackQuery.SESSION_ID);
+ String sessionTitle = c.getString(SessionsNeedingFeedbackQuery.SESSION_TITLE);
+
+ // Avoid repeated notifications.
+ if (UIUtils.isFeedbackNotificationFiredForSession(this, sessionId)) {
+ LOGD(TAG, "Skipping repeated session feedback notification for session '"
+ + sessionTitle + "'");
+ continue;
+ }
+
+ needFeedbackIds.add(sessionId);
+ needFeedbackTitles.add(sessionTitle);
+ }
+
+ if (needFeedbackIds.size() == 0) {
+ // the user has already been notified of all sessions needing feedback
+ return;
+ }
+
+ LOGD(TAG, "Going forward with session feedback notification for "
+ + needFeedbackIds.size() + " session(s).");
final Resources res = getResources();
- String contentText = res.getString(R.string.session_feedback_notification_text,
- sessionTitle);
-
- PendingIntent pi = TaskStackBuilder.create(this)
- .addNextIntent(new Intent(this, MyScheduleActivity.class))
- .addNextIntent(new Intent(Intent.ACTION_VIEW, sessionUri, this,
- SessionFeedbackActivity.class))
- .getPendingIntent(1, PendingIntent.FLAG_CANCEL_CURRENT);
// this is used to synchronize deletion of notifications on phone and wear
Intent dismissalIntent = new Intent(ACTION_NOTIFICATION_DISMISSAL);
- dismissalIntent.putExtra(KEY_SESSION_ID, sessionId);
+ // TODO: fix Wear dismiss integration
+ //dismissalIntent.putExtra(KEY_SESSION_ID, sessionId);
PendingIntent dismissalPendingIntent = PendingIntent
.getService(this, (int) new Date().getTime(), dismissalIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
+ String provideFeedbackTicker = res.getString(R.string.session_feedback_notification_ticker);
NotificationCompat.Builder notifBuilder = new NotificationCompat.Builder(this)
- .setContentTitle(sessionTitle)
- .setContentText(contentText)
- //.setColor(getResources().getColor(R.color.theme_primary))
- // Note: setColor() is available in the support lib v21+.
- // We commented it out because we want the source to compile
- // against support lib v20. If you are using support lib
- // v21 or above on Android L, uncomment this line.
- .setTicker(res.getString(R.string.session_feedback_notification_ticker))
- .setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE)
+ .setColor(getResources().getColor(R.color.theme_primary))
+ .setContentText(provideFeedbackTicker)
+ .setTicker(provideFeedbackTicker)
.setLights(
SessionAlarmService.NOTIFICATION_ARGB_COLOR,
SessionAlarmService.NOTIFICATION_LED_ON_MS,
SessionAlarmService.NOTIFICATION_LED_OFF_MS)
.setSmallIcon(R.drawable.ic_stat_notification)
- .setContentIntent(pi)
- .setPriority(Notification.PRIORITY_MAX)
+ .setPriority(Notification.PRIORITY_LOW)
.setLocalOnly(true) // make it local to the phone
+ .setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE)
.setDeleteIntent(dismissalPendingIntent)
.setAutoCancel(true);
+
+ if (needFeedbackIds.size() == 1) {
+ // Only 1 session needs feedback
+ Uri sessionUri = ScheduleContract.Sessions.buildSessionUri(needFeedbackIds.get(0));
+ PendingIntent pi = TaskStackBuilder.create(this)
+ .addNextIntent(new Intent(this, MyScheduleActivity.class))
+ .addNextIntent(new Intent(Intent.ACTION_VIEW, sessionUri, this,
+ SessionFeedbackActivity.class))
+ .getPendingIntent(1, PendingIntent.FLAG_CANCEL_CURRENT);
+
+ notifBuilder.setContentTitle(needFeedbackTitles.get(0))
+ .setContentIntent(pi);
+ } else {
+ // Show information about several sessions that need feedback
+ PendingIntent pi = TaskStackBuilder.create(this)
+ .addNextIntent(new Intent(this, MyScheduleActivity.class))
+ .getPendingIntent(1, PendingIntent.FLAG_CANCEL_CURRENT);
+
+ NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
+ inboxStyle.setBigContentTitle(provideFeedbackTicker);
+ for (String title : needFeedbackTitles) {
+ inboxStyle.addLine(title);
+ }
+
+ notifBuilder.setContentTitle(
+ getResources().getQuantityString(R.plurals.session_plurals,
+ needFeedbackIds.size(), needFeedbackIds.size()))
+ .setStyle(inboxStyle)
+ .setContentIntent(pi);
+ }
+
NotificationManager nm = (NotificationManager) getSystemService(
Context.NOTIFICATION_SERVICE);
LOGD(TAG, "Now showing session feedback notification!");
- nm.notify(sessionId, FEEDBACK_NOTIFICATION_ID, notifBuilder.build());
- setupNotificationOnWear(sessionId, sessionRoom, sessionTitle, sessionSpeakers);
+ nm.notify(FEEDBACK_NOTIFICATION_ID, notifBuilder.build());
+
+ for (int i = 0; i < needFeedbackIds.size(); i++) {
+ setupNotificationOnWear(needFeedbackIds.get(i), null, needFeedbackTitles.get(i), null);
+ }
}
/**
@@ -494,11 +509,7 @@
NotificationCompat.Builder notifBuilder = new NotificationCompat.Builder(this)
.setContentTitle(starredSessionTitles.get(0))
.setContentText(contentText)
- //.setColor(getResources().getColor(R.color.theme_primary))
- // Note: setColor() is available in the support lib v21+.
- // We commented it out because we want the source to compile
- // against support lib v20. If you are using support lib
- // v21 or above on Android L, uncomment this line.
+ .setColor(getResources().getColor(R.color.theme_primary))
.setTicker(res.getQuantityString(R.plurals.session_notification_ticker,
starredCount,
starredCount))
@@ -560,8 +571,8 @@
private PendingIntent createRoomMapIntent(final String roomId) {
Intent mapIntent = new Intent(getApplicationContext(),
UIUtils.getMapActivityClass(getApplicationContext()));
- mapIntent.putExtra(MapFragment.EXTRA_ROOM, roomId);
- mapIntent.putExtra(MapActivity.EXTRA_DETACHED_MODE, true);
+ mapIntent.putExtra(BaseMapActivity.EXTRA_ROOM, roomId);
+ mapIntent.putExtra(BaseMapActivity.EXTRA_DETACHED_MODE, true);
return TaskStackBuilder
.create(getApplicationContext())
.addNextIntent(new Intent(this, BrowseSessionsActivity.class))
@@ -596,12 +607,9 @@
// TODO: Should we also check that SESSION_IN_MY_SCHEDULE is true?
final Cursor c = cr.query(ScheduleContract.Sessions.CONTENT_MY_SCHEDULE_URI,
new String[]{
- ScheduleContract.Sessions.SESSION_ID,
ScheduleContract.Sessions.SESSION_TITLE,
ScheduleContract.Sessions.SESSION_END,
ScheduleContract.Sessions.SESSION_IN_MY_SCHEDULE,
- ScheduleContract.Sessions.ROOM_NAME,
- ScheduleContract.Sessions.SESSION_SPEAKER_NAMES,
},
null,
null,
@@ -611,13 +619,9 @@
return;
}
while (c.moveToNext()) {
- final String sessionId = c.getString(0);
- final String sessionTitle = c.getString(1);
- final long sessionEnd = c.getLong(2);
- final String sessionRoom = c.getString(3);
- final String sessionSpeakers = c.getString(4);
- scheduleFeedbackAlarm(sessionId, sessionEnd, UNDEFINED_ALARM_OFFSET, sessionTitle,
- sessionRoom, sessionSpeakers);
+ final String sessionTitle = c.getString(0);
+ final long sessionEnd = c.getLong(1);
+ scheduleFeedbackAlarm(sessionEnd, UNDEFINED_ALARM_OFFSET, sessionTitle);
}
}
@@ -635,16 +639,19 @@
int ROOM_ID = 2;
}
- public interface MySessionsExistenceQuery {
-
+ public interface SessionsNeedingFeedbackQuery {
String[] PROJECTION = {
- ScheduleContract.MySchedule.SESSION_ID
+ ScheduleContract.Sessions.SESSION_ID,
+ ScheduleContract.Sessions.SESSION_TITLE,
+ ScheduleContract.Sessions.SESSION_IN_MY_SCHEDULE,
+ ScheduleContract.Sessions.HAS_GIVEN_FEEDBACK,
};
int SESSION_ID = 0;
+ int SESSION_TITLE = 1;
public static final String WHERE_CLAUSE =
- ScheduleContract.MySchedule.SESSION_ID + "=?";
+ ScheduleContract.Sessions.HAS_GIVEN_FEEDBACK + "=0";
}
@Override
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/BaseActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/BaseActivity.java
index 681503c..ea4f2b8 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/BaseActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/BaseActivity.java
@@ -18,28 +18,50 @@
import android.accounts.Account;
import android.accounts.AccountManager;
-import android.animation.*;
-import android.app.ActionBar;
-import android.app.Activity;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ArgbEvaluator;
+import android.animation.ObjectAnimator;
+import android.animation.TypeEvaluator;
+import android.animation.ValueAnimator;
import android.app.AlertDialog;
-import android.content.*;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SyncStatusObserver;
import android.content.pm.PackageManager;
-import android.content.res.Configuration;
import android.graphics.Color;
+import android.graphics.Rect;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
-import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.provider.Settings;
+import android.support.v4.view.ViewCompat;
import android.support.v4.widget.DrawerLayout;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.ActionBarActivity;
+import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
-import android.view.*;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
-import android.widget.*;
+import android.widget.AbsListView;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
import com.google.android.gcm.GCMRegistrar;
import com.google.android.gms.auth.GoogleAuthUtil;
@@ -53,21 +75,36 @@
import com.google.samples.apps.iosched.sync.SyncHelper;
import com.google.samples.apps.iosched.ui.debug.DebugActionRunnerActivity;
import com.google.samples.apps.iosched.ui.widget.MultiSwipeRefreshLayout;
+import com.google.samples.apps.iosched.ui.widget.ScrimInsetsScrollView;
import com.google.samples.apps.iosched.ui.widget.SwipeRefreshLayout;
-import com.google.samples.apps.iosched.util.*;
+import com.google.samples.apps.iosched.util.AccountUtils;
+import com.google.samples.apps.iosched.util.AnalyticsManager;
+import com.google.samples.apps.iosched.util.HelpUtils;
+import com.google.samples.apps.iosched.util.ImageLoader;
+import com.google.samples.apps.iosched.util.LUtils;
+import com.google.samples.apps.iosched.util.LoginAndAuthHelper;
+import com.google.samples.apps.iosched.util.PlayServicesUtils;
+import com.google.samples.apps.iosched.util.PrefUtils;
+import com.google.samples.apps.iosched.util.RecentTasksStyler;
+import com.google.samples.apps.iosched.util.UIUtils;
+import com.google.samples.apps.iosched.util.WiFiUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import static com.google.samples.apps.iosched.util.LogUtils.*;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGE;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGI;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGW;
+import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
/**
* A base activity that handles common functionality in the app. This includes the
* navigation drawer, login and authentication, Action Bar tweaks, amongst others.
*/
-public abstract class BaseActivity extends Activity implements
+public abstract class BaseActivity extends ActionBarActivity implements
LoginAndAuthHelper.Callbacks,
SharedPreferences.OnSharedPreferenceChangeListener,
MultiSwipeRefreshLayout.CanChildScrollUpCallback {
@@ -78,11 +115,9 @@
// Navigation drawer:
private DrawerLayout mDrawerLayout;
- private LPreviewUtilsBase.ActionBarDrawerToggleWrapper mDrawerToggle;
- // allows access to L-Preview APIs through an abstract interface so we can compile with
- // both the L Preview SDK and with the API 19 SDK
- private LPreviewUtilsBase mLPreviewUtils;
+ // Helper methods for L APIs
+ private LUtils mLUtils;
private ObjectAnimator mStatusBarColorAnimator;
private LinearLayout mAccountListContainer;
@@ -160,6 +195,9 @@
// SwipeRefreshLayout allows the user to swipe the screen down to trigger a manual refresh
private SwipeRefreshLayout mSwipeRefreshLayout;
+ // Primary toolbar and drawer toggle
+ private Toolbar mActionBarToolbar;
+
// asynctask that performs GCM registration in the backgorund
private AsyncTask<Void, Void, Void> mGCMRegisterTask;
@@ -183,6 +221,7 @@
private boolean mManualSyncRequest;
private int mThemedStatusBarColor;
+ private int mNormalStatusBarColor;
private int mProgressBarTopWhenActionBarShown;
private static final TypeEvaluator ARGB_EVALUATOR = new ArgbEvaluator();
private ImageLoader mImageLoader;
@@ -191,6 +230,7 @@
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AnalyticsManager.initializeAnalyticsTracker(getApplicationContext());
+ RecentTasksStyler.styleRecentTasksEntry(this);
PrefUtils.init(this);
@@ -217,13 +257,14 @@
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
sp.registerOnSharedPreferenceChangeListener(this);
- ActionBar ab = getActionBar();
+ ActionBar ab = getSupportActionBar();
if (ab != null) {
ab.setDisplayHomeAsUpEnabled(true);
}
- mLPreviewUtils = LPreviewUtils.getInstance(this);
+ mLUtils = LUtils.getInstance(this);
mThemedStatusBarColor = getResources().getColor(R.color.theme_primary_dark);
+ mNormalStatusBarColor = mThemedStatusBarColor;
}
private void trySetupSwipeRefresh() {
@@ -287,9 +328,12 @@
if (mDrawerLayout == null) {
return;
}
+ mDrawerLayout.setStatusBarBackgroundColor(
+ getResources().getColor(R.color.theme_primary_dark));
+ ScrimInsetsScrollView navDrawer = (ScrimInsetsScrollView)
+ mDrawerLayout.findViewById(R.id.navdrawer);
if (selfItem == NAVDRAWER_ITEM_INVALID) {
// do not show a nav drawer
- View navDrawer = mDrawerLayout.findViewById(R.id.navdrawer);
if (navDrawer != null) {
((ViewGroup) navDrawer.getParent()).removeView(navDrawer);
}
@@ -297,7 +341,37 @@
return;
}
- mDrawerToggle = mLPreviewUtils.setupDrawerToggle(mDrawerLayout, new DrawerLayout.DrawerListener() {
+ if (navDrawer != null) {
+ final View chosenAccountContentView = findViewById(R.id.chosen_account_content_view);
+ final View chosenAccountView = findViewById(R.id.chosen_account_view);
+ final int navDrawerChosenAccountHeight = getResources().getDimensionPixelSize(
+ R.dimen.navdrawer_chosen_account_height);
+ navDrawer.setOnInsetsCallback(new ScrimInsetsScrollView.OnInsetsCallback() {
+ @Override
+ public void onInsetsChanged(Rect insets) {
+ ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams)
+ chosenAccountContentView.getLayoutParams();
+ lp.topMargin = insets.top;
+ chosenAccountContentView.setLayoutParams(lp);
+
+ ViewGroup.LayoutParams lp2 = chosenAccountView.getLayoutParams();
+ lp2.height = navDrawerChosenAccountHeight + insets.top;
+ chosenAccountView.setLayoutParams(lp2);
+ }
+ });
+ }
+
+ if (mActionBarToolbar != null) {
+ mActionBarToolbar.setNavigationIcon(R.drawable.ic_drawer);
+ mActionBarToolbar.setNavigationOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ mDrawerLayout.openDrawer(Gravity.START);
+ }
+ });
+ }
+
+ mDrawerLayout.setDrawerListener(new DrawerLayout.DrawerListener() {
@Override
public void onDrawerClosed(View drawerView) {
// run deferred action, if we have one
@@ -309,40 +383,30 @@
mAccountBoxExpanded = false;
setupAccountBoxToggle();
}
- invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
- updateStatusBarForNavDrawerSlide(0f);
onNavDrawerStateChanged(false, false);
}
@Override
public void onDrawerOpened(View drawerView) {
- invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
- updateStatusBarForNavDrawerSlide(1f);
onNavDrawerStateChanged(true, false);
}
@Override
public void onDrawerStateChanged(int newState) {
- invalidateOptionsMenu();
onNavDrawerStateChanged(isNavDrawerOpen(), newState != DrawerLayout.STATE_IDLE);
}
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
- updateStatusBarForNavDrawerSlide(slideOffset);
onNavDrawerSlide(slideOffset);
}
});
- mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, Gravity.START);
- getActionBar().setDisplayHomeAsUpEnabled(true);
- getActionBar().setHomeButtonEnabled(true);
+ mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, Gravity.START);
// populate the nav drawer with the correct items
populateNavDrawer();
- mDrawerToggle.syncState();
-
// When the user runs the app for the first time, we want to land them with the
// navigation drawer open. But just the first time.
if (!PrefUtils.isWelcomeDone(this)) {
@@ -352,6 +416,12 @@
}
}
+ @Override
+ public void setContentView(int layoutResID) {
+ super.setContentView(layoutResID);
+ getActionBarToolbar();
+ }
+
// Subclasses can override this for custom behavior
protected void onNavDrawerStateChanged(boolean isOpen, boolean isAnimating) {
if (mActionBarAutoHideEnabled && isOpen) {
@@ -507,6 +577,7 @@
if (name == null) {
nameTextView.setVisibility(View.GONE);
} else {
+ nameTextView.setVisibility(View.VISIBLE);
nameTextView.setText(name);
}
@@ -557,6 +628,11 @@
((TextView) itemView.findViewById(R.id.profile_email_text))
.setText(account.name);
final String accountName = account.name;
+ String imageUrl = AccountUtils.getPlusImageUrl(this, accountName);
+ if (!TextUtils.isEmpty(imageUrl)) {
+ mImageLoader.loadImage(imageUrl,
+ (ImageView) itemView.findViewById(R.id.profile_image));
+ }
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
@@ -654,25 +730,8 @@
}
@Override
- public void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- if (mDrawerToggle != null) {
- mDrawerToggle.onConfigurationChanged(newConfig);
- }
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- return super.onCreateOptionsMenu(menu);
- }
-
- @Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
- if (mDrawerToggle != null && mDrawerToggle.onOptionsItemSelected(item)) {
- return true;
- }
-
switch (id) {
case R.id.menu_about:
HelpUtils.showAbout(this);
@@ -1185,13 +1244,22 @@
autoShowOrHideActionBar(shouldShow);
}
+ protected Toolbar getActionBarToolbar() {
+ if (mActionBarToolbar == null) {
+ mActionBarToolbar = (Toolbar) findViewById(R.id.toolbar_actionbar);
+ if (mActionBarToolbar != null) {
+ setSupportActionBar(mActionBarToolbar);
+ }
+ }
+ return mActionBarToolbar;
+ }
+
protected void autoShowOrHideActionBar(boolean show) {
if (show == mActionBarShown) {
return;
}
mActionBarShown = show;
- getLPreviewUtils().showHideActionBarIfPartOfDecor(show);
onActionBarAutoShowOrHide(show);
}
@@ -1413,30 +1481,39 @@
}
}
- public LPreviewUtilsBase getLPreviewUtils() {
- return mLPreviewUtils;
+ public LUtils getLUtils() {
+ return mLUtils;
}
- private void updateStatusBarForNavDrawerSlide(float slideOffset) {
- if (mStatusBarColorAnimator != null) {
- mStatusBarColorAnimator.cancel();
- }
+ public int getThemedStatusBarColor() {
+ return mThemedStatusBarColor;
+ }
- if (!mActionBarShown) {
- mLPreviewUtils.setStatusBarColor(Color.BLACK);
- return;
+ public void setNormalStatusBarColor(int color) {
+ mNormalStatusBarColor = color;
+ if (mDrawerLayout != null) {
+ mDrawerLayout.setStatusBarBackgroundColor(mNormalStatusBarColor);
}
-
- mLPreviewUtils.setStatusBarColor((Integer) ARGB_EVALUATOR.evaluate(slideOffset,
- mThemedStatusBarColor, Color.BLACK));
}
protected void onActionBarAutoShowOrHide(boolean shown) {
if (mStatusBarColorAnimator != null) {
mStatusBarColorAnimator.cancel();
}
- mStatusBarColorAnimator = ObjectAnimator.ofInt(mLPreviewUtils, "statusBarColor",
- shown ? mThemedStatusBarColor : Color.BLACK).setDuration(250);
+ mStatusBarColorAnimator = ObjectAnimator.ofInt(
+ (mDrawerLayout != null) ? mDrawerLayout : mLUtils,
+ (mDrawerLayout != null) ? "statusBarBackgroundColor" : "statusBarColor",
+ shown ? Color.BLACK : mNormalStatusBarColor,
+ shown ? mNormalStatusBarColor : Color.BLACK)
+ .setDuration(250);
+ if (mDrawerLayout != null) {
+ mStatusBarColorAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator valueAnimator) {
+ ViewCompat.postInvalidateOnAnimation(mDrawerLayout);
+ }
+ });
+ }
mStatusBarColorAnimator.setEvaluator(ARGB_EVALUATOR);
mStatusBarColorAnimator.start();
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/NearbyActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/BaseMapActivity.java
similarity index 70%
rename from android/src/main/java/com/google/samples/apps/iosched/ui/NearbyActivity.java
rename to android/src/main/java/com/google/samples/apps/iosched/ui/BaseMapActivity.java
index 7affcc6..89edd17 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/NearbyActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/BaseMapActivity.java
@@ -25,16 +25,20 @@
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.DataSetObserver;
+import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
+import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.Button;
import com.google.samples.apps.iosched.R;
import com.google.samples.apps.iosched.nearby.MetadataResolver;
import com.google.samples.apps.iosched.nearby.NearbyDeviceManager;
+import com.google.samples.apps.iosched.ui.widget.ScrimInsetsFrameLayout;
import com.google.samples.apps.iosched.util.PrefUtils;
import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
@@ -47,16 +51,27 @@
*
* This activity requires API level 18 because it utilizes BLE.
*/
-public abstract class NearbyActivity extends BaseActivity implements NearbyFragment.Callbacks {
- private static final String TAG = makeLogTag(NearbyActivity.class);
+public abstract class BaseMapActivity extends BaseActivity implements NearbyFragment.Callbacks, ScrimInsetsFrameLayout.OnInsetsCallback {
+ private static final String TAG = makeLogTag(BaseMapActivity.class);
private static final int REQUEST_ENABLE_BT = 500;
private static final int REQUEST_ENABLE_NEARBY = 501;
protected static final String NEARBY_FRAGMENT_TAG = "NEARBY_FRAGMENT";
+ /**
+ * When specified, will automatically point the map to the requested room.
+ */
+ public static final String EXTRA_ROOM = "com.google.android.iosched.extra.ROOM";
+
+ public static final String EXTRA_DETACHED_MODE
+ = "com.google.samples.apps.iosched.EXTRA_DETACHED_MODE";
+
private boolean mNearbyCapable = false;
private boolean mShouldShowNearbyFragment = false;
private NearbyDeviceManager mDeviceManager;
private Button mNearbyButton;
+ private boolean mDetachedMode;
+
+ protected MapFragment mMapFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -66,6 +81,58 @@
&& PrefUtils.isAttendeeAtVenue(this)) {
mNearbyCapable = initNearby();
}
+
+ FragmentManager fm = getFragmentManager();
+ mMapFragment = (MapFragment) fm.findFragmentByTag("map");
+
+ mDetachedMode = getIntent().getBooleanExtra(EXTRA_DETACHED_MODE, false);
+ }
+
+ @Override
+ protected void onPostCreate(Bundle savedInstanceState) {
+ super.onPostCreate(savedInstanceState);
+ if (mDetachedMode) {
+ final Toolbar toolbar = getActionBarToolbar();
+ toolbar.setNavigationIcon(R.drawable.ic_up);
+ toolbar.setNavigationOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ finish();
+ }
+ });
+ }
+
+ if (mMapFragment == null) {
+ mMapFragment = MapFragment.newInstance();
+ mMapFragment.setArguments(intentToFragmentArguments(getIntent()));
+ getFragmentManager().beginTransaction()
+ .add(R.id.fragment_container_map, mMapFragment, "map")
+ .commit();
+ }
+
+ mDetachedMode = getIntent().getBooleanExtra(EXTRA_DETACHED_MODE, false);
+
+ ScrimInsetsFrameLayout scrimInsetsFrameLayout = (ScrimInsetsFrameLayout)
+ findViewById(R.id.capture_insets_frame_layout);
+ scrimInsetsFrameLayout.setOnInsetsCallback(this);
+ }
+
+ @Override
+ public void onInsetsChanged(Rect insets) {
+ Toolbar toolbar = getActionBarToolbar();
+ ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams)
+ toolbar.getLayoutParams();
+ lp.topMargin = insets.top;
+ int top = insets.top;
+ insets.top += getActionBarToolbar().getHeight();
+ toolbar.setLayoutParams(lp);
+ mMapFragment.setMapInsets(insets);
+ insets.top = top; // revert
+ }
+
+ @Override
+ protected int getSelfNavDrawerItem() {
+ return mDetachedMode ? NAVDRAWER_ITEM_INVALID : NAVDRAWER_ITEM_MAP;
}
@Override
@@ -120,6 +187,15 @@
return super.onCreateOptionsMenu(menu);
}
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (getIntent().getBooleanExtra(EXTRA_DETACHED_MODE, false)
+ && item.getItemId() == android.R.id.home) {
+ finish();
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
protected abstract void showNearbyFragment(String tag);
// Handles a click on the Nearby menu item. Recognizes several states:
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/BrowseSessionsActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/BrowseSessionsActivity.java
index adb7647..b687c82 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/BrowseSessionsActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/BrowseSessionsActivity.java
@@ -16,14 +16,19 @@
package com.google.samples.apps.iosched.ui;
-import android.app.ActionBar;
import android.content.Intent;
import android.graphics.Paint;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.os.Bundle;
+import android.support.v7.app.ActionBar;
+import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
-import android.view.*;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Spinner;
@@ -78,20 +83,20 @@
// time when the user last clicked "refresh" from the stale data butter bar
private long mLastDataStaleUserActionTime = 0L;
+ private int mHeaderColor = 0; // 0 means not customized
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_browse_sessions);
- getLPreviewUtils().trySetActionBar();
- ActionBar ab = getActionBar();
+ Toolbar toolbar = getActionBarToolbar();
long[] interval = ScheduleContract.Sessions.getInterval(getIntent().getData());
if (interval != null) {
String title = UIUtils.formatIntervalTimeString(interval[0], interval[1], null, this);
- ab.setTitle(title);
+ toolbar.setTitle(title);
mMode = MODE_TIME_FIT;
/* [ANALYTICS:SCREEN]
* TRIGGER: View the Explore screen to find sessions fitting a time slot
@@ -121,8 +126,7 @@
if (mMode == MODE_EXPLORE) {
// no title (to make more room for navigation and actions)
// unless Nav Drawer opens
- ab.setTitle(getString(R.string.app_name));
- ab.setDisplayShowTitleEnabled(false);
+ toolbar.setTitle(null);
}
mButterBar = findViewById(R.id.butter_bar);
@@ -201,12 +205,6 @@
}
@Override
- public void onStart() {
- super.onStart();
- updateActionBarNavigation();
- }
-
- @Override
public void onTagMetadataLoaded(TagMetadata metadata) {
mTagMetadata = metadata;
if (mSpinnerConfigured) {
@@ -221,8 +219,8 @@
}
private void trySetUpActionBarSpinner() {
- ActionBar ab = getActionBar();
- if (mMode != MODE_EXPLORE || mSpinnerConfigured || mTagMetadata == null || ab == null) {
+ Toolbar toolbar = getActionBarToolbar();
+ if (mMode != MODE_EXPLORE || mSpinnerConfigured || mTagMetadata == null || toolbar == null) {
// already done it, or not ready yet, or don't need to do
LOGD(TAG, "Not configuring Action Bar spinner.");
return;
@@ -246,8 +244,8 @@
mTopLevelSpinnerAdapter.addHeader(categoryTitle);
for (TagMetadata.Tag tag : mTagMetadata.getTagsInCategory(category)) {
LOGD(TAG, "Adding item to spinner: " + tag.getId() + " --> " + tag.getName());
- mTopLevelSpinnerAdapter.addItem(tag.getId(), tag.getName(), true,
- Config.Tags.CATEGORY_TOPIC.equals(category) ? tag.getColor() : 0);
+ int tagColor = Config.Tags.CATEGORY_TOPIC.equals(category) ? tag.getColor() : 0;
+ mTopLevelSpinnerAdapter.addItem(tag.getId(), tag.getName(), true, tagColor);
if (!TextUtils.isEmpty(mFilterTagsToRestore[0]) && tag.getId().equals(mFilterTagsToRestore[0])) {
mFilterTagsToRestore[0] = null;
itemToSelect = mTopLevelSpinnerAdapter.getCount() - 1;
@@ -259,11 +257,11 @@
}
mFilterTagsToRestore[0] = null;
- View spinnerContainer = LayoutInflater.from(getActionBar().getThemedContext())
- .inflate(R.layout.actionbar_spinner, null);
+ View spinnerContainer = LayoutInflater.from(this).inflate(R.layout.actionbar_spinner,
+ toolbar, false);
ActionBar.LayoutParams lp = new ActionBar.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
- ab.setCustomView(spinnerContainer, lp);
+ toolbar.addView(spinnerContainer, lp);
Spinner spinner = (Spinner) spinnerContainer.findViewById(R.id.actionbar_spinner);
spinner.setAdapter(mTopLevelSpinnerAdapter);
@@ -282,33 +280,28 @@
spinner.setSelection(itemToSelect);
}
+ updateHeaderColor();
showSecondaryFilters();
- updateActionBarNavigation();
}
- private void updateActionBarNavigation() {
- boolean show = mSpinnerConfigured && !isNavDrawerOpen();
-
- ActionBar ab = getActionBar();
- if (mMode == MODE_TIME_FIT) {
- ab.setDisplayShowCustomEnabled(false);
- ab.setDisplayShowTitleEnabled(true);
- ab.setDisplayUseLogoEnabled(false);
- } else if (show) {
- ab.setDisplayShowCustomEnabled(true);
- ab.setDisplayShowTitleEnabled(false);
- ab.setDisplayUseLogoEnabled(false);
- } else if (getLPreviewUtils().shouldChangeActionBarForDrawer()) {
- ab.setDisplayShowCustomEnabled(false);
- ab.setDisplayShowTitleEnabled(false);
- ab.setDisplayUseLogoEnabled(true);
+ private void updateHeaderColor() {
+ mHeaderColor = 0;
+ for (String tag : mFilterTags) {
+ if (tag != null) {
+ TagMetadata.Tag tagObj = mTagMetadata.getTag(tag);
+ if (tagObj != null && Config.Tags.CATEGORY_TOPIC.equals(tagObj.getCategory())) {
+ mHeaderColor = tagObj.getColor();
+ }
+ }
}
- }
-
- @Override
- protected void onNavDrawerStateChanged(boolean isOpen, boolean isAnimating) {
- super.onNavDrawerStateChanged(isOpen, isAnimating);
- updateActionBarNavigation();
+ findViewById(R.id.headerbar).setBackgroundColor(
+ mHeaderColor == 0
+ ? getResources().getColor(R.color.theme_primary)
+ : mHeaderColor);
+ setNormalStatusBarColor(
+ mHeaderColor == 0
+ ? getThemedStatusBarColor()
+ : UIUtils.scaleColor(mHeaderColor, 0.8f, false));
}
private void onTopLevelTagSelected(String tag) {
@@ -323,6 +316,7 @@
// nothing to do
return;
}
+
/* [ANALYTICS:EVENT]
* TRIGGER: Select a top-level filter on the Explore screen.
* CATEGORY: 'Explore'
@@ -339,6 +333,7 @@
}
showSecondaryFilters();
+ updateHeaderColor();
reloadFromFilters();
}
@@ -412,7 +407,7 @@
Bundle args = BaseActivity.intentToFragmentArguments(
new Intent(Intent.ACTION_VIEW, ScheduleContract.Sessions.buildTagFilterUri(
mFilterTags))
- );
+ .putExtra(SessionsFragment.EXTRA_NO_TRACK_BRANDING, mHeaderColor != 0));
frag.reloadFromArguments(args);
frag.animateReload();
@@ -467,6 +462,7 @@
* [/ANALYTICS]
*/
AnalyticsManager.sendEvent(SCREEN_LABEL, "secondaryfilter", tag);
+ updateHeaderColor();
reloadFromFilters();
}
}
@@ -489,11 +485,6 @@
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
- if (getLPreviewUtils().shouldChangeActionBarForDrawer() && isNavDrawerOpen()) {
- // nothing to show if nav drawer is open or animating
- return true;
- }
-
getMenuInflater().inflate(R.menu.browse_sessions, menu);
// remove actions when in time interval mode:
if (mMode != MODE_EXPLORE) {
@@ -536,12 +527,10 @@
* [/ANALYTICS]
*/
AnalyticsManager.sendEvent(SCREEN_LABEL, "selectsession", sessionId);
- getLPreviewUtils().startActivityWithTransition(
- new Intent(Intent.ACTION_VIEW,
+ getLUtils().startActivityWithTransition(new Intent(Intent.ACTION_VIEW,
ScheduleContract.Sessions.buildSessionUri(sessionId)),
clickedView,
- SessionDetailFragment.VIEW_NAME_PHOTO
- );
+ SessionDetailActivity.TRANSITION_NAME_PHOTO);
}
@Override
@@ -621,7 +610,7 @@
TextView headerTextView = (TextView) view.findViewById(R.id.header_text);
View dividerView = view.findViewById(R.id.divider_view);
- TextView normalTextView = (TextView) view.findViewById(R.id.normal_text);
+ TextView normalTextView = (TextView) view.findViewById(android.R.id.text1);
if (isHeader(position)) {
headerTextView.setText(getTitle(position));
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/ExpertsDirectoryActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/ExpertsDirectoryActivity.java
index c045ab7..897f93f 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/ExpertsDirectoryActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/ExpertsDirectoryActivity.java
@@ -73,7 +73,6 @@
}
setContentView(R.layout.activity_experts_directory);
- getLPreviewUtils().trySetActionBar();
AnalyticsManager.sendScreenView(SCREEN_LABEL);
mDrawShadowFrameLayout = (DrawShadowFrameLayout) findViewById(R.id.main_content);
@@ -107,15 +106,6 @@
}
}
- private void updateActionBarNavigation() {
- boolean show = !isNavDrawerOpen();
- if (getLPreviewUtils().shouldChangeActionBarForDrawer()) {
- ActionBar ab = getActionBar();
- ab.setDisplayShowTitleEnabled(show);
- ab.setDisplayUseLogoEnabled(!show);
- }
- }
-
@Override
protected void onActionBarAutoShowOrHide(boolean shown) {
super.onActionBarAutoShowOrHide(shown);
@@ -123,12 +113,6 @@
}
@Override
- protected void onNavDrawerStateChanged(boolean isOpen, boolean isAnimating) {
- super.onNavDrawerStateChanged(isOpen, isAnimating);
- updateActionBarNavigation();
- }
-
- @Override
protected int getSelfNavDrawerItem() {
return NAVDRAWER_ITEM_EXPERTS_DIRECTORY;
}
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/MapFragment.java b/android/src/main/java/com/google/samples/apps/iosched/ui/MapFragment.java
index 14d1790..a24b540 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/MapFragment.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/MapFragment.java
@@ -16,26 +16,24 @@
package com.google.samples.apps.iosched.ui;
-import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
-import static com.google.samples.apps.iosched.util.LogUtils.LOGE;
-import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
-
import android.annotation.SuppressLint;
import android.app.Activity;
-import android.app.DialogFragment;
-import android.content.*;
+import android.app.LoaderManager;
+import android.app.LoaderManager.LoaderCallbacks;
+import android.content.AsyncQueryHandler;
+import android.content.ContentResolver;
+import android.content.CursorLoader;
+import android.content.Loader;
+import android.content.SharedPreferences;
import android.database.ContentObserver;
import android.database.Cursor;
import android.graphics.Point;
+import android.graphics.Rect;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
-import android.app.LoaderManager;
-import android.app.LoaderManager.LoaderCallbacks;
-import android.content.CursorLoader;
-import android.content.Loader;
import android.text.format.DateUtils;
import android.util.SparseArray;
import android.view.LayoutInflater;
@@ -45,15 +43,25 @@
import android.widget.FrameLayout;
import com.google.android.gms.maps.CameraUpdate;
-import com.google.samples.apps.iosched.R;
-import com.google.samples.apps.iosched.provider.ScheduleContract;
-import com.google.samples.apps.iosched.util.*;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.Projection;
-import com.google.android.gms.maps.model.*;
+import com.google.android.gms.maps.model.CameraPosition;
+import com.google.android.gms.maps.model.IndoorBuilding;
+import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
+import com.google.android.gms.maps.model.MarkerOptions;
+import com.google.android.gms.maps.model.TileOverlay;
+import com.google.android.gms.maps.model.TileOverlayOptions;
+import com.google.android.gms.maps.model.TileProvider;
import com.google.maps.android.ui.IconGenerator;
+import com.google.samples.apps.iosched.R;
+import com.google.samples.apps.iosched.provider.ScheduleContract;
+import com.google.samples.apps.iosched.util.AnalyticsManager;
+import com.google.samples.apps.iosched.util.MapUtils;
+import com.google.samples.apps.iosched.util.PrefUtils;
+import com.google.samples.apps.iosched.util.UIUtils;
+import com.jakewharton.disklrucache.DiskLruCache;
import java.io.File;
import java.io.IOException;
@@ -62,7 +70,8 @@
import java.util.HashMap;
import java.util.Locale;
-import com.jakewharton.disklrucache.DiskLruCache;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
+import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
/**
* Shows a map of the conference venue.
@@ -87,12 +96,6 @@
// Default level (index of level in IndoorBuilding object for Moscone)
private static final int MOSCONE_DEFAULT_LEVEL_INDEX = 1;
-
- /**
- * When specified, will automatically point the map to the requested room.
- */
- public static final String EXTRA_ROOM = "com.google.android.iosched.extra.ROOM";
-
private static final String TAG = makeLogTag(MapFragment.class);
// Marker types
@@ -144,6 +147,7 @@
private Marker mMosconeMaker = null;
private GoogleMap mMap;
+ private Rect mMapInsets = new Rect();
private MapInfoWindowAdapter mInfoAdapter;
@@ -243,8 +247,7 @@
setupMap(true);
}
-
- mMap.setPadding(0, UIUtils.calculateActionBarSize(getActivity()), 0, 0);
+ setMapInsets(mMapInsets);
// load all markers
LoaderManager lm = getLoaderManager();
@@ -256,6 +259,13 @@
return v;
}
+ public void setMapInsets(Rect insets) {
+ mMapInsets.set(insets);
+ if (mMap != null) {
+ mMap.setPadding(mMapInsets.left, mMapInsets.top, mMapInsets.right, mMapInsets.bottom);
+ }
+ }
+
@Override
public void onStart() {
super.onStart();
@@ -319,8 +329,8 @@
mMap.setMyLocationEnabled(false);
Bundle data = getArguments();
- if (data != null && data.containsKey(EXTRA_ROOM)) {
- mHighlightedRoom = data.getString(EXTRA_ROOM);
+ if (data != null && data.containsKey(BaseMapActivity.EXTRA_ROOM)) {
+ mHighlightedRoom = data.getString(BaseMapActivity.EXTRA_ROOM);
}
LOGD(TAG, "Map setup complete.");
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/MyScheduleActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/MyScheduleActivity.java
index 6e1a06d..de96869 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/MyScheduleActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/MyScheduleActivity.java
@@ -16,7 +16,6 @@
package com.google.samples.apps.iosched.ui;
-import android.app.ActionBar;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.ListFragment;
@@ -127,7 +126,6 @@
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_schedule);
- getLPreviewUtils().trySetActionBar();
/* [ANALYTICS:SCREEN]
* TRIGGER: View the My Schedule screen.
@@ -142,7 +140,7 @@
int i;
for (i = 0; i < Config.CONFERENCE_DAYS.length; i++) {
- mScheduleAdapters[i] = new MyScheduleAdapter(this, getLPreviewUtils());
+ mScheduleAdapters[i] = new MyScheduleAdapter(this, getLUtils());
}
mViewPagerAdapter = new OurViewPagerAdapter(getFragmentManager());
@@ -224,21 +222,6 @@
getResources().getDisplayMetrics()));
}
- private void updateActionBarNavigation() {
- boolean show = !isNavDrawerOpen();
- if (getLPreviewUtils().shouldChangeActionBarForDrawer()) {
- ActionBar ab = getActionBar();
- ab.setDisplayShowTitleEnabled(show);
- ab.setDisplayUseLogoEnabled(!show);
- }
- }
-
- @Override
- protected void onNavDrawerStateChanged(boolean isOpen, boolean isAnimating) {
- super.onNavDrawerStateChanged(isOpen, isAnimating);
- updateActionBarNavigation();
- }
-
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
@@ -431,12 +414,6 @@
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
-
- if (getLPreviewUtils().shouldChangeActionBarForDrawer() && isNavDrawerOpen()) {
- // nothing to show if nav drawer is open or animating
- return true;
- }
-
getMenuInflater().inflate(R.menu.my_schedule, menu);
configureStandardMenuItems(menu);
return true;
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/MyScheduleAdapter.java b/android/src/main/java/com/google/samples/apps/iosched/ui/MyScheduleAdapter.java
index fd515fe..167ab88 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/MyScheduleAdapter.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/MyScheduleAdapter.java
@@ -21,6 +21,7 @@
import android.content.res.Resources;
import android.database.DataSetObserver;
import android.graphics.Color;
+import android.graphics.ColorFilter;
import android.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
@@ -52,7 +53,7 @@
private static final int VIEW_TYPE_PAST_DURING_CONFERENCE = 2;
private final Context mContext;
- private final LPreviewUtilsBase mLPreviewUtils;
+ private final LUtils mLUtils;
// additional top padding to add to first item of list
int mContentTopClearance = 0;
@@ -74,9 +75,9 @@
// the data and thus shouldn't be used
int mDataGeneration = 0;
- public MyScheduleAdapter(Context context, LPreviewUtilsBase lPreviewUtils) {
+ public MyScheduleAdapter(Context context, LUtils lUtils) {
mContext = context;
- mLPreviewUtils = lPreviewUtils;
+ mLUtils = lUtils;
mDefaultSessionColor = mContext.getResources().getColor(R.color.default_session_color);
mDefaultStartTimeColor = mContext.getResources().getColor(R.color.body_text_2);
@@ -333,14 +334,13 @@
final ColorDrawable colorDrawable = new ColorDrawable(color);
bgImageView.setImageDrawable(colorDrawable);
- bgImageView.setColorFilter(UIUtils.setColorAlpha(color,
- UIUtils.SESSION_PHOTO_SCRIM_ALPHA));
+ ColorFilter scrimFilter = UIUtils.makeSessionImageScrimColorFilter(color);
+ bgImageView.setColorFilter(scrimFilter);
if (TextUtils.isEmpty(item.backgroundImageUrl)) {
sessionImageView.setVisibility(View.GONE);
} else {
- sessionImageView.setColorFilter(UIUtils.setColorAlpha(color,
- UIUtils.SESSION_PHOTO_SCRIM_ALPHA));
+ sessionImageView.setColorFilter(scrimFilter);
mImageLoader.loadImage(item.backgroundImageUrl, sessionImageView, null,
colorDrawable);
}
@@ -348,7 +348,7 @@
slotTitleView.setTextColor(isBlockNow
? Color.WHITE
: res.getColor(R.color.body_text_1_inverse));
- mLPreviewUtils.setMediumTypeface(slotTitleView);
+ mLUtils.setMediumTypeface(slotTitleView);
if (slotSubtitleView != null) {
slotSubtitleView.setText(item.subtitle);
slotSubtitleView.setTextColor(res.getColor(R.color.body_text_2_inverse));
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/NearbyFragment.java b/android/src/main/java/com/google/samples/apps/iosched/ui/NearbyFragment.java
index 730b000..fc0fa97 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/NearbyFragment.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/NearbyFragment.java
@@ -51,9 +51,6 @@
View rootView = inflater.inflate(R.layout.fragment_nearby, container, false);
if (getArguments() != null && !getArguments().getBoolean(ARG_HAS_HEADER, true)) {
rootView.findViewById(R.id.headerbar).setVisibility(View.GONE);
- } else {
- ((FrameLayout) rootView.findViewById(R.id.list_container))
- .setForeground(getResources().getDrawable(R.drawable.bottom_shadow));
}
Callbacks parentActivity = (Callbacks) getActivity();
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/PartnersFragment.java b/android/src/main/java/com/google/samples/apps/iosched/ui/PartnersFragment.java
index 7309ac8..222ba53 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/PartnersFragment.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/PartnersFragment.java
@@ -75,9 +75,6 @@
View rootView = inflater.inflate(R.layout.fragment_partners, container, false);
if (getArguments() != null && !getArguments().getBoolean(ARG_HAS_HEADER, true)) {
rootView.findViewById(R.id.headerbar).setVisibility(View.GONE);
- } else {
- ((FrameLayout) rootView.findViewById(R.id.list_container))
- .setForeground(getResources().getDrawable(R.drawable.bottom_shadow));
}
rootView.findViewById(R.id.close_button).setOnClickListener(new View.OnClickListener() {
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/PeopleIveMetActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/PeopleIveMetActivity.java
index 2ca6ced..6f520d6 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/PeopleIveMetActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/PeopleIveMetActivity.java
@@ -16,16 +16,12 @@
package com.google.samples.apps.iosched.ui;
-import android.app.ActionBar;
-import android.content.*;
+import android.content.Intent;
import android.os.Bundle;
import com.google.samples.apps.iosched.R;
import com.google.samples.apps.iosched.util.PrefUtils;
-import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
-import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
-
public class PeopleIveMetActivity extends BaseActivity {
private static final String FRAGMENT_PEOPLE_IVE_MET = "people_ive_met";
@@ -39,7 +35,6 @@
}
setContentView(R.layout.activity_people_ive_met);
- getLPreviewUtils().trySetActionBar();
if (null == savedInstanceState) {
getFragmentManager().beginTransaction()
@@ -48,25 +43,9 @@
.commit();
}
- setTitle(R.string.title_people_ive_met);
overridePendingTransition(0, 0);
}
- private void updateActionBarNavigation() {
- boolean show = !isNavDrawerOpen();
- if (getLPreviewUtils().shouldChangeActionBarForDrawer()) {
- ActionBar ab = getActionBar();
- ab.setDisplayShowTitleEnabled(show);
- ab.setDisplayUseLogoEnabled(!show);
- }
- }
-
- @Override
- protected void onNavDrawerStateChanged(boolean isOpen, boolean isAnimating) {
- super.onNavDrawerStateChanged(isOpen, isAnimating);
- updateActionBarNavigation();
- }
-
@Override
protected int getSelfNavDrawerItem() {
return NAVDRAWER_ITEM_PEOPLE_IVE_MET;
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/SearchActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/SearchActivity.java
index 0eefe50..645a679 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/SearchActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/SearchActivity.java
@@ -17,14 +17,17 @@
import android.app.FragmentManager;
import android.app.SearchManager;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
+import android.support.v4.content.IntentCompat;
+import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
-import android.widget.SearchView;
+import android.support.v7.widget.SearchView;
import com.google.samples.apps.iosched.R;
import com.google.samples.apps.iosched.model.TagMetadata;
@@ -48,6 +51,19 @@
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
+
+ Toolbar toolbar = getActionBarToolbar();
+ toolbar.setTitle(R.string.title_search);
+ toolbar.setNavigationIcon(R.drawable.ic_up);
+ toolbar.setNavigationOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ navigateUpToFromChild(SearchActivity.this,
+ IntentCompat.makeMainActivity(new ComponentName(SearchActivity.this,
+ BrowseSessionsActivity.class)));
+ }
+ });
+
FragmentManager fm = getFragmentManager();
mSessionsFragment = (SessionsFragment) fm.findFragmentById(R.id.fragment_container);
@@ -80,11 +96,11 @@
* [/ANALYTICS]
*/
AnalyticsManager.sendEvent(SCREEN_LABEL, "selectsession", sessionId);
- getLPreviewUtils().startActivityWithTransition(
+ getLUtils().startActivityWithTransition(
new Intent(Intent.ACTION_VIEW,
ScheduleContract.Sessions.buildSessionUri(sessionId)),
clickedView,
- SessionDetailFragment.VIEW_NAME_PHOTO);
+ SessionDetailActivity.TRANSITION_NAME_PHOTO);
}
@Override
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/SessionDetailActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/SessionDetailActivity.java
index f3f64e6..1a07743 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/SessionDetailActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/SessionDetailActivity.java
@@ -16,47 +16,279 @@
package com.google.samples.apps.iosched.ui;
-import android.app.Fragment;
+import android.app.LoaderManager;
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.CursorLoader;
import android.content.Intent;
+import android.content.Loader;
import android.content.res.Resources;
+import android.database.Cursor;
+import android.graphics.Paint;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.OvalShape;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
+import android.os.Handler;
+import android.support.v4.view.ViewCompat;
+import android.support.v7.widget.Toolbar;
+import android.text.TextUtils;
+import android.util.Pair;
import android.util.TypedValue;
+import android.view.LayoutInflater;
+import android.view.Menu;
import android.view.MenuItem;
-import android.view.Window;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
import android.view.WindowManager;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import com.bumptech.glide.request.bitmap.RequestListener;
+import com.bumptech.glide.request.target.Target;
+import com.google.android.gms.plus.PlusOneButton;
+import com.google.android.youtube.player.YouTubeIntents;
+import com.google.samples.apps.iosched.Config;
import com.google.samples.apps.iosched.R;
+import com.google.samples.apps.iosched.model.TagMetadata;
+import com.google.samples.apps.iosched.provider.ScheduleContract;
+import com.google.samples.apps.iosched.service.SessionAlarmService;
+import com.google.samples.apps.iosched.service.SessionCalendarService;
+import com.google.samples.apps.iosched.ui.widget.CheckableFrameLayout;
+import com.google.samples.apps.iosched.ui.widget.MessageCardView;
+import com.google.samples.apps.iosched.ui.widget.ObservableScrollView;
+import com.google.samples.apps.iosched.util.AccountUtils;
+import com.google.samples.apps.iosched.util.AnalyticsManager;
import com.google.samples.apps.iosched.util.BeamUtils;
+import com.google.samples.apps.iosched.util.ImageLoader;
+import com.google.samples.apps.iosched.util.LogUtils;
+import com.google.samples.apps.iosched.util.SessionsHelper;
+import com.google.samples.apps.iosched.util.TimeUtils;
import com.google.samples.apps.iosched.util.UIUtils;
-public class SessionDetailActivity extends SimpleSinglePaneActivity {
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+
+import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
+
+/**
+ * An activity that shows detail information for a session, including session title, abstract,
+ * time information, speaker photos and bios, etc.
+ */
+public class SessionDetailActivity extends BaseActivity implements
+ LoaderManager.LoaderCallbacks<Cursor>,
+ ObservableScrollView.Callbacks {
+ private static final String TAG = LogUtils.makeLogTag(SessionDetailActivity.class);
+
+ private static final int[] SECTION_HEADER_RES_IDS = {
+ R.id.session_links_header,
+ R.id.session_speakers_header,
+ R.id.session_requirements_header,
+ R.id.related_videos_header,
+ };
+ private static final float PHOTO_ASPECT_RATIO = 1.7777777f;
+
+ public static final String TRANSITION_NAME_PHOTO = "photo";
+
+ private Handler mHandler = new Handler();
+ private static final int TIME_HINT_UPDATE_INTERVAL = 10000; // 10 sec
+
+ private TagMetadata mTagMetadata;
+
+ private String mSessionId;
+ private Uri mSessionUri;
+
+ private long mSessionStart;
+ private long mSessionEnd;
+ private String mTitleString;
+ private String mHashTag;
+ private String mUrl;
+ private String mRoomId;
+ private String mRoomName;
+ private String mTagsString;
+
+ // A comma-separated list of speakers to be passed to Android Wear
+ private String mSpeakers;
+
+ private boolean mStarred;
+ private boolean mInitStarred;
+ private boolean mDismissedWatchLivestreamCard = false;
+ private boolean mHasLivestream = false;
+ private MenuItem mSocialStreamMenuItem;
+ private MenuItem mShareMenuItem;
+
+ private View mScrollViewChild;
+ private TextView mTitle;
+ private TextView mSubtitle;
+ private PlusOneButton mPlusOneButton;
+
+ private ObservableScrollView mScrollView;
+ private CheckableFrameLayout mAddScheduleButton;
+
+ private TextView mAbstract;
+ private LinearLayout mTags;
+ private ViewGroup mTagsContainer;
+ private TextView mRequirements;
+ private View mHeaderBox;
+ private View mDetailsContainer;
+
+ private boolean mSessionCursor = false;
+ private boolean mSpeakersCursor = false;
+ private boolean mHasSummaryContent = false;
+
+ private ImageLoader mSpeakersImageLoader, mNoPlaceholderImageLoader;
+ private List<Runnable> mDeferredUiOperations = new ArrayList<Runnable>();
+
+ private StringBuilder mBuffer = new StringBuilder();
+
+ private int mPhotoHeightPixels;
+ private int mHeaderHeightPixels;
+ private int mAddScheduleButtonHeightPixels;
+
+ private boolean mHasPhoto;
+ private View mPhotoViewContainer;
+ private ImageView mPhotoView;
+ private int mSessionColor;
+ private String mLivestreamUrl;
+
+ private Runnable mTimeHintUpdaterRunnable = null;
+
+ private boolean mAlreadyGaveFeedback = false;
+ private boolean mIsKeynote = false;
+
+ // this set stores the session IDs for which the user has dismissed the
+ // "give feedback" card. This information is kept for the duration of the app's execution
+ // so that if they say "No, thanks", we don't show the card again for that session while
+ // the app is still executing.
+ private static HashSet<String> sDismissedFeedbackCard = new HashSet<String>();
+
+ private TextView mSubmitFeedbackView;
+ private float mMaxHeaderElevation;
+ private float mFABElevation;
+
+ private int mTagColorDotSize;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
UIUtils.tryTranslateHttpIntent(this);
BeamUtils.tryUpdateIntentFromBeam(this);
- requestWindowFeature(Window.FEATURE_ACTION_BAR);
- if (shouldBeFloatingWindow()) {
+ boolean shouldBeFloatingWindow = shouldBeFloatingWindow();
+ if (shouldBeFloatingWindow) {
setupFloatingWindow();
}
+
super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_session_detail);
+
+ final Toolbar toolbar = getActionBarToolbar();
+ toolbar.setNavigationIcon(shouldBeFloatingWindow
+ ? R.drawable.ic_ab_close : R.drawable.ic_up);
+ toolbar.setNavigationOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ finish();
+ }
+ });
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ toolbar.setTitle("");
+ }
+ });
if (savedInstanceState == null) {
Uri sessionUri = getIntent().getData();
BeamUtils.setBeamSessionUri(this, sessionUri);
}
- setTitle("");
- }
+ mSessionUri = getIntent().getData();
- @Override
- protected Fragment onCreatePane() {
- return new SessionDetailFragment();
+ if (mSessionUri == null) {
+ return;
+ }
+
+ mSessionId = ScheduleContract.Sessions.getSessionId(mSessionUri);
+
+ mFABElevation = getResources().getDimensionPixelSize(R.dimen.fab_elevation);
+ mMaxHeaderElevation = getResources().getDimensionPixelSize(
+ R.dimen.session_detail_max_header_elevation);
+
+ mTagColorDotSize = getResources().getDimensionPixelSize(R.dimen.tag_color_dot_size);
+
+ mHandler = new Handler();
+
+ if (mSpeakersImageLoader == null) {
+ mSpeakersImageLoader = new ImageLoader(this, R.drawable.person_image_empty);
+ }
+ if (mNoPlaceholderImageLoader == null) {
+ mNoPlaceholderImageLoader = new ImageLoader(this);
+ }
+
+ mScrollView = (ObservableScrollView) findViewById(R.id.scroll_view);
+ mScrollView.addCallbacks(this);
+ ViewTreeObserver vto = mScrollView.getViewTreeObserver();
+ if (vto.isAlive()) {
+ vto.addOnGlobalLayoutListener(mGlobalLayoutListener);
+ }
+
+ mScrollViewChild = findViewById(R.id.scroll_view_child);
+ mScrollViewChild.setVisibility(View.INVISIBLE);
+
+ mDetailsContainer = findViewById(R.id.details_container);
+ mHeaderBox = findViewById(R.id.header_session);
+ mTitle = (TextView) findViewById(R.id.session_title);
+ mSubtitle = (TextView) findViewById(R.id.session_subtitle);
+ mPhotoViewContainer = findViewById(R.id.session_photo_container);
+ mPhotoView = (ImageView) findViewById(R.id.session_photo);
+
+ mPlusOneButton = (PlusOneButton) findViewById(R.id.plus_one_button);
+ mAbstract = (TextView) findViewById(R.id.session_abstract);
+ mRequirements = (TextView) findViewById(R.id.session_requirements);
+ mTags = (LinearLayout) findViewById(R.id.session_tags);
+ mTagsContainer = (ViewGroup) findViewById(R.id.session_tags_container);
+
+ mAddScheduleButton = (CheckableFrameLayout) findViewById(R.id.add_schedule_button);
+ mAddScheduleButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ boolean starred = !mStarred;
+ SessionsHelper helper = new SessionsHelper(SessionDetailActivity.this);
+ showStarred(starred, true);
+ helper.setSessionStarred(mSessionUri, starred, mTitleString);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
+ mAddScheduleButton.announceForAccessibility(starred ?
+ getString(R.string.session_details_a11y_session_added) :
+ getString(R.string.session_details_a11y_session_removed));
+ }
+
+ /* [ANALYTICS:EVENT]
+ * TRIGGER: Add or remove a session from My Schedule.
+ * CATEGORY: 'Session'
+ * ACTION: 'Starred' or 'Unstarred'
+ * LABEL: Session title/subtitle.
+ * [/ANALYTICS]
+ */
+ AnalyticsManager.sendEvent(
+ "Session", starred ? "Starred" : "Unstarred", mTitleString, 0L);
+ }
+ });
+
+ ViewCompat.setTransitionName(mPhotoView, TRANSITION_NAME_PHOTO);
+
+ LoaderManager manager = getLoaderManager();
+ manager.initLoader(SessionsQuery._TOKEN, null, this);
+ manager.initLoader(SpeakersQuery._TOKEN, null, this);
+ manager.initLoader(TAG_METADATA_TOKEN, null, this);
}
@Override
public Intent getParentActivityIntent() {
- // TODO: make this Activity navigate up to the right screen depending on how it was launched
+ // TODO(mangini): make this Activity navigate up to the right screen depending on how it was launched
return new Intent(this, MyScheduleActivity.class);
}
@@ -66,8 +298,8 @@
params.width = getResources().getDimensionPixelSize(R.dimen.session_details_floating_width);
params.height = getResources().getDimensionPixelSize(R.dimen.session_details_floating_height);
params.alpha = 1;
- params.dimAmount = 0.7f;
- params.flags = WindowManager.LayoutParams.FLAG_DIM_BEHIND;
+ params.dimAmount = 0.4f;
+ params.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
getWindow().setAttributes(params);
}
@@ -81,12 +313,972 @@
return (floatingWindowFlag.data != 0);
}
+ private void recomputePhotoAndScrollingMetrics() {
+ mHeaderHeightPixels = mHeaderBox.getHeight();
+
+ mPhotoHeightPixels = 0;
+ if (mHasPhoto) {
+ mPhotoHeightPixels = (int) (mPhotoView.getWidth() / PHOTO_ASPECT_RATIO);
+ mPhotoHeightPixels = Math.min(mPhotoHeightPixels, mScrollView.getHeight() * 2 / 3);
+ }
+
+ ViewGroup.LayoutParams lp;
+ lp = mPhotoViewContainer.getLayoutParams();
+ if (lp.height != mPhotoHeightPixels) {
+ lp.height = mPhotoHeightPixels;
+ mPhotoViewContainer.setLayoutParams(lp);
+ }
+
+ ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams)
+ mDetailsContainer.getLayoutParams();
+ if (mlp.topMargin != mHeaderHeightPixels + mPhotoHeightPixels) {
+ mlp.topMargin = mHeaderHeightPixels + mPhotoHeightPixels;
+ mDetailsContainer.setLayoutParams(mlp);
+ }
+
+ onScrollChanged(0, 0); // trigger scroll handling
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ if (mScrollView == null) {
+ return;
+ }
+
+ ViewTreeObserver vto = mScrollView.getViewTreeObserver();
+ if (vto.isAlive()) {
+ vto.removeGlobalOnLayoutListener(mGlobalLayoutListener);
+ }
+ }
+
+ private ViewTreeObserver.OnGlobalLayoutListener mGlobalLayoutListener
+ = new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ mAddScheduleButtonHeightPixels = mAddScheduleButton.getHeight();
+ recomputePhotoAndScrollingMetrics();
+ }
+ };
+
+ @Override
+ public void onScrollChanged(int deltaX, int deltaY) {
+ // Reposition the header bar -- it's normally anchored to the top of the content,
+ // but locks to the top of the screen on scroll
+ int scrollY = mScrollView.getScrollY();
+
+ float newTop = Math.max(mPhotoHeightPixels, scrollY);
+ mHeaderBox.setTranslationY(newTop);
+ mAddScheduleButton.setTranslationY(newTop + mHeaderHeightPixels
+ - mAddScheduleButtonHeightPixels / 2);
+
+ float gapFillProgress = 1;
+ if (mPhotoHeightPixels != 0) {
+ gapFillProgress = Math.min(Math.max(UIUtils.getProgress(scrollY,
+ 0,
+ mPhotoHeightPixels), 0), 1);
+ }
+
+ ViewCompat.setElevation(mHeaderBox, gapFillProgress * mMaxHeaderElevation);
+ ViewCompat.setElevation(mAddScheduleButton, gapFillProgress * mMaxHeaderElevation
+ + mFABElevation);
+
+ // Move background photo (parallax effect)
+ mPhotoViewContainer.setTranslationY(scrollY * 0.5f);
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ updatePlusOneButton();
+ if (mTimeHintUpdaterRunnable != null) {
+ mHandler.postDelayed(mTimeHintUpdaterRunnable, TIME_HINT_UPDATE_INTERVAL);
+ }
+
+ // Refresh whether or not feedback has been submitted
+ getLoaderManager().restartLoader(FeedbackQuery._TOKEN, null, this);
+ }
+
+ @Override
+ public void onStop() {
+ super.onStop();
+ if (mInitStarred != mStarred) {
+ if (UIUtils.getCurrentTime(this) < mSessionStart) {
+ // Update Calendar event through the Calendar API on Android 4.0 or new versions.
+ Intent intent = null;
+ if (mStarred) {
+ // Set up intent to add session to Calendar, if it doesn't exist already.
+ intent = new Intent(SessionCalendarService.ACTION_ADD_SESSION_CALENDAR,
+ mSessionUri);
+ intent.putExtra(SessionCalendarService.EXTRA_SESSION_START,
+ mSessionStart);
+ intent.putExtra(SessionCalendarService.EXTRA_SESSION_END,
+ mSessionEnd);
+ intent.putExtra(SessionCalendarService.EXTRA_SESSION_ROOM, mRoomName);
+ intent.putExtra(SessionCalendarService.EXTRA_SESSION_TITLE, mTitleString);
+ } else {
+ // Set up intent to remove session from Calendar, if exists.
+ intent = new Intent(SessionCalendarService.ACTION_REMOVE_SESSION_CALENDAR,
+ mSessionUri);
+ intent.putExtra(SessionCalendarService.EXTRA_SESSION_START,
+ mSessionStart);
+ intent.putExtra(SessionCalendarService.EXTRA_SESSION_END,
+ mSessionEnd);
+ intent.putExtra(SessionCalendarService.EXTRA_SESSION_TITLE, mTitleString);
+ }
+ intent.setClass(this, SessionCalendarService.class);
+ startService(intent);
+
+ if (mStarred) {
+ setupNotification();
+ }
+ }
+ }
+ }
+
+ private void setupNotification() {
+ Intent scheduleIntent;
+
+ // Schedule session notification
+ if (UIUtils.getCurrentTime(this) < mSessionStart) {
+ LOGD(TAG, "Scheduling notification about session start.");
+ scheduleIntent = new Intent(
+ SessionAlarmService.ACTION_SCHEDULE_STARRED_BLOCK,
+ null, this, SessionAlarmService.class);
+ scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_START, mSessionStart);
+ scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_END, mSessionEnd);
+ startService(scheduleIntent);
+ } else {
+ LOGD(TAG, "Not scheduling notification about session start, too late.");
+ }
+
+ // Schedule feedback notification
+ if (UIUtils.getCurrentTime(this) < mSessionEnd) {
+ LOGD(TAG, "Scheduling notification about session feedback.");
+ scheduleIntent = new Intent(
+ SessionAlarmService.ACTION_SCHEDULE_FEEDBACK_NOTIFICATION,
+ null, this, SessionAlarmService.class);
+ scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_ID, mSessionId);
+ scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_START, mSessionStart);
+ scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_END, mSessionEnd);
+ scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_TITLE, mTitleString);
+ scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_ROOM, mRoomName);
+ scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_SPEAKERS, mSpeakers);
+ startService(scheduleIntent);
+ } else {
+ LOGD(TAG, "Not scheduling feedback notification, too late.");
+ }
+ }
+
+ private void updateTimeBasedUi() {
+ long currentTimeMillis = UIUtils.getCurrentTime(this);
+ boolean canShowLivestream = mHasLivestream;
+
+ if (canShowLivestream && !mDismissedWatchLivestreamCard
+ && currentTimeMillis > mSessionStart
+ && currentTimeMillis <= mSessionEnd) {
+ // show the "watch now" card
+ showWatchNowCard();
+ } else if (!mAlreadyGaveFeedback && mInitStarred && currentTimeMillis >= (mSessionEnd -
+ Config.FEEDBACK_MILLIS_BEFORE_SESSION_END)
+ && !sDismissedFeedbackCard.contains(mSessionId)) {
+ // show the "give feedback" card
+ showGiveFeedbackCard();
+ }
+
+ String timeHint = "";
+ long countdownMillis = mSessionStart - currentTimeMillis;
+
+ if (TimeUtils.hasConferenceEnded(this)) {
+ // no time hint to display
+ timeHint = "";
+ } else if (currentTimeMillis >= mSessionEnd) {
+ timeHint = getString(R.string.time_hint_session_ended);
+ } else if (currentTimeMillis >= mSessionStart) {
+ long minutesAgo = (currentTimeMillis - mSessionStart) / 60000;
+ if (minutesAgo > 1) {
+ timeHint = getString(R.string.time_hint_started_min, minutesAgo);
+ } else {
+ timeHint = getString(R.string.time_hint_started_just);
+ }
+ } else if (countdownMillis > 0 && countdownMillis < Config.HINT_TIME_BEFORE_SESSION) {
+ long millisUntil = mSessionStart - currentTimeMillis;
+ long minutesUntil = millisUntil / 60000 + (millisUntil % 1000 > 0 ? 1 : 0);
+ if (minutesUntil > 1) {
+ timeHint = getString(R.string.time_hint_about_to_start_min, minutesUntil);
+ } else {
+ timeHint = getString(R.string.time_hint_about_to_start_shortly, minutesUntil);
+ }
+ }
+
+ final TextView timeHintView = (TextView) findViewById(R.id.time_hint);
+
+ if (!TextUtils.isEmpty(timeHint)) {
+ timeHintView.setVisibility(View.VISIBLE);
+ timeHintView.setText(timeHint);
+ } else {
+ timeHintView.setVisibility(View.GONE);
+ }
+ }
+
+ private void setTextSelectable(TextView tv) {
+ if (tv != null && !tv.isTextSelectable()) {
+ tv.setTextIsSelectable(true);
+ }
+ }
+
+ private void onFeedbackQueryComplete(Cursor cursor) {
+ // Is there existing feedback for this session?
+ mAlreadyGaveFeedback = cursor.getCount() > 0;
+
+ if (mAlreadyGaveFeedback) {
+ final MessageCardView giveFeedbackCardView = (MessageCardView) findViewById(R.id.give_feedback_card);
+ if (giveFeedbackCardView != null) {
+ giveFeedbackCardView.setVisibility(View.GONE);
+ }
+ if (mSubmitFeedbackView != null) {
+ mSubmitFeedbackView.setVisibility(View.GONE);
+ }
+ }
+ LOGD(TAG, "User " + (mAlreadyGaveFeedback ? "already gave" : "has not given") + " feedback for session.");
+ cursor.close();
+ }
+
+ /**
+ * Handle {@link SessionsQuery} {@link Cursor}.
+ */
+ private void onSessionQueryComplete(Cursor cursor) {
+ mSessionCursor = true;
+ if (!cursor.moveToFirst()) {
+ // TODO: Remove this in favor of a callbacks interface that the activity
+ // can implement.
+ finish();
+ return;
+ }
+
+ mTitleString = cursor.getString(SessionsQuery.TITLE);
+ mSessionColor = cursor.getInt(SessionsQuery.COLOR);
+
+ if (mSessionColor == 0) {
+ // no color -- use default
+ mSessionColor = getResources().getColor(R.color.default_session_color);
+ } else {
+ // make sure it's opaque
+ mSessionColor = UIUtils.setColorAlpha(mSessionColor, 255);
+ }
+
+ mHeaderBox.setBackgroundColor(mSessionColor);
+ getLUtils().setStatusBarColor(UIUtils.scaleColor(mSessionColor, 0.8f, false));
+
+ mLivestreamUrl = cursor.getString(SessionsQuery.LIVESTREAM_URL);
+ mHasLivestream = !TextUtils.isEmpty(mLivestreamUrl);
+
+ // Format the time this session occupies
+ mSessionStart = cursor.getLong(SessionsQuery.START);
+ mSessionEnd = cursor.getLong(SessionsQuery.END);
+ mRoomName = cursor.getString(SessionsQuery.ROOM_NAME);
+ mSpeakers = cursor.getString(SessionsQuery.SPEAKER_NAMES);
+ String subtitle = UIUtils.formatSessionSubtitle(
+ mSessionStart, mSessionEnd, mRoomName, mBuffer, this);
+ if (mHasLivestream) {
+ subtitle += " " + UIUtils.getLiveBadgeText(this, mSessionStart, mSessionEnd);
+ }
+
+ mTitle.setText(mTitleString);
+ mSubtitle.setText(subtitle);
+
+ for (int resId : SECTION_HEADER_RES_IDS) {
+ ((TextView) findViewById(resId)).setTextColor(mSessionColor);
+ }
+
+ mPhotoViewContainer.setBackgroundColor(UIUtils.scaleSessionColorToDefaultBG(mSessionColor));
+
+ String photo = cursor.getString(SessionsQuery.PHOTO_URL);
+ if (!TextUtils.isEmpty(photo)) {
+ mHasPhoto = true;
+ mNoPlaceholderImageLoader.loadImage(photo, mPhotoView, new RequestListener<String>() {
+ @Override
+ public void onException(Exception e, String url, Target target) {
+ mHasPhoto = false;
+ recomputePhotoAndScrollingMetrics();
+ }
+
+ @Override
+ public void onImageReady(String url, Target target, boolean b, boolean b2) {
+ // Trigger image transition
+ recomputePhotoAndScrollingMetrics();
+ }
+ });
+ recomputePhotoAndScrollingMetrics();
+ } else {
+ mHasPhoto = false;
+ recomputePhotoAndScrollingMetrics();
+ }
+
+ mUrl = cursor.getString(SessionsQuery.URL);
+ if (TextUtils.isEmpty(mUrl)) {
+ mUrl = "";
+ }
+
+ mHashTag = cursor.getString(SessionsQuery.HASHTAG);
+ if (!TextUtils.isEmpty(mHashTag)) {
+ enableSocialStreamMenuItemDeferred();
+ }
+
+ mRoomId = cursor.getString(SessionsQuery.ROOM_ID);
+
+ final boolean inMySchedule = cursor.getInt(SessionsQuery.IN_MY_SCHEDULE) != 0;
+
+ setupShareMenuItemDeferred();
+
+ // Handle Keynote as a special case, where the user cannot remove it
+ // from the schedule (it is auto added to schedule on sync)
+ mTagsString = cursor.getString(SessionsQuery.TAGS);
+ mIsKeynote = mTagsString.contains(Config.Tags.SPECIAL_KEYNOTE);
+ mAddScheduleButton.setVisibility(
+ (AccountUtils.hasActiveAccount(this) && !mIsKeynote)
+ ? View.VISIBLE : View.INVISIBLE);
+
+ tryRenderTags();
+
+ if (!mIsKeynote) {
+ showStarredDeferred(mInitStarred = inMySchedule, false);
+ }
+
+ final String sessionAbstract = cursor.getString(SessionsQuery.ABSTRACT);
+ if (!TextUtils.isEmpty(sessionAbstract)) {
+ UIUtils.setTextMaybeHtml(mAbstract, sessionAbstract);
+ mAbstract.setVisibility(View.VISIBLE);
+ mHasSummaryContent = true;
+ } else {
+ mAbstract.setVisibility(View.GONE);
+ }
+
+ updatePlusOneButton();
+
+ // Build requirements section
+ final View requirementsBlock = findViewById(R.id.session_requirements_block);
+ final String sessionRequirements = cursor.getString(SessionsQuery.REQUIREMENTS);
+ if (!TextUtils.isEmpty(sessionRequirements)) {
+ UIUtils.setTextMaybeHtml(mRequirements, sessionRequirements);
+ requirementsBlock.setVisibility(View.VISIBLE);
+ mHasSummaryContent = true;
+ } else {
+ requirementsBlock.setVisibility(View.GONE);
+ }
+
+ // Build related videos section
+ final ViewGroup relatedVideosBlock = (ViewGroup) findViewById(R.id.related_videos_block);
+ relatedVideosBlock.setVisibility(View.GONE);
+
+ // Build links section
+ buildLinksSection(cursor);
+
+ updateEmptyView();
+
+ updateTimeBasedUi();
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ onScrollChanged(0, 0); // trigger scroll handling
+ mScrollViewChild.setVisibility(View.VISIBLE);
+ //mAbstract.setTextIsSelectable(true);
+ }
+ });
+
+ mTimeHintUpdaterRunnable = new Runnable() {
+ @Override
+ public void run() {
+ updateTimeBasedUi();
+ mHandler.postDelayed(mTimeHintUpdaterRunnable, TIME_HINT_UPDATE_INTERVAL);
+ }
+ };
+ mHandler.postDelayed(mTimeHintUpdaterRunnable, TIME_HINT_UPDATE_INTERVAL);
+ }
+
+ private void tryRenderTags() {
+ if (mTagMetadata == null || mTagsString == null) {
+ return;
+ }
+
+ if (TextUtils.isEmpty(mTagsString)) {
+ mTagsContainer.setVisibility(View.GONE);
+ } else {
+ mTagsContainer.setVisibility(View.VISIBLE);
+ mTags.removeAllViews();
+ LayoutInflater inflater = LayoutInflater.from(this);
+ String[] tagIds = mTagsString.split(",");
+
+ List<TagMetadata.Tag> tags = new ArrayList<TagMetadata.Tag>();
+ for (String tagId : tagIds) {
+ if (Config.Tags.SESSIONS.equals(tagId) ||
+ Config.Tags.SPECIAL_KEYNOTE.equals(tagId)) {
+ continue;
+ }
+
+ TagMetadata.Tag tag = mTagMetadata.getTag(tagId);
+ if (tag == null) {
+ continue;
+ }
+
+ tags.add(tag);
+ }
+
+ if (tags.size() == 0) {
+ mTagsContainer.setVisibility(View.GONE);
+ return;
+ }
+
+ Collections.sort(tags, TagMetadata.TAG_DISPLAY_ORDER_COMPARATOR);
+
+ for (final TagMetadata.Tag tag : tags) {
+ TextView chipView = (TextView) inflater.inflate(
+ R.layout.include_session_tag_chip, mTags, false);
+ chipView.setText(tag.getName());
+
+ if (Config.Tags.CATEGORY_TOPIC.equals(tag.getCategory())) {
+ ShapeDrawable colorDrawable = new ShapeDrawable(new OvalShape());
+ colorDrawable.setIntrinsicWidth(mTagColorDotSize);
+ colorDrawable.setIntrinsicHeight(mTagColorDotSize);
+ colorDrawable.getPaint().setStyle(Paint.Style.FILL);
+ chipView.setCompoundDrawablesWithIntrinsicBounds(colorDrawable,
+ null, null, null);
+ colorDrawable.getPaint().setColor(tag.getColor());
+ }
+
+ chipView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ finish(); // TODO: better encapsulation
+ Intent intent = new Intent(SessionDetailActivity.this, BrowseSessionsActivity.class)
+ .putExtra(BrowseSessionsActivity.EXTRA_FILTER_TAG, tag.getId())
+ .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
+ startActivity(intent);
+ }
+ });
+
+ mTags.addView(chipView);
+ }
+ }
+ }
+
+ private void buildLinksSection(Cursor cursor) {
+ // Compile list of links (I/O live link, submit feedback, and normal links)
+ ViewGroup linkContainer = (ViewGroup) findViewById(R.id.links_container);
+ linkContainer.removeAllViews();
+
+
+ // Build links section
+ // the Object can be either a string URL or an Intent
+ List<Pair<Integer, Object>> links = new ArrayList<Pair<Integer, Object>>();
+
+ long currentTimeMillis = UIUtils.getCurrentTime(this);
+ if (mHasLivestream
+ && currentTimeMillis > mSessionStart
+ && currentTimeMillis <= mSessionEnd) {
+ links.add(new Pair<Integer, Object>(
+ R.string.session_link_livestream,
+ getWatchLiveIntent(this)));
+ }
+
+ // Add session feedback link, if appropriate
+ if (!mAlreadyGaveFeedback && currentTimeMillis > mSessionEnd
+ - Config.FEEDBACK_MILLIS_BEFORE_SESSION_END) {
+ links.add(new Pair<Integer, Object>(
+ R.string.session_feedback_submitlink,
+ getFeedbackIntent()
+ ));
+ }
+
+ for (int i = 0; i < SessionsQuery.LINKS_INDICES.length; i++) {
+ final String linkUrl = cursor.getString(SessionsQuery.LINKS_INDICES[i]);
+ if (TextUtils.isEmpty(linkUrl)) {
+ continue;
+ }
+
+ links.add(new Pair<Integer, Object>(
+ SessionsQuery.LINKS_TITLES[i],
+ new Intent(Intent.ACTION_VIEW, Uri.parse(linkUrl))
+ .addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
+ ));
+ }
+
+ // Render links
+ if (links.size() > 0) {
+ LayoutInflater inflater = LayoutInflater.from(this);
+ int columns = getResources().getInteger(R.integer.links_columns);
+
+ LinearLayout currentLinkRowView = null;
+ for (int i = 0; i < links.size(); i++) {
+ final Pair<Integer, Object> link = links.get(i);
+
+ // Create link view
+ TextView linkView = (TextView) inflater.inflate(R.layout.list_item_session_link,
+ linkContainer, false);
+ if (link.first == R.string.session_feedback_submitlink) {
+ mSubmitFeedbackView = linkView;
+ }
+ linkView.setText(getString(link.first));
+ linkView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ fireLinkEvent(link.first);
+ Intent intent=null;
+ if (link.second instanceof Intent) {
+ intent = (Intent) link.second;
+ } else if (link.second instanceof String) {
+ intent = new Intent(Intent.ACTION_VIEW, Uri.parse((String) link.second))
+ .addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+ }
+ try {
+ startActivity(intent);
+ } catch (ActivityNotFoundException ignored) {
+ }
+ }
+ });
+
+ // Place it inside a container
+ if (columns == 1) {
+ linkContainer.addView(linkView);
+ } else {
+ // create a new link row
+ if (i % columns == 0) {
+ currentLinkRowView = (LinearLayout) inflater.inflate(
+ R.layout.include_link_row, linkContainer, false);
+ currentLinkRowView.setWeightSum(columns);
+ linkContainer.addView(currentLinkRowView);
+ }
+
+ ((LinearLayout.LayoutParams) linkView.getLayoutParams()).width = 0;
+ ((LinearLayout.LayoutParams) linkView.getLayoutParams()).weight = 1;
+ currentLinkRowView.addView(linkView);
+ }
+ }
+
+ findViewById(R.id.session_links_header).setVisibility(View.VISIBLE);
+ findViewById(R.id.links_container).setVisibility(View.VISIBLE);
+
+ } else {
+ findViewById(R.id.session_links_header).setVisibility(View.GONE);
+ findViewById(R.id.links_container).setVisibility(View.GONE);
+ }
+
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ if (mTimeHintUpdaterRunnable != null) {
+ mHandler.removeCallbacks(mTimeHintUpdaterRunnable);
+ }
+ }
+
+ private Intent getWatchLiveIntent(Context context) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
+ YouTubeIntents.canResolvePlayVideoIntent(context)) {
+ String youtubeVideoId = SessionLivestreamActivity.getVideoIdFromUrl(mLivestreamUrl);
+ return YouTubeIntents.createPlayVideoIntentWithOptions(
+ context, youtubeVideoId, true, false);
+ }
+ return new Intent(Intent.ACTION_VIEW, mSessionUri).setClass(context,
+ SessionLivestreamActivity.class);
+ }
+
+ private void updatePlusOneButton() {
+ if (mPlusOneButton == null) {
+ return;
+ }
+
+ if (!TextUtils.isEmpty(mUrl) && !mIsKeynote) {
+ mPlusOneButton.initialize(mUrl, 0);
+ mPlusOneButton.setVisibility(View.VISIBLE);
+ } else {
+ mPlusOneButton.setVisibility(View.GONE);
+ }
+ }
+
+ private void showWatchNowCard() {
+ final MessageCardView messageCardView = (MessageCardView) findViewById(R.id.live_now_card);
+ messageCardView.show();
+ messageCardView.setListener(new MessageCardView.OnMessageCardButtonClicked() {
+ @Override
+ public void onMessageCardButtonClicked(String tag) {
+ if ("WATCH_NOW".equals(tag)) {
+ Intent intent = getWatchLiveIntent(SessionDetailActivity.this);
+ startActivity(intent);
+ } else {
+ mDismissedWatchLivestreamCard = true;
+ messageCardView.dismiss();
+ }
+ }
+ });
+ }
+
+ private void showGiveFeedbackCard() {
+ final MessageCardView messageCardView = (MessageCardView) findViewById(R.id.give_feedback_card);
+ messageCardView.show();
+ messageCardView.setListener(new MessageCardView.OnMessageCardButtonClicked() {
+ @Override
+ public void onMessageCardButtonClicked(String tag) {
+ if ("GIVE_FEEDBACK".equals(tag)) {
+ /* [ANALYTICS:EVENT]
+ * TRIGGER: Click on the Send Feedback action on the Session Details page.
+ * CATEGORY: 'Session'
+ * ACTION: 'Feedback'
+ * LABEL: session title/subtitle
+ * [/ANALYTICS]
+ */
+ AnalyticsManager.sendEvent("Session", "Feedback", mTitleString, 0L);
+ Intent intent = getFeedbackIntent();
+ startActivity(intent);
+ } else {
+ sDismissedFeedbackCard.add(mSessionId);
+ messageCardView.dismiss();
+ }
+ }
+ });
+ }
+
+ private Intent getFeedbackIntent() {
+ return new Intent(Intent.ACTION_VIEW, mSessionUri, this,
+ SessionFeedbackActivity.class);
+ }
+
+ private void enableSocialStreamMenuItemDeferred() {
+ mDeferredUiOperations.add(new Runnable() {
+ @Override
+ public void run() {
+ mSocialStreamMenuItem.setVisible(true);
+ }
+ });
+ tryExecuteDeferredUiOperations();
+ }
+
+ private void showStarredDeferred(final boolean starred, final boolean allowAnimate) {
+ mDeferredUiOperations.add(new Runnable() {
+ @Override
+ public void run() {
+ showStarred(starred, allowAnimate);
+ }
+ });
+ tryExecuteDeferredUiOperations();
+ }
+
+ private void showStarred(boolean starred, boolean allowAnimate) {
+ mStarred = starred;
+
+ mAddScheduleButton.setChecked(mStarred, allowAnimate);
+
+ ImageView iconView = (ImageView) mAddScheduleButton.findViewById(R.id.add_schedule_icon);
+ getLUtils().setOrAnimatePlusCheckIcon(iconView, starred, allowAnimate);
+ mAddScheduleButton.setContentDescription(getString(starred
+ ? R.string.remove_from_schedule_desc
+ : R.string.add_to_schedule_desc));
+ }
+
+ private void setupShareMenuItemDeferred() {
+ mDeferredUiOperations.add(new Runnable() {
+ @Override
+ public void run() {
+ new SessionsHelper(SessionDetailActivity.this).tryConfigureShareMenuItem(mShareMenuItem,
+ R.string.share_template, mTitleString, mHashTag, mUrl);
+ }
+ });
+ tryExecuteDeferredUiOperations();
+ }
+
+ private void tryExecuteDeferredUiOperations() {
+ if (mSocialStreamMenuItem != null) {
+ for (Runnable r : mDeferredUiOperations) {
+ r.run();
+ }
+ mDeferredUiOperations.clear();
+ }
+ }
+
+ private void onSpeakersQueryComplete(Cursor cursor) {
+ mSpeakersCursor = true;
+ final ViewGroup speakersGroup = (ViewGroup) findViewById(R.id.session_speakers_block);
+
+ // Remove all existing speakers (everything but first child, which is the header)
+ for (int i = speakersGroup.getChildCount() - 1; i >= 1; i--) {
+ speakersGroup.removeViewAt(i);
+ }
+
+ final LayoutInflater inflater = getLayoutInflater();
+
+ boolean hasSpeakers = false;
+
+ cursor.moveToPosition(-1); // move to just before first record
+ while (cursor.moveToNext()) {
+ final String speakerName = cursor.getString(SpeakersQuery.SPEAKER_NAME);
+ if (TextUtils.isEmpty(speakerName)) {
+ continue;
+ }
+
+ final String speakerImageUrl = cursor.getString(SpeakersQuery.SPEAKER_IMAGE_URL);
+ final String speakerCompany = cursor.getString(SpeakersQuery.SPEAKER_COMPANY);
+ final String speakerUrl = cursor.getString(SpeakersQuery.SPEAKER_URL);
+ final String speakerAbstract = cursor.getString(SpeakersQuery.SPEAKER_ABSTRACT);
+
+ String speakerHeader = speakerName;
+ if (!TextUtils.isEmpty(speakerCompany)) {
+ speakerHeader += ", " + speakerCompany;
+ }
+
+ final View speakerView = inflater
+ .inflate(R.layout.speaker_detail, speakersGroup, false);
+ final TextView speakerHeaderView = (TextView) speakerView
+ .findViewById(R.id.speaker_header);
+ final ImageView speakerImageView = (ImageView) speakerView
+ .findViewById(R.id.speaker_image);
+ final TextView speakerAbstractView = (TextView) speakerView
+ .findViewById(R.id.speaker_abstract);
+
+ if (!TextUtils.isEmpty(speakerImageUrl) && mSpeakersImageLoader != null) {
+ mSpeakersImageLoader.loadImage(speakerImageUrl, speakerImageView);
+ }
+
+ speakerHeaderView.setText(speakerHeader);
+ speakerImageView.setContentDescription(
+ getString(R.string.speaker_googleplus_profile, speakerHeader));
+ UIUtils.setTextMaybeHtml(speakerAbstractView, speakerAbstract);
+
+ if (!TextUtils.isEmpty(speakerUrl)) {
+ speakerImageView.setEnabled(true);
+ speakerImageView.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ Intent speakerProfileIntent = new Intent(Intent.ACTION_VIEW,
+ Uri.parse(speakerUrl));
+ speakerProfileIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
+ UIUtils.preferPackageForIntent(SessionDetailActivity.this,
+ speakerProfileIntent,
+ UIUtils.GOOGLE_PLUS_PACKAGE_NAME);
+ startActivity(speakerProfileIntent);
+ }
+ });
+ } else {
+ speakerImageView.setEnabled(false);
+ speakerImageView.setOnClickListener(null);
+ }
+
+ speakersGroup.addView(speakerView);
+ hasSpeakers = true;
+ mHasSummaryContent = true;
+ }
+
+ speakersGroup.setVisibility(hasSpeakers ? View.VISIBLE : View.GONE);
+ updateEmptyView();
+ }
+
+ private void updateEmptyView() {
+ findViewById(android.R.id.empty).setVisibility(
+ (mSpeakersCursor && mSessionCursor && !mHasSummaryContent)
+ ? View.VISIBLE
+ : View.GONE);
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+ getMenuInflater().inflate(R.menu.session_detail, menu);
+ mSocialStreamMenuItem = menu.findItem(R.id.menu_social_stream);
+ mShareMenuItem = menu.findItem(R.id.menu_share);
+ tryExecuteDeferredUiOperations();
+ return true;
+ }
+
@Override
public boolean onOptionsItemSelected(MenuItem item) {
- if (item.getItemId() == android.R.id.home) {
- finish();
- return true;
+ SessionsHelper helper = new SessionsHelper(this);
+ switch (item.getItemId()) {
+ case R.id.menu_map_room:
+ /* [ANALYTICS:EVENT]
+ * TRIGGER: Click on the Map action on the Session Details page.
+ * CATEGORY: 'Session'
+ * ACTION: 'Map'
+ * LABEL: session title/subtitle
+ * [/ANALYTICS]
+ */
+ AnalyticsManager.sendEvent("Session", "Map", mTitleString, 0L);
+ helper.startMapActivity(mRoomId);
+ return true;
+
+ case R.id.menu_share:
+ // On ICS+ devices, we normally won't reach this as ShareActionProvider will handle
+ // sharing.
+ helper.shareSession(this, R.string.share_template, mTitleString,
+ mHashTag, mUrl);
+ return true;
+
+ case R.id.menu_social_stream:
+ if (!TextUtils.isEmpty(mHashTag)) {
+ /* [ANALYTICS:EVENT]
+ * TRIGGER: Click on the Social Stream action on the Session Details page.
+ * CATEGORY: 'Session'
+ * ACTION: 'Stream'
+ * LABEL: session title/subtitle
+ * [/ANALYTICS]
+ */
+ AnalyticsManager.sendEvent("Session", "Stream", mTitleString, 0L);
+ UIUtils.showHashtagStream(this, mHashTag);
+ }
+ return true;
}
- return super.onOptionsItemSelected(item);
+ return false;
}
+
+ /*
+ * Event structure:
+ * Category -> "Session Details"
+ * Action -> Link Text
+ * Label -> Session's Title
+ * Value -> 0.
+ */
+ void fireLinkEvent(int actionId) {
+ /* [ANALYTICS:EVENT]
+ * TRIGGER: Click on a link on the Session Details page.
+ * CATEGORY: 'Session'
+ * ACTION: The link's name ("Watch Live", "Follow us on Google+", etc)
+ * LABEL: The session's title/subtitle.
+ * [/ANALYTICS]
+ */
+ AnalyticsManager.sendEvent("Session", getString(actionId), mTitleString, 0L);
+ }
+
+ /**
+ * {@link com.google.samples.apps.iosched.provider.ScheduleContract.Sessions} query parameters.
+ */
+ private interface SessionsQuery {
+ int _TOKEN = 0x1;
+
+ String[] PROJECTION = {
+ ScheduleContract.Sessions.SESSION_START,
+ ScheduleContract.Sessions.SESSION_END,
+ ScheduleContract.Sessions.SESSION_LEVEL,
+ ScheduleContract.Sessions.SESSION_TITLE,
+ ScheduleContract.Sessions.SESSION_ABSTRACT,
+ ScheduleContract.Sessions.SESSION_REQUIREMENTS,
+ ScheduleContract.Sessions.SESSION_IN_MY_SCHEDULE,
+ ScheduleContract.Sessions.SESSION_HASHTAG,
+ ScheduleContract.Sessions.SESSION_URL,
+ ScheduleContract.Sessions.SESSION_YOUTUBE_URL,
+ ScheduleContract.Sessions.SESSION_PDF_URL,
+ ScheduleContract.Sessions.SESSION_NOTES_URL,
+ ScheduleContract.Sessions.SESSION_LIVESTREAM_URL,
+ ScheduleContract.Sessions.SESSION_MODERATOR_URL,
+ ScheduleContract.Sessions.ROOM_ID,
+ ScheduleContract.Rooms.ROOM_NAME,
+ ScheduleContract.Sessions.SESSION_COLOR,
+ ScheduleContract.Sessions.SESSION_PHOTO_URL,
+ ScheduleContract.Sessions.SESSION_RELATED_CONTENT,
+ ScheduleContract.Sessions.SESSION_TAGS,
+ ScheduleContract.Sessions.SESSION_SPEAKER_NAMES
+ };
+
+ int START = 0;
+ int END = 1;
+ int LEVEL = 2;
+ int TITLE = 3;
+ int ABSTRACT = 4;
+ int REQUIREMENTS = 5;
+ int IN_MY_SCHEDULE = 6;
+ int HASHTAG = 7;
+ int URL = 8;
+ int YOUTUBE_URL = 9;
+ int PDF_URL = 10;
+ int NOTES_URL = 11;
+ int LIVESTREAM_URL = 12;
+ int MODERATOR_URL = 13;
+ int ROOM_ID = 14;
+ int ROOM_NAME = 15;
+ int COLOR = 16;
+ int PHOTO_URL = 17;
+ int RELATED_CONTENT = 18;
+ int TAGS = 19;
+ int SPEAKER_NAMES = 20;
+
+ int[] LINKS_INDICES = {
+ YOUTUBE_URL,
+ MODERATOR_URL,
+ PDF_URL,
+ NOTES_URL,
+ };
+
+ int[] LINKS_TITLES = {
+ R.string.session_link_youtube,
+ R.string.session_link_moderator,
+ R.string.session_link_pdf,
+ R.string.session_link_notes,
+ };
+ }
+
+ private interface SpeakersQuery {
+ int _TOKEN = 0x3;
+
+ String[] PROJECTION = {
+ ScheduleContract.Speakers.SPEAKER_NAME,
+ ScheduleContract.Speakers.SPEAKER_IMAGE_URL,
+ ScheduleContract.Speakers.SPEAKER_COMPANY,
+ ScheduleContract.Speakers.SPEAKER_ABSTRACT,
+ ScheduleContract.Speakers.SPEAKER_URL,
+ };
+
+ int SPEAKER_NAME = 0;
+ int SPEAKER_IMAGE_URL = 1;
+ int SPEAKER_COMPANY = 2;
+ int SPEAKER_ABSTRACT = 3;
+ int SPEAKER_URL = 4;
+ }
+
+ private interface FeedbackQuery {
+ int _TOKEN = 0x4;
+
+ String[] PROJECTION = {
+ ScheduleContract.Feedback.SESSION_ID
+ };
+ }
+
+ private static final int TAG_METADATA_TOKEN = 0x5;
+
+ @Override
+ public Loader<Cursor> onCreateLoader(int id, Bundle data) {
+ CursorLoader loader = null;
+ if (id == SessionsQuery._TOKEN){
+ loader = new CursorLoader(this, mSessionUri, SessionsQuery.PROJECTION, null,
+ null, null);
+ } else if (id == SpeakersQuery._TOKEN && mSessionUri != null){
+ Uri speakersUri = ScheduleContract.Sessions.buildSpeakersDirUri(mSessionId);
+ loader = new CursorLoader(this, speakersUri, SpeakersQuery.PROJECTION, null,
+ null, ScheduleContract.Speakers.DEFAULT_SORT);
+ } else if (id == FeedbackQuery._TOKEN) {
+ Uri feedbackUri = ScheduleContract.Feedback.buildFeedbackUri(mSessionId);
+ loader = new CursorLoader(this, feedbackUri, FeedbackQuery.PROJECTION, null,
+ null, null);
+ } else if (id == TAG_METADATA_TOKEN) {
+ loader = TagMetadata.createCursorLoader(this);
+ }
+ return loader;
+ }
+
+ @Override
+ public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
+ if (loader.getId() == SessionsQuery._TOKEN) {
+ onSessionQueryComplete(cursor);
+ } else if (loader.getId() == SpeakersQuery._TOKEN) {
+ onSpeakersQueryComplete(cursor);
+ } else if (loader.getId() == FeedbackQuery._TOKEN) {
+ onFeedbackQueryComplete(cursor);
+ } else if (loader.getId() == TAG_METADATA_TOKEN) {
+ mTagMetadata = new TagMetadata(cursor);
+ cursor.close();
+ tryRenderTags();
+ } else {
+ cursor.close();
+ }
+ }
+
+ @Override
+ public void onLoaderReset(Loader<Cursor> loader) {}
}
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/SessionDetailFragment.java b/android/src/main/java/com/google/samples/apps/iosched/ui/SessionDetailFragment.java
deleted file mode 100644
index b824bba..0000000
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/SessionDetailFragment.java
+++ /dev/null
@@ -1,1306 +0,0 @@
-/*
- * Copyright 2014 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.
- */
-
-package com.google.samples.apps.iosched.ui;
-
-import android.app.Fragment;
-import android.app.LoaderManager;
-import android.content.*;
-import android.database.Cursor;
-import android.graphics.Paint;
-import android.graphics.drawable.ShapeDrawable;
-import android.graphics.drawable.shapes.OvalShape;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.Handler;
-import android.text.TextUtils;
-import android.util.Pair;
-import android.view.*;
-import android.view.View.OnClickListener;
-import android.view.animation.DecelerateInterpolator;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import com.google.android.gms.plus.PlusOneButton;
-import com.google.android.youtube.player.YouTubeIntents;
-import com.google.samples.apps.iosched.Config;
-import com.google.samples.apps.iosched.R;
-import com.google.samples.apps.iosched.model.TagMetadata;
-import com.google.samples.apps.iosched.provider.ScheduleContract;
-import com.google.samples.apps.iosched.service.SessionAlarmService;
-import com.google.samples.apps.iosched.service.SessionCalendarService;
-import com.google.samples.apps.iosched.ui.widget.CheckableFrameLayout;
-import com.google.samples.apps.iosched.ui.widget.MessageCardView;
-import com.google.samples.apps.iosched.ui.widget.ObservableScrollView;
-import com.google.samples.apps.iosched.util.*;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-
-import com.bumptech.glide.request.bitmap.RequestListener;
-import com.bumptech.glide.request.target.Target;
-
-import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
-import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
-
-/**
- * A fragment that shows detail information for a session, including session title, abstract,
- * time information, speaker photos and bios, etc.
- */
-public class SessionDetailFragment extends Fragment implements
- LoaderManager.LoaderCallbacks<Cursor>,
- ObservableScrollView.Callbacks {
-
- private static final String TAG = makeLogTag(SessionDetailFragment.class);
-
- private static final int[] SECTION_HEADER_RES_IDS = {
- R.id.session_links_header,
- R.id.session_speakers_header,
- R.id.session_requirements_header,
- R.id.related_videos_header,
- };
- private static final float PHOTO_ASPECT_RATIO = 1.7777777f;
-
- public static final String VIEW_NAME_PHOTO = "photo";
-
- private Handler mHandler = new Handler();
- private static final int TIME_HINT_UPDATE_INTERVAL = 10000; // 10 sec
-
- private TagMetadata mTagMetadata;
-
- private String mSessionId;
- private Uri mSessionUri;
-
- private long mSessionStart;
- private long mSessionEnd;
- private String mTitleString;
- private String mHashTag;
- private String mUrl;
- private String mRoomId;
- private String mRoomName;
- private String mTagsString;
-
- // A comma-separated list of speakers to be passed to Android Wear
- private String mSpeakers;
-
- private boolean mStarred;
- private boolean mInitStarred;
- private boolean mDismissedWatchLivestreamCard = false;
- private boolean mHasLivestream = false;
- private MenuItem mSocialStreamMenuItem;
- private MenuItem mShareMenuItem;
-
- private ViewGroup mRootView;
- private View mScrollViewChild;
- private TextView mTitle;
- private TextView mSubtitle;
- private PlusOneButton mPlusOneButton;
-
- private ObservableScrollView mScrollView;
- private CheckableFrameLayout mAddScheduleButton;
-
- private TextView mAbstract;
- private LinearLayout mTags;
- private ViewGroup mTagsContainer;
- private TextView mRequirements;
- private View mHeaderBox;
- private View mHeaderContentBox;
- private View mHeaderBackgroundBox;
- private View mHeaderShadow;
- private View mDetailsContainer;
-
- private boolean mSessionCursor = false;
- private boolean mSpeakersCursor = false;
- private boolean mHasSummaryContent = false;
-
- private ImageLoader mSpeakersImageLoader, mNoPlaceholderImageLoader;
- private List<Runnable> mDeferredUiOperations = new ArrayList<Runnable>();
-
- private StringBuilder mBuffer = new StringBuilder();
-
- private int mHeaderTopClearance;
- private int mPhotoHeightPixels;
- private int mHeaderHeightPixels;
- private int mAddScheduleButtonHeightPixels;
-
- private boolean mHasPhoto;
- private View mPhotoViewContainer;
- private ImageView mPhotoView;
- boolean mGapFillShown;
- private int mSessionColor;
- private String mLivestreamUrl;
-
- private static final float GAP_FILL_DISTANCE_MULTIPLIER = 1.5f;
-
- private Runnable mTimeHintUpdaterRunnable = null;
-
- private boolean mAlreadyGaveFeedback = false;
- private boolean mIsKeynote = false;
-
- // this set stores the session IDs for which the user has dismissed the
- // "give feedback" card. This information is kept for the duration of the app's execution
- // so that if they say "No, thanks", we don't show the card again for that session while
- // the app is still executing.
- private static HashSet<String> sDismissedFeedbackCard = new HashSet<String>();
-
- private TextView mSubmitFeedbackView;
- private float mMaxHeaderElevation;
- private float mFABElevation;
-
- private int mTagColorDotSize;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- final Intent intent = BaseActivity.fragmentArgumentsToIntent(getArguments());
- mSessionUri = intent.getData();
-
- if (mSessionUri == null) {
- return;
- }
-
- mSessionId = ScheduleContract.Sessions.getSessionId(mSessionUri);
-
- setHasOptionsMenu(true);
-
- mFABElevation = getResources().getDimensionPixelSize(R.dimen.fab_elevation);
- mMaxHeaderElevation = getResources().getDimensionPixelSize(
- R.dimen.session_detail_max_header_elevation);
-
- mTagColorDotSize = getResources().getDimensionPixelSize(R.dimen.tag_color_dot_size);
-
- mHandler = new Handler();
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
-
- mRootView = (ViewGroup) inflater.inflate(R.layout.fragment_session_detail, container, false);
- mScrollViewChild = mRootView.findViewById(R.id.scroll_view_child);
- mScrollViewChild.setVisibility(View.INVISIBLE);
-
- mDetailsContainer = mRootView.findViewById(R.id.details_container);
- mHeaderBox = mRootView.findViewById(R.id.header_session);
- mHeaderContentBox = mRootView.findViewById(R.id.header_session_contents);
- mHeaderBackgroundBox = mRootView.findViewById(R.id.header_background);
- mHeaderShadow = mRootView.findViewById(R.id.header_shadow);
- mTitle = (TextView) mRootView.findViewById(R.id.session_title);
- mSubtitle = (TextView) mRootView.findViewById(R.id.session_subtitle);
- mPhotoViewContainer = mRootView.findViewById(R.id.session_photo_container);
- mPhotoView = (ImageView) mRootView.findViewById(R.id.session_photo);
-
- mPlusOneButton = (PlusOneButton) mRootView.findViewById(R.id.plus_one_button);
- mAbstract = (TextView) mRootView.findViewById(R.id.session_abstract);
- mRequirements = (TextView) mRootView.findViewById(R.id.session_requirements);
- mTags = (LinearLayout) mRootView.findViewById(R.id.session_tags);
- mTagsContainer = (ViewGroup) mRootView.findViewById(R.id.session_tags_container);
-
- mAddScheduleButton = (CheckableFrameLayout)
- mRootView.findViewById(R.id.add_schedule_button);
- mAddScheduleButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View view) {
- boolean starred = !mStarred;
- SessionsHelper helper = new SessionsHelper(getActivity());
- showStarred(starred, true);
- helper.setSessionStarred(mSessionUri, starred, mTitleString);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
- mRootView.announceForAccessibility(starred ?
- getString(R.string.session_details_a11y_session_added) :
- getString(R.string.session_details_a11y_session_removed));
- }
-
- /* [ANALYTICS:EVENT]
- * TRIGGER: Add or remove a session from My Schedule.
- * CATEGORY: 'Session'
- * ACTION: 'Starred' or 'Unstarred'
- * LABEL: Session title/subtitle.
- * [/ANALYTICS]
- */
- AnalyticsManager.sendEvent(
- "Session", starred ? "Starred" : "Unstarred", mTitleString, 0L);
- }
- });
-
- ((BaseActivity) getActivity()).getLPreviewUtils().setViewName(mPhotoView, VIEW_NAME_PHOTO);
-
- setupCustomScrolling(mRootView);
- return mRootView;
- }
-
- private void recomputePhotoAndScrollingMetrics() {
- final int actionBarSize = UIUtils.calculateActionBarSize(getActivity());
- mHeaderTopClearance = actionBarSize - mHeaderContentBox.getPaddingTop();
- mHeaderHeightPixels = mHeaderContentBox.getHeight();
-
- mPhotoHeightPixels = mHeaderTopClearance;
- if (mHasPhoto) {
- mPhotoHeightPixels = (int) (mPhotoView.getWidth() / PHOTO_ASPECT_RATIO);
- mPhotoHeightPixels = Math.min(mPhotoHeightPixels, mRootView.getHeight() * 2 / 3);
- }
-
- ViewGroup.LayoutParams lp;
- lp = mPhotoViewContainer.getLayoutParams();
- if (lp.height != mPhotoHeightPixels) {
- lp.height = mPhotoHeightPixels;
- mPhotoViewContainer.setLayoutParams(lp);
- }
-
- lp = mHeaderBackgroundBox.getLayoutParams();
- if (lp.height != mHeaderHeightPixels) {
- lp.height = mHeaderHeightPixels;
- mHeaderBackgroundBox.setLayoutParams(lp);
- }
-
- ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams)
- mDetailsContainer.getLayoutParams();
- if (mlp.topMargin != mHeaderHeightPixels + mPhotoHeightPixels) {
- mlp.topMargin = mHeaderHeightPixels + mPhotoHeightPixels;
- mDetailsContainer.setLayoutParams(mlp);
- }
-
- onScrollChanged(0, 0); // trigger scroll handling
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- if (mSpeakersImageLoader == null) {
- mSpeakersImageLoader = new ImageLoader(this.getActivity(), R.drawable.person_image_empty);
- }
- if (mNoPlaceholderImageLoader == null) {
- mNoPlaceholderImageLoader = new ImageLoader(this.getActivity());
- }
- }
-
- private void setupCustomScrolling(View rootView) {
- mScrollView = (ObservableScrollView) rootView.findViewById(R.id.scroll_view);
- mScrollView.addCallbacks(this);
- ViewTreeObserver vto = mScrollView.getViewTreeObserver();
- if (vto.isAlive()) {
- vto.addOnGlobalLayoutListener(mGlobalLayoutListener);
- }
- }
-
- @Override
- public void onDestroyView() {
- super.onDestroyView();
- if (mScrollView == null) {
- return;
- }
-
- ViewTreeObserver vto = mScrollView.getViewTreeObserver();
- if (vto.isAlive()) {
- vto.removeGlobalOnLayoutListener(mGlobalLayoutListener);
- }
- }
-
- private ViewTreeObserver.OnGlobalLayoutListener mGlobalLayoutListener
- = new ViewTreeObserver.OnGlobalLayoutListener() {
- @Override
- public void onGlobalLayout() {
- mAddScheduleButtonHeightPixels = mAddScheduleButton.getHeight();
- recomputePhotoAndScrollingMetrics();
- }
- };
-
- @Override
- public void onScrollChanged(int deltaX, int deltaY) {
- final BaseActivity activity = (BaseActivity) getActivity();
- if (activity == null) {
- return;
- }
-
- // Reposition the header bar -- it's normally anchored to the top of the content,
- // but locks to the top of the screen on scroll
- int scrollY = mScrollView.getScrollY();
-
- float newTop = Math.max(mPhotoHeightPixels, scrollY + mHeaderTopClearance);
- mHeaderBox.setTranslationY(newTop);
- mAddScheduleButton.setTranslationY(newTop + mHeaderHeightPixels
- - mAddScheduleButtonHeightPixels / 2);
-
- mHeaderBackgroundBox.setPivotY(mHeaderHeightPixels);
- int gapFillDistance = (int) (mHeaderTopClearance * GAP_FILL_DISTANCE_MULTIPLIER);
- boolean showGapFill = !mHasPhoto || (scrollY > (mPhotoHeightPixels - gapFillDistance));
- float desiredHeaderScaleY = showGapFill ?
- ((mHeaderHeightPixels + gapFillDistance + 1) * 1f / mHeaderHeightPixels)
- : 1f;
- if (!mHasPhoto) {
- mHeaderBackgroundBox.setScaleY(desiredHeaderScaleY);
- } else if (mGapFillShown != showGapFill) {
- mHeaderBackgroundBox.animate()
- .scaleY(desiredHeaderScaleY)
- .setInterpolator(new DecelerateInterpolator(2f))
- .setDuration(250)
- .start();
- }
- mGapFillShown = showGapFill;
-
- LPreviewUtilsBase lpu = activity.getLPreviewUtils();
-
- mHeaderShadow.setVisibility(lpu.hasLPreviewAPIs() ? View.GONE : View.VISIBLE);
-
- if (mHeaderTopClearance != 0) {
- // Fill the gap between status bar and header bar with color
- float gapFillProgress = Math.min(Math.max(UIUtils.getProgress(scrollY,
- mPhotoHeightPixels - mHeaderTopClearance * 2,
- mPhotoHeightPixels - mHeaderTopClearance), 0), 1);
- lpu.setViewElevation(mHeaderBackgroundBox, gapFillProgress * mMaxHeaderElevation);
- lpu.setViewElevation(mHeaderContentBox, gapFillProgress * mMaxHeaderElevation + 0.1f);
- lpu.setViewElevation(mAddScheduleButton, gapFillProgress * mMaxHeaderElevation
- + mFABElevation);
- if (!lpu.hasLPreviewAPIs()) {
- mHeaderShadow.setAlpha(gapFillProgress);
- }
- }
-
- // Move background photo (parallax effect)
- mPhotoViewContainer.setTranslationY(scrollY * 0.5f);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- updatePlusOneButton();
- if (mTimeHintUpdaterRunnable != null) {
- mHandler.postDelayed(mTimeHintUpdaterRunnable, TIME_HINT_UPDATE_INTERVAL);
- }
-
- // Refresh whether or not feedback has been submitted
- getLoaderManager().restartLoader(FeedbackQuery._TOKEN, null, this);
- }
-
- @Override
- public void onStop() {
- super.onStop();
- if (mInitStarred != mStarred) {
- if (UIUtils.getCurrentTime(getActivity()) < mSessionStart) {
- // Update Calendar event through the Calendar API on Android 4.0 or new versions.
- Intent intent = null;
- if (mStarred) {
- // Set up intent to add session to Calendar, if it doesn't exist already.
- intent = new Intent(SessionCalendarService.ACTION_ADD_SESSION_CALENDAR,
- mSessionUri);
- intent.putExtra(SessionCalendarService.EXTRA_SESSION_START,
- mSessionStart);
- intent.putExtra(SessionCalendarService.EXTRA_SESSION_END,
- mSessionEnd);
- intent.putExtra(SessionCalendarService.EXTRA_SESSION_ROOM, mRoomName);
- intent.putExtra(SessionCalendarService.EXTRA_SESSION_TITLE, mTitleString);
- } else {
- // Set up intent to remove session from Calendar, if exists.
- intent = new Intent(SessionCalendarService.ACTION_REMOVE_SESSION_CALENDAR,
- mSessionUri);
- intent.putExtra(SessionCalendarService.EXTRA_SESSION_START,
- mSessionStart);
- intent.putExtra(SessionCalendarService.EXTRA_SESSION_END,
- mSessionEnd);
- intent.putExtra(SessionCalendarService.EXTRA_SESSION_TITLE, mTitleString);
- }
- intent.setClass(getActivity(), SessionCalendarService.class);
- getActivity().startService(intent);
-
- if (mStarred) {
- setupNotification();
- }
- }
- }
- }
-
- private void setupNotification() {
- Intent scheduleIntent;
- final Context context = getActivity();
-
- // Schedule session notification
- if (UIUtils.getCurrentTime(context) < mSessionStart) {
- LOGD(TAG, "Scheduling notification about session start.");
- scheduleIntent = new Intent(
- SessionAlarmService.ACTION_SCHEDULE_STARRED_BLOCK,
- null, context, SessionAlarmService.class);
- scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_START, mSessionStart);
- scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_END, mSessionEnd);
- context.startService(scheduleIntent);
- } else {
- LOGD(TAG, "Not scheduling notification about session start, too late.");
- }
-
- // Schedule feedback notification
- if (UIUtils.getCurrentTime(context) < mSessionEnd) {
- LOGD(TAG, "Scheduling notification about session feedback.");
- scheduleIntent = new Intent(
- SessionAlarmService.ACTION_SCHEDULE_FEEDBACK_NOTIFICATION,
- null, context, SessionAlarmService.class);
- scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_ID, mSessionId);
- scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_START, mSessionStart);
- scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_END, mSessionEnd);
- scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_TITLE, mTitleString);
- scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_ROOM, mRoomName);
- scheduleIntent.putExtra(SessionAlarmService.EXTRA_SESSION_SPEAKERS, mSpeakers);
- context.startService(scheduleIntent);
- } else {
- LOGD(TAG, "Not scheduling feedback notification, too late.");
- }
- }
-
- private void updateTimeBasedUi() {
- final Context context = mRootView.getContext();
- long currentTimeMillis = UIUtils.getCurrentTime(context);
- boolean canShowLivestream = mHasLivestream;
-
- if (canShowLivestream && !mDismissedWatchLivestreamCard
- && currentTimeMillis > mSessionStart
- && currentTimeMillis <= mSessionEnd) {
- // show the "watch now" card
- showWatchNowCard();
- } else if (!mAlreadyGaveFeedback && mInitStarred && currentTimeMillis >= (mSessionEnd -
- Config.FEEDBACK_MILLIS_BEFORE_SESSION_END)
- && !sDismissedFeedbackCard.contains(mSessionId)) {
- // show the "give feedback" card
- showGiveFeedbackCard();
- }
-
- String timeHint = "";
- long countdownMillis = mSessionStart - currentTimeMillis;
-
- if (TimeUtils.hasConferenceEnded(context)) {
- // no time hint to display
- timeHint = "";
- } else if (currentTimeMillis >= mSessionEnd) {
- timeHint = context.getString(R.string.time_hint_session_ended);
- } else if (currentTimeMillis >= mSessionStart) {
- long minutesAgo = (currentTimeMillis - mSessionStart) / 60000;
- if (minutesAgo > 1) {
- timeHint = context.getString(R.string.time_hint_started_min, minutesAgo);
- } else {
- timeHint = context.getString(R.string.time_hint_started_just);
- }
- } else if (countdownMillis > 0 && countdownMillis < Config.HINT_TIME_BEFORE_SESSION) {
- long millisUntil = mSessionStart - currentTimeMillis;
- long minutesUntil = millisUntil / 60000 + (millisUntil % 1000 > 0 ? 1 : 0);
- if (minutesUntil > 1) {
- timeHint = context.getString(R.string.time_hint_about_to_start_min, minutesUntil);
- } else {
- timeHint = context.getString(R.string.time_hint_about_to_start_shortly, minutesUntil);
- }
- }
-
- final TextView timeHintView = (TextView) mRootView.findViewById(R.id.time_hint);
-
- if (!TextUtils.isEmpty(timeHint)) {
- timeHintView.setVisibility(View.VISIBLE);
- timeHintView.setText(timeHint);
- } else {
- timeHintView.setVisibility(View.GONE);
- }
- }
-
- private void setTextSelectable(TextView tv) {
- if (tv != null && !tv.isTextSelectable()) {
- tv.setTextIsSelectable(true);
- }
- }
-
- private void onFeedbackQueryComplete(Cursor cursor) {
- // Views have not been set up yet -- continue loading the rest of data
- if (mSubmitFeedbackView == null) {
- LoaderManager manager = getLoaderManager();
- manager.restartLoader(SessionsQuery._TOKEN, null, this);
- manager.restartLoader(SpeakersQuery._TOKEN, null, this);
- manager.restartLoader(TAG_METADATA_TOKEN, null, this);
- }
-
- // Is there existing feedback for this session?
- mAlreadyGaveFeedback = cursor.getCount() > 0;
-
- if (mAlreadyGaveFeedback) {
- final MessageCardView giveFeedbackCardView = (MessageCardView) mRootView.findViewById(
- R.id.give_feedback_card);
- if (giveFeedbackCardView != null) {
- giveFeedbackCardView.setVisibility(View.GONE);
- }
- if (mSubmitFeedbackView != null) {
- mSubmitFeedbackView.setVisibility(View.GONE);
- }
- }
- LOGD(TAG, "User " + (mAlreadyGaveFeedback ? "already gave" : "has not given") + " feedback for session.");
- cursor.close();
- }
-
- /**
- * Handle {@link SessionsQuery} {@link Cursor}.
- */
- private void onSessionQueryComplete(Cursor cursor) {
- mSessionCursor = true;
- if (!cursor.moveToFirst()) {
- if (isAdded()) {
- // TODO: Remove this in favor of a callbacks interface that the activity
- // can implement.
- getActivity().finish();
- }
- return;
- }
-
- mTitleString = cursor.getString(SessionsQuery.TITLE);
- mSessionColor = cursor.getInt(SessionsQuery.COLOR);
-
- if (mSessionColor == 0) {
- // no color -- use default
- mSessionColor = getResources().getColor(R.color.default_session_color);
- } else {
- // make sure it's opaque
- mSessionColor = UIUtils.setColorAlpha(mSessionColor, 255);
- }
-
- mHeaderBackgroundBox.setBackgroundColor(mSessionColor);
- ((BaseActivity) getActivity()).getLPreviewUtils().setStatusBarColor(
- UIUtils.scaleColor(mSessionColor, 0.8f, false));
-
- mLivestreamUrl = cursor.getString(SessionsQuery.LIVESTREAM_URL);
- mHasLivestream = !TextUtils.isEmpty(mLivestreamUrl);
-
- // Format the time this session occupies
- mSessionStart = cursor.getLong(SessionsQuery.START);
- mSessionEnd = cursor.getLong(SessionsQuery.END);
- mRoomName = cursor.getString(SessionsQuery.ROOM_NAME);
- mSpeakers = cursor.getString(SessionsQuery.SPEAKER_NAMES);
- String subtitle = UIUtils.formatSessionSubtitle(
- mSessionStart, mSessionEnd, mRoomName, mBuffer, getActivity());
- if (mHasLivestream) {
- subtitle += " " + UIUtils.getLiveBadgeText(getActivity(), mSessionStart, mSessionEnd);
- }
-
- mTitle.setText(mTitleString);
- mSubtitle.setText(subtitle);
-
- for (int resId : SECTION_HEADER_RES_IDS) {
- ((TextView) mRootView.findViewById(resId)).setTextColor(mSessionColor);
- }
-
- mPhotoViewContainer.setBackgroundColor(UIUtils.scaleSessionColorToDefaultBG(mSessionColor));
-
- String photo = cursor.getString(SessionsQuery.PHOTO_URL);
- if (!TextUtils.isEmpty(photo)) {
- mHasPhoto = true;
- mNoPlaceholderImageLoader.loadImage(photo, mPhotoView, new RequestListener<String>() {
- @Override
- public void onException(Exception e, String url, Target target) {
- mHasPhoto = false;
- recomputePhotoAndScrollingMetrics();
- }
-
- @Override
- public void onImageReady(String url, Target target, boolean b, boolean b2) {
- // Trigger image transition
- recomputePhotoAndScrollingMetrics();
- }
- });
- recomputePhotoAndScrollingMetrics();
- } else {
- mHasPhoto = false;
- recomputePhotoAndScrollingMetrics();
- }
-
- mUrl = cursor.getString(SessionsQuery.URL);
- if (TextUtils.isEmpty(mUrl)) {
- mUrl = "";
- }
-
- mHashTag = cursor.getString(SessionsQuery.HASHTAG);
- if (!TextUtils.isEmpty(mHashTag)) {
- enableSocialStreamMenuItemDeferred();
- }
-
- mRoomId = cursor.getString(SessionsQuery.ROOM_ID);
-
- final boolean inMySchedule = cursor.getInt(SessionsQuery.IN_MY_SCHEDULE) != 0;
-
- setupShareMenuItemDeferred();
-
- // Handle Keynote as a special case, where the user cannot remove it
- // from the schedule (it is auto added to schedule on sync)
- mTagsString = cursor.getString(SessionsQuery.TAGS);
- mIsKeynote = mTagsString.contains(Config.Tags.SPECIAL_KEYNOTE);
- mAddScheduleButton.setVisibility(
- (AccountUtils.hasActiveAccount(getActivity()) && !mIsKeynote)
- ? View.VISIBLE : View.INVISIBLE);
-
- tryRenderTags();
-
- if (!mIsKeynote) {
- showStarredDeferred(mInitStarred = inMySchedule, false);
- }
-
- final String sessionAbstract = cursor.getString(SessionsQuery.ABSTRACT);
- if (!TextUtils.isEmpty(sessionAbstract)) {
- UIUtils.setTextMaybeHtml(mAbstract, sessionAbstract);
- mAbstract.setVisibility(View.VISIBLE);
- mHasSummaryContent = true;
- } else {
- mAbstract.setVisibility(View.GONE);
- }
-
- updatePlusOneButton();
-
- // Build requirements section
- final View requirementsBlock = mRootView.findViewById(R.id.session_requirements_block);
- final String sessionRequirements = cursor.getString(SessionsQuery.REQUIREMENTS);
- if (!TextUtils.isEmpty(sessionRequirements)) {
- UIUtils.setTextMaybeHtml(mRequirements, sessionRequirements);
- requirementsBlock.setVisibility(View.VISIBLE);
- mHasSummaryContent = true;
- } else {
- requirementsBlock.setVisibility(View.GONE);
- }
-
- // Build related videos section
- final ViewGroup relatedVideosBlock = (ViewGroup) mRootView.findViewById(R.id.related_videos_block);
- relatedVideosBlock.setVisibility(View.GONE);
-
-
- // Build links section
- buildLinksSection(cursor);
-
- // Show empty message when all data is loaded, and nothing to show
- if (mSpeakersCursor && !mHasSummaryContent) {
- mRootView.findViewById(android.R.id.empty).setVisibility(View.VISIBLE);
- }
-
- updateTimeBasedUi();
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- onScrollChanged(0, 0); // trigger scroll handling
- mScrollViewChild.setVisibility(View.VISIBLE);
- //mAbstract.setTextIsSelectable(true);
- }
- });
-
- mTimeHintUpdaterRunnable = new Runnable() {
- @Override
- public void run() {
- if (isAdded()) {
- updateTimeBasedUi();
- mHandler.postDelayed(mTimeHintUpdaterRunnable, TIME_HINT_UPDATE_INTERVAL);
- }
- }
- };
- mHandler.postDelayed(mTimeHintUpdaterRunnable, TIME_HINT_UPDATE_INTERVAL);
- }
-
- private void tryRenderTags() {
- if (mTagMetadata == null || mTagsString == null || !isAdded()) {
- return;
- }
-
- if (TextUtils.isEmpty(mTagsString)) {
- mTagsContainer.setVisibility(View.GONE);
- } else {
- mTagsContainer.setVisibility(View.VISIBLE);
- mTags.removeAllViews();
- LayoutInflater inflater = LayoutInflater.from(getActivity());
- String[] tagIds = mTagsString.split(",");
-
- List<TagMetadata.Tag> tags = new ArrayList<TagMetadata.Tag>();
- for (String tagId : tagIds) {
- if (Config.Tags.SESSIONS.equals(tagId) ||
- Config.Tags.SPECIAL_KEYNOTE.equals(tagId)) {
- continue;
- }
-
- TagMetadata.Tag tag = mTagMetadata.getTag(tagId);
- if (tag == null) {
- continue;
- }
-
- tags.add(tag);
- }
-
- if (tags.size() == 0) {
- mTagsContainer.setVisibility(View.GONE);
- return;
- }
-
- Collections.sort(tags, TagMetadata.TAG_DISPLAY_ORDER_COMPARATOR);
-
- for (final TagMetadata.Tag tag : tags) {
- TextView chipView = (TextView) inflater.inflate(
- R.layout.include_session_tag_chip, mTags, false);
- chipView.setText(tag.getName());
-
- if (Config.Tags.CATEGORY_TOPIC.equals(tag.getCategory())) {
- ShapeDrawable colorDrawable = new ShapeDrawable(new OvalShape());
- colorDrawable.setIntrinsicWidth(mTagColorDotSize);
- colorDrawable.setIntrinsicHeight(mTagColorDotSize);
- colorDrawable.getPaint().setStyle(Paint.Style.FILL);
- chipView.setCompoundDrawablesWithIntrinsicBounds(colorDrawable,
- null, null, null);
- colorDrawable.getPaint().setColor(tag.getColor());
- }
-
- chipView.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View view) {
- getActivity().finish(); // TODO: better encapsulation
- Intent intent = new Intent(getActivity(), BrowseSessionsActivity.class)
- .putExtra(BrowseSessionsActivity.EXTRA_FILTER_TAG, tag.getId())
- .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
- startActivity(intent);
- }
- });
-
- mTags.addView(chipView);
- }
- }
- }
-
- private void buildLinksSection(Cursor cursor) {
- final Context context = mRootView.getContext();
-
- // Compile list of links (I/O live link, submit feedback, and normal links)
- ViewGroup linkContainer = (ViewGroup) mRootView.findViewById(R.id.links_container);
- linkContainer.removeAllViews();
-
-
- // Build links section
- // the Object can be either a string URL or an Intent
- List<Pair<Integer, Object>> links = new ArrayList<Pair<Integer, Object>>();
-
- long currentTimeMillis = UIUtils.getCurrentTime(context);
- if (mHasLivestream
- && currentTimeMillis > mSessionStart
- && currentTimeMillis <= mSessionEnd) {
- links.add(new Pair<Integer, Object>(
- R.string.session_link_livestream,
- getWatchLiveIntent(context)));
- }
-
- // Add session feedback link, if appropriate
- if (!mAlreadyGaveFeedback && currentTimeMillis > mSessionEnd
- - Config.FEEDBACK_MILLIS_BEFORE_SESSION_END) {
- links.add(new Pair<Integer, Object>(
- R.string.session_feedback_submitlink,
- getFeedbackIntent()
- ));
- }
-
- for (int i = 0; i < SessionsQuery.LINKS_INDICES.length; i++) {
- final String linkUrl = cursor.getString(SessionsQuery.LINKS_INDICES[i]);
- if (TextUtils.isEmpty(linkUrl)) {
- continue;
- }
-
- links.add(new Pair<Integer, Object>(
- SessionsQuery.LINKS_TITLES[i],
- new Intent(Intent.ACTION_VIEW, Uri.parse(linkUrl))
- .addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
- ));
- }
-
- // Render links
- if (links.size() > 0) {
- LayoutInflater inflater = LayoutInflater.from(context);
- int columns = context.getResources().getInteger(R.integer.links_columns);
-
- LinearLayout currentLinkRowView = null;
- for (int i = 0; i < links.size(); i++) {
- final Pair<Integer, Object> link = links.get(i);
-
- // Create link view
- TextView linkView = (TextView) inflater.inflate(R.layout.list_item_session_link,
- linkContainer, false);
- if (link.first == R.string.session_feedback_submitlink) {
- mSubmitFeedbackView = linkView;
- }
- linkView.setText(getString(link.first));
- linkView.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- fireLinkEvent(link.first);
- Intent intent=null;
- if (link.second instanceof Intent) {
- intent = (Intent) link.second;
- } else if (link.second instanceof String) {
- intent = new Intent(Intent.ACTION_VIEW, Uri.parse((String) link.second))
- .addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
- }
- try {
- startActivity(intent);
- } catch (ActivityNotFoundException ignored) {
- }
- }
- });
-
- // Place it inside a container
- if (columns == 1) {
- linkContainer.addView(linkView);
- } else {
- // create a new link row
- if (i % columns == 0) {
- currentLinkRowView = (LinearLayout) inflater.inflate(
- R.layout.include_link_row, linkContainer, false);
- currentLinkRowView.setWeightSum(columns);
- linkContainer.addView(currentLinkRowView);
- }
-
- ((LinearLayout.LayoutParams) linkView.getLayoutParams()).width = 0;
- ((LinearLayout.LayoutParams) linkView.getLayoutParams()).weight = 1;
- currentLinkRowView.addView(linkView);
- }
- }
-
- mRootView.findViewById(R.id.session_links_header).setVisibility(View.VISIBLE);
- mRootView.findViewById(R.id.links_container).setVisibility(View.VISIBLE);
-
- } else {
- mRootView.findViewById(R.id.session_links_header).setVisibility(View.GONE);
- mRootView.findViewById(R.id.links_container).setVisibility(View.GONE);
- }
-
- }
-
- @Override
- public void onPause() {
- super.onPause();
- if (mTimeHintUpdaterRunnable != null) {
- mHandler.removeCallbacks(mTimeHintUpdaterRunnable);
- }
- }
-
- private Intent getWatchLiveIntent(Context context) {
- LPreviewUtilsBase lpu = ((BaseActivity) getActivity()).getLPreviewUtils();
- if (lpu.hasLPreviewAPIs() && YouTubeIntents.canResolvePlayVideoIntent(context)) {
- String youtubeVideoId = SessionLivestreamActivity.getVideoIdFromUrl(mLivestreamUrl);
- return YouTubeIntents.createPlayVideoIntentWithOptions(
- context, youtubeVideoId, true, false);
- }
- return new Intent(Intent.ACTION_VIEW, mSessionUri).setClass(context,
- SessionLivestreamActivity.class);
- }
-
- private void updatePlusOneButton() {
- if (mPlusOneButton == null) {
- return;
- }
-
- if (!TextUtils.isEmpty(mUrl) && !mIsKeynote) {
- mPlusOneButton.initialize(mUrl, 0);
- mPlusOneButton.setVisibility(View.VISIBLE);
- } else {
- mPlusOneButton.setVisibility(View.GONE);
- }
- }
-
- private void showWatchNowCard() {
- final MessageCardView messageCardView = (MessageCardView) mRootView.findViewById(
- R.id.live_now_card);
- messageCardView.show();
- messageCardView.setListener(new MessageCardView.OnMessageCardButtonClicked() {
- @Override
- public void onMessageCardButtonClicked(String tag) {
- if ("WATCH_NOW".equals(tag)) {
- Intent intent = getWatchLiveIntent(getActivity());
- startActivity(intent);
- } else {
- mDismissedWatchLivestreamCard = true;
- messageCardView.dismiss();
- }
- }
- });
- }
-
- private void showGiveFeedbackCard() {
- final MessageCardView messageCardView = (MessageCardView) mRootView.findViewById(
- R.id.give_feedback_card);
- messageCardView.show();
- messageCardView.setListener(new MessageCardView.OnMessageCardButtonClicked() {
- @Override
- public void onMessageCardButtonClicked(String tag) {
- if ("GIVE_FEEDBACK".equals(tag)) {
- /* [ANALYTICS:EVENT]
- * TRIGGER: Click on the Send Feedback action on the Session Details page.
- * CATEGORY: 'Session'
- * ACTION: 'Feedback'
- * LABEL: session title/subtitle
- * [/ANALYTICS]
- */
- AnalyticsManager.sendEvent("Session", "Feedback", mTitleString, 0L);
- Intent intent = getFeedbackIntent();
- startActivity(intent);
- } else {
- sDismissedFeedbackCard.add(mSessionId);
- messageCardView.dismiss();
- }
- }
- });
- }
-
- private Intent getFeedbackIntent() {
- return new Intent(Intent.ACTION_VIEW, mSessionUri, getActivity(),
- SessionFeedbackActivity.class);
- }
-
- private void enableSocialStreamMenuItemDeferred() {
- mDeferredUiOperations.add(new Runnable() {
- @Override
- public void run() {
- mSocialStreamMenuItem.setVisible(true);
- }
- });
- tryExecuteDeferredUiOperations();
- }
-
- private void showStarredDeferred(final boolean starred, final boolean allowAnimate) {
- mDeferredUiOperations.add(new Runnable() {
- @Override
- public void run() {
- showStarred(starred, allowAnimate);
- }
- });
- tryExecuteDeferredUiOperations();
- }
-
- private void showStarred(boolean starred, boolean allowAnimate) {
- mStarred = starred;
-
- mAddScheduleButton.setChecked(mStarred, allowAnimate);
-
- ImageView iconView = (ImageView) mAddScheduleButton.findViewById(R.id.add_schedule_icon);
- ((BaseActivity) getActivity()).getLPreviewUtils().setOrAnimatePlusCheckIcon(
- iconView, starred, allowAnimate);
- mAddScheduleButton.setContentDescription(getString(starred
- ? R.string.remove_from_schedule_desc
- : R.string.add_to_schedule_desc));
- }
-
- private void setupShareMenuItemDeferred() {
- mDeferredUiOperations.add(new Runnable() {
- @Override
- public void run() {
- new SessionsHelper(getActivity()).tryConfigureShareMenuItem(mShareMenuItem,
- R.string.share_template, mTitleString, mHashTag, mUrl);
- }
- });
- tryExecuteDeferredUiOperations();
- }
-
- private void tryExecuteDeferredUiOperations() {
- if (mSocialStreamMenuItem != null) {
- for (Runnable r : mDeferredUiOperations) {
- r.run();
- }
- mDeferredUiOperations.clear();
- }
- }
-
- private void onSpeakersQueryComplete(Cursor cursor) {
- mSpeakersCursor = true;
- final ViewGroup speakersGroup = (ViewGroup)
- mRootView.findViewById(R.id.session_speakers_block);
-
- // Remove all existing speakers (everything but first child, which is the header)
- for (int i = speakersGroup.getChildCount() - 1; i >= 1; i--) {
- speakersGroup.removeViewAt(i);
- }
-
- final LayoutInflater inflater = getActivity().getLayoutInflater();
-
- boolean hasSpeakers = false;
-
- while (cursor.moveToNext()) {
- final String speakerName = cursor.getString(SpeakersQuery.SPEAKER_NAME);
- if (TextUtils.isEmpty(speakerName)) {
- continue;
- }
-
- final String speakerImageUrl = cursor.getString(SpeakersQuery.SPEAKER_IMAGE_URL);
- final String speakerCompany = cursor.getString(SpeakersQuery.SPEAKER_COMPANY);
- final String speakerUrl = cursor.getString(SpeakersQuery.SPEAKER_URL);
- final String speakerAbstract = cursor.getString(SpeakersQuery.SPEAKER_ABSTRACT);
-
- String speakerHeader = speakerName;
- if (!TextUtils.isEmpty(speakerCompany)) {
- speakerHeader += ", " + speakerCompany;
- }
-
- final View speakerView = inflater
- .inflate(R.layout.speaker_detail, speakersGroup, false);
- final TextView speakerHeaderView = (TextView) speakerView
- .findViewById(R.id.speaker_header);
- final ImageView speakerImageView = (ImageView) speakerView
- .findViewById(R.id.speaker_image);
- final TextView speakerAbstractView = (TextView) speakerView
- .findViewById(R.id.speaker_abstract);
-
- if (!TextUtils.isEmpty(speakerImageUrl) && mSpeakersImageLoader != null) {
- mSpeakersImageLoader.loadImage(speakerImageUrl, speakerImageView);
- }
-
- speakerHeaderView.setText(speakerHeader);
- speakerImageView.setContentDescription(
- getString(R.string.speaker_googleplus_profile, speakerHeader));
- UIUtils.setTextMaybeHtml(speakerAbstractView, speakerAbstract);
-
- if (!TextUtils.isEmpty(speakerUrl)) {
- speakerImageView.setEnabled(true);
- speakerImageView.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View view) {
- Intent speakerProfileIntent = new Intent(Intent.ACTION_VIEW,
- Uri.parse(speakerUrl));
- speakerProfileIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
- UIUtils.preferPackageForIntent(getActivity(), speakerProfileIntent,
- UIUtils.GOOGLE_PLUS_PACKAGE_NAME);
- startActivity(speakerProfileIntent);
- }
- });
- } else {
- speakerImageView.setEnabled(false);
- speakerImageView.setOnClickListener(null);
- }
-
- speakersGroup.addView(speakerView);
- hasSpeakers = true;
- mHasSummaryContent = true;
- }
-
- speakersGroup.setVisibility(hasSpeakers ? View.VISIBLE : View.GONE);
-
- // Show empty message when all data is loaded, and nothing to show
- if (mSessionCursor && !mHasSummaryContent) {
- mRootView.findViewById(android.R.id.empty).setVisibility(View.VISIBLE);
- }
- }
-
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- inflater.inflate(R.menu.session_detail, menu);
- mSocialStreamMenuItem = menu.findItem(R.id.menu_social_stream);
- mShareMenuItem = menu.findItem(R.id.menu_share);
- tryExecuteDeferredUiOperations();
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- SessionsHelper helper = new SessionsHelper(getActivity());
- switch (item.getItemId()) {
- case R.id.menu_map_room:
- /* [ANALYTICS:EVENT]
- * TRIGGER: Click on the Map action on the Session Details page.
- * CATEGORY: 'Session'
- * ACTION: 'Map'
- * LABEL: session title/subtitle
- * [/ANALYTICS]
- */
- AnalyticsManager.sendEvent("Session", "Map", mTitleString, 0L);
- helper.startMapActivity(mRoomId);
- return true;
-
- case R.id.menu_share:
- // On ICS+ devices, we normally won't reach this as ShareActionProvider will handle
- // sharing.
- helper.shareSession(getActivity(), R.string.share_template, mTitleString,
- mHashTag, mUrl);
- return true;
-
- case R.id.menu_social_stream:
- if (!TextUtils.isEmpty(mHashTag)) {
- /* [ANALYTICS:EVENT]
- * TRIGGER: Click on the Social Stream action on the Session Details page.
- * CATEGORY: 'Session'
- * ACTION: 'Stream'
- * LABEL: session title/subtitle
- * [/ANALYTICS]
- */
- AnalyticsManager.sendEvent("Session", "Stream", mTitleString, 0L);
- UIUtils.showHashtagStream(getActivity(), mHashTag);
- }
- return true;
- }
- return false;
- }
-
- @Override
- public void onPrepareOptionsMenu(Menu menu) {
- }
-
- @Override
- public void onDestroyOptionsMenu() {
- }
-
- /*
- * Event structure:
- * Category -> "Session Details"
- * Action -> Link Text
- * Label -> Session's Title
- * Value -> 0.
- */
- void fireLinkEvent(int actionId) {
- /* [ANALYTICS:EVENT]
- * TRIGGER: Click on a link on the Session Details page.
- * CATEGORY: 'Session'
- * ACTION: The link's name ("Watch Live", "Follow us on Google+", etc)
- * LABEL: The session's title/subtitle.
- * [/ANALYTICS]
- */
- AnalyticsManager.sendEvent("Session", getString(actionId), mTitleString, 0L);
- }
-
- /**
- * {@link com.google.samples.apps.iosched.provider.ScheduleContract.Sessions} query parameters.
- */
- private interface SessionsQuery {
- int _TOKEN = 0x1;
-
- String[] PROJECTION = {
- ScheduleContract.Sessions.SESSION_START,
- ScheduleContract.Sessions.SESSION_END,
- ScheduleContract.Sessions.SESSION_LEVEL,
- ScheduleContract.Sessions.SESSION_TITLE,
- ScheduleContract.Sessions.SESSION_ABSTRACT,
- ScheduleContract.Sessions.SESSION_REQUIREMENTS,
- ScheduleContract.Sessions.SESSION_IN_MY_SCHEDULE,
- ScheduleContract.Sessions.SESSION_HASHTAG,
- ScheduleContract.Sessions.SESSION_URL,
- ScheduleContract.Sessions.SESSION_YOUTUBE_URL,
- ScheduleContract.Sessions.SESSION_PDF_URL,
- ScheduleContract.Sessions.SESSION_NOTES_URL,
- ScheduleContract.Sessions.SESSION_LIVESTREAM_URL,
- ScheduleContract.Sessions.SESSION_MODERATOR_URL,
- ScheduleContract.Sessions.ROOM_ID,
- ScheduleContract.Rooms.ROOM_NAME,
- ScheduleContract.Sessions.SESSION_COLOR,
- ScheduleContract.Sessions.SESSION_PHOTO_URL,
- ScheduleContract.Sessions.SESSION_RELATED_CONTENT,
- ScheduleContract.Sessions.SESSION_TAGS,
- ScheduleContract.Sessions.SESSION_SPEAKER_NAMES
- };
-
- int START = 0;
- int END = 1;
- int LEVEL = 2;
- int TITLE = 3;
- int ABSTRACT = 4;
- int REQUIREMENTS = 5;
- int IN_MY_SCHEDULE = 6;
- int HASHTAG = 7;
- int URL = 8;
- int YOUTUBE_URL = 9;
- int PDF_URL = 10;
- int NOTES_URL = 11;
- int LIVESTREAM_URL = 12;
- int MODERATOR_URL = 13;
- int ROOM_ID = 14;
- int ROOM_NAME = 15;
- int COLOR = 16;
- int PHOTO_URL = 17;
- int RELATED_CONTENT = 18;
- int TAGS = 19;
- int SPEAKER_NAMES = 20;
-
- int[] LINKS_INDICES = {
- YOUTUBE_URL,
- MODERATOR_URL,
- PDF_URL,
- NOTES_URL,
- };
-
- int[] LINKS_TITLES = {
- R.string.session_link_youtube,
- R.string.session_link_moderator,
- R.string.session_link_pdf,
- R.string.session_link_notes,
- };
- }
-
- private interface SpeakersQuery {
- int _TOKEN = 0x3;
-
- String[] PROJECTION = {
- ScheduleContract.Speakers.SPEAKER_NAME,
- ScheduleContract.Speakers.SPEAKER_IMAGE_URL,
- ScheduleContract.Speakers.SPEAKER_COMPANY,
- ScheduleContract.Speakers.SPEAKER_ABSTRACT,
- ScheduleContract.Speakers.SPEAKER_URL,
- };
-
- int SPEAKER_NAME = 0;
- int SPEAKER_IMAGE_URL = 1;
- int SPEAKER_COMPANY = 2;
- int SPEAKER_ABSTRACT = 3;
- int SPEAKER_URL = 4;
- }
-
- private interface FeedbackQuery {
- int _TOKEN = 0x4;
-
- String[] PROJECTION = {
- ScheduleContract.Feedback.SESSION_ID
- };
- }
-
- private static final int TAG_METADATA_TOKEN = 0x5;
-
- @Override
- public Loader<Cursor> onCreateLoader(int id, Bundle data) {
- CursorLoader loader = null;
- if (id == SessionsQuery._TOKEN){
- loader = new CursorLoader(getActivity(), mSessionUri, SessionsQuery.PROJECTION, null,
- null, null);
- } else if (id == SpeakersQuery._TOKEN && mSessionUri != null){
- Uri speakersUri = ScheduleContract.Sessions.buildSpeakersDirUri(mSessionId);
- loader = new CursorLoader(getActivity(), speakersUri, SpeakersQuery.PROJECTION, null,
- null, ScheduleContract.Speakers.DEFAULT_SORT);
- } else if (id == FeedbackQuery._TOKEN) {
- Uri feedbackUri = ScheduleContract.Feedback.buildFeedbackUri(mSessionId);
- loader = new CursorLoader(getActivity(), feedbackUri, FeedbackQuery.PROJECTION, null,
- null, null);
- } else if (id == TAG_METADATA_TOKEN) {
- loader = TagMetadata.createCursorLoader(getActivity());
- }
- return loader;
- }
-
- @Override
- public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
- if (!isAdded()) {
- return;
- }
-
- if (loader.getId() == SessionsQuery._TOKEN) {
- onSessionQueryComplete(cursor);
- } else if (loader.getId() == SpeakersQuery._TOKEN) {
- onSpeakersQueryComplete(cursor);
- } else if (loader.getId() == FeedbackQuery._TOKEN) {
- onFeedbackQueryComplete(cursor);
- } else if (loader.getId() == TAG_METADATA_TOKEN) {
- mTagMetadata = new TagMetadata(cursor);
- cursor.close();
- tryRenderTags();
- } else {
- cursor.close();
- }
- }
-
- @Override
- public void onLoaderReset(Loader<Cursor> loader) {}
-}
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/SessionFeedbackActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/SessionFeedbackActivity.java
index e4a9f3a..d2bf0fb 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/SessionFeedbackActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/SessionFeedbackActivity.java
@@ -16,10 +16,12 @@
package com.google.samples.apps.iosched.ui;
+import android.app.Fragment;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
-import android.app.Fragment;
+import android.support.v7.widget.Toolbar;
+import android.view.View;
import com.google.samples.apps.iosched.R;
import com.google.samples.apps.iosched.provider.ScheduleContract;
@@ -39,11 +41,23 @@
}
mSessionId = ScheduleContract.Sessions.getSessionId(getIntent().getData());
+
+ Toolbar toolbar = getActionBarToolbar();
+ toolbar.setTitle(R.string.title_session_feedback);
+ toolbar.setNavigationIcon(R.drawable.ic_up);
+ toolbar.setNavigationOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ navigateUpToFromChild(SessionFeedbackActivity.this,
+ new Intent(Intent.ACTION_VIEW,
+ ScheduleContract.Sessions.buildSessionUri(mSessionId)));
+ }
+ });
}
@Override
protected int getContentViewResId() {
- return R.layout.activity_letterboxed_when_large;
+ return R.layout.activity_feedback;
}
@Override
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/SessionFeedbackFragment.java b/android/src/main/java/com/google/samples/apps/iosched/ui/SessionFeedbackFragment.java
index 0f59861..e5e0d92 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/SessionFeedbackFragment.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/SessionFeedbackFragment.java
@@ -18,7 +18,6 @@
import android.app.Fragment;
import android.app.LoaderManager;
-import android.content.ContentValues;
import android.content.CursorLoader;
import android.content.Intent;
import android.content.Loader;
@@ -30,7 +29,6 @@
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.RatingBar;
-import android.widget.SeekBar;
import android.widget.TextView;
import com.google.android.gms.common.ConnectionResult;
@@ -54,7 +52,7 @@
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener {
- private static final String TAG = makeLogTag(SessionDetailFragment.class);
+ private static final String TAG = makeLogTag(SessionDetailActivity.class);
// Set this boolean extra to true to show a variable height header
public static final String EXTRA_VARIABLE_HEIGHT_HEADER =
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/SessionLivestreamActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/SessionLivestreamActivity.java
index 73cc886..eec9202 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/SessionLivestreamActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/SessionLivestreamActivity.java
@@ -765,7 +765,7 @@
}
private int getActionBarHeightPx() {
- int[] attrs = new int[] { android.R.attr.actionBarSize };
+ int[] attrs = new int[] { R.attr.actionBarSize };
return (int) getTheme().obtainStyledAttributes(attrs).getDimension(0, 0f);
}
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/SessionsFragment.java b/android/src/main/java/com/google/samples/apps/iosched/ui/SessionsFragment.java
index 5c0793c..6427cd4 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/SessionsFragment.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/SessionsFragment.java
@@ -20,8 +20,14 @@
import android.app.Fragment;
import android.app.ListFragment;
import android.app.LoaderManager;
-import android.content.*;
+import android.content.Context;
+import android.content.CursorLoader;
+import android.content.Intent;
+import android.content.Loader;
+import android.content.SharedPreferences;
import android.database.Cursor;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -41,6 +47,8 @@
import android.widget.TextView;
import android.widget.Toast;
+import com.bumptech.glide.GenericRequestBuilder;
+import com.bumptech.glide.ListPreloader;
import com.google.samples.apps.iosched.Config;
import com.google.samples.apps.iosched.R;
import com.google.samples.apps.iosched.model.TagMetadata;
@@ -48,7 +56,12 @@
import com.google.samples.apps.iosched.ui.widget.CollectionView;
import com.google.samples.apps.iosched.ui.widget.CollectionViewCallbacks;
import com.google.samples.apps.iosched.ui.widget.MessageCardView;
-import com.google.samples.apps.iosched.util.*;
+import com.google.samples.apps.iosched.util.ImageLoader;
+import com.google.samples.apps.iosched.util.PrefUtils;
+import com.google.samples.apps.iosched.util.ThrottledContentObserver;
+import com.google.samples.apps.iosched.util.TimeUtils;
+import com.google.samples.apps.iosched.util.UIUtils;
+import com.google.samples.apps.iosched.util.WiFiUtils;
import java.text.DateFormat;
import java.util.ArrayList;
@@ -56,10 +69,11 @@
import java.util.List;
import java.util.TimeZone;
-import com.bumptech.glide.GenericRequestBuilder;
-import com.bumptech.glide.ListPreloader;
-
-import static com.google.samples.apps.iosched.util.LogUtils.*;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGE;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGV;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGW;
+import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
import static com.google.samples.apps.iosched.util.UIUtils.buildStyledSnippet;
/**
@@ -72,6 +86,10 @@
private static final String TAG = makeLogTag(SessionsFragment.class);
+ // Disable track branding
+ public static final String EXTRA_NO_TRACK_BRANDING =
+ "com.google.android.iosched.extra.NO_TRACK_BRANDING";
+
private static final String STATE_SESSION_QUERY_TOKEN = "session_query_token";
private static final String STATE_ARGUMENTS = "arguments";
@@ -92,6 +110,7 @@
private Uri mCurrentUri = ScheduleContract.Sessions.CONTENT_URI;
private Cursor mCursor;
private boolean mIsSearchCursor;
+ private boolean mNoTrackBranding;
// this variable is relevant when we start the sessions loader, and indicates the desired
// behavior when load finishes: if true, this is a full reload (for example, because filters
@@ -231,6 +250,7 @@
mArguments = savedInstanceState.getParcelable(STATE_ARGUMENTS);
if (mArguments != null) {
mCurrentUri = mArguments.getParcelable("_uri");
+ mNoTrackBranding = mArguments.getBoolean(EXTRA_NO_TRACK_BRANDING);
}
if (mSessionQueryToken > 0) {
@@ -292,6 +312,8 @@
mCurrentUri = ScheduleContract.Sessions.CONTENT_URI;
}
+ mNoTrackBranding = mArguments.getBoolean(EXTRA_NO_TRACK_BRANDING);
+
if (ScheduleContract.Sessions.isSearchUri(mCurrentUri)) {
mSessionQueryToken = SessionsQuery.SEARCH_TOKEN;
} else {
@@ -694,6 +716,7 @@
int sessionColor = mCursor.getInt(SessionsQuery.COLOR);
sessionColor = sessionColor == 0 ? getResources().getColor(R.color.default_session_color)
: sessionColor;
+ int darkSessionColor = 0;
final String snippet = mIsSearchCursor ? mCursor.getString(SessionsQuery.SNIPPET) : null;
final Spannable styledSnippet = mIsSearchCursor ? buildStyledSnippet(snippet) : null;
final boolean starred = mCursor.getInt(SessionsQuery.IN_MY_SCHEDULE) != 0;
@@ -717,14 +740,18 @@
final TextView snippetView = (TextView) view.findViewById(R.id.session_snippet);
final TextView abstractView = (TextView) view.findViewById(R.id.session_abstract);
final TextView categoryView = (TextView) view.findViewById(R.id.session_category);
- final View boxView = view.findViewById(R.id.info_box);
final View sessionTargetView = view.findViewById(R.id.session_target);
if (sessionColor == 0) {
// use default
sessionColor = mDefaultSessionColor;
}
- sessionColor = UIUtils.scaleSessionColorToDefaultBG(sessionColor);
+
+ if (mNoTrackBranding) {
+ sessionColor = getResources().getColor(R.color.no_track_branding_session_color);
+ }
+
+ darkSessionColor = UIUtils.scaleSessionColorToDefaultBG(sessionColor);
ImageView photoView = (ImageView) view.findViewById(R.id.session_photo_colored);
if (photoView != null) {
@@ -738,23 +765,23 @@
});
}
// colored
- photoView.setColorFilter(UIUtils.setColorAlpha(sessionColor,
- UIUtils.SESSION_PHOTO_SCRIM_ALPHA));
+ photoView.setColorFilter(mNoTrackBranding
+ ? new PorterDuffColorFilter(
+ getResources().getColor(R.color.no_track_branding_session_tile_overlay),
+ PorterDuff.Mode.SRC_ATOP)
+ : UIUtils.makeSessionImageScrimColorFilter(darkSessionColor));
} else {
photoView = (ImageView) view.findViewById(R.id.session_photo);
}
- ((BaseActivity) getActivity()).getLPreviewUtils().setViewName(photoView,
- "photo_" + sessionId);
-
-
+ ViewCompat.setTransitionName(photoView, "photo_" + sessionId);
// when we load a photo, it will fade in from transparent so the
// background of the container must be the session color to avoid a white flash
ViewParent parent = photoView.getParent();
if (parent != null && parent instanceof View) {
- ((View) parent).setBackgroundColor(sessionColor);
+ ((View) parent).setBackgroundColor(darkSessionColor);
} else {
- photoView.setBackgroundColor(sessionColor);
+ photoView.setBackgroundColor(darkSessionColor);
}
String photo = mCursor.getString(SessionsQuery.PHOTO_URL);
@@ -818,11 +845,6 @@
abstractView.setText(mBuffer.toString());
}
- // in expanded mode, the box background color follows the session color
- if (useExpandedMode()) {
- boxView.setBackgroundColor(sessionColor);
- }
-
// show or hide the "in my schedule" indicator
view.findViewById(R.id.indicator_in_schedule).setVisibility(starred ? View.VISIBLE
: View.INVISIBLE);
@@ -840,7 +862,7 @@
if (cardContainer != null && abstractContainer != null) {
cardContainer.setVisibility(cardShown ? View.VISIBLE : View.GONE);
abstractContainer.setVisibility(cardShown ? View.GONE : View.VISIBLE);
- abstractContainer.setBackgroundColor(sessionColor);
+ abstractContainer.setBackgroundColor(darkSessionColor);
}
}
@@ -891,7 +913,6 @@
}
private void setupLocalOrRemoteCard(final MessageCardView card) {
- card.overrideBackground(R.drawable.card_bg);
card.setText(getString(R.string.question_local_or_remote));
card.setButton(0, getString(R.string.attending_remotely), CARD_ANSWER_ATTENDING_REMOTELY,
false, 0);
@@ -924,7 +945,6 @@
}
private void setupWifiOfferCard(final MessageCardView card) {
- card.overrideBackground(R.drawable.card_bg);
card.setText(getString(TimeUtils.hasConferenceStarted(getActivity()) ?
R.string.question_setup_wifi_after_i_o_start :
R.string.question_setup_wifi_before_i_o_start));
@@ -955,13 +975,11 @@
}
private void setupIOExtendedCard(final MessageCardView card) {
- card.overrideBackground(R.drawable.card_bg);
card.setText(getString(R.string.question_i_o_extended));
card.setButton(0, getString(R.string.no_thanks), CARD_ANSWER_NO,
false, 0);
card.setButton(1, getString(R.string.browse_events), CARD_ANSWER_YES,
true, 0);
- final Context context = getActivity().getApplicationContext();
card.setListener(new MessageCardView.OnMessageCardButtonClicked() {
@Override
public void onMessageCardButtonClicked(final String tag) {
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/SettingsActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/SettingsActivity.java
index 1e2e1a7..4e138c8 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/SettingsActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/SettingsActivity.java
@@ -16,12 +16,14 @@
package com.google.samples.apps.iosched.ui;
-import android.annotation.TargetApi;
+import android.content.ComponentName;
import android.content.Intent;
import android.content.SharedPreferences;
-import android.os.Build;
import android.os.Bundle;
-import android.preference.PreferenceActivity;
+import android.preference.PreferenceFragment;
+import android.support.v4.content.IntentCompat;
+import android.support.v7.widget.Toolbar;
+import android.view.View;
import com.google.samples.apps.iosched.R;
import com.google.samples.apps.iosched.service.SessionCalendarService;
@@ -30,50 +32,71 @@
/**
* Activity for customizing app settings.
*/
-public class SettingsActivity extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
+public class SettingsActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- getActionBar().setDisplayHomeAsUpEnabled(true);
- }
+ setContentView(R.layout.activity_settings);
- @Override
- protected void onPostCreate(Bundle savedInstanceState) {
- super.onPostCreate(savedInstanceState);
- setupSimplePreferencesScreen();
- PrefUtils.registerOnSharedPreferenceChangeListener(this, this);
- }
+ Toolbar toolbar = getActionBarToolbar();
+ toolbar.setTitle(R.string.title_settings);
+ toolbar.setNavigationIcon(R.drawable.ic_up);
+ toolbar.setNavigationOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ navigateUpToFromChild(SettingsActivity.this,
+ IntentCompat.makeMainActivity(new ComponentName(SettingsActivity.this,
+ BrowseSessionsActivity.class)));
+ }
+ });
- @Override
- protected void onDestroy() {
- super.onDestroy();
- PrefUtils.unrgisterOnSharedPreferenceChangeListener(this, this);
- }
-
- private void setupSimplePreferencesScreen() {
- // Add 'general' preferences.
- addPreferencesFromResource(R.xml.preferences);
- if (PrefUtils.hasEnabledBle(this)) {
- addPreferencesFromResource(R.xml.ble_preferences);
+ if (savedInstanceState == null) {
+ getFragmentManager().beginTransaction()
+ .add(R.id.container, new SettingsFragment())
+ .commit();
}
}
- @Override
- public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
- if (PrefUtils.PREF_SYNC_CALENDAR.equals(key)) {
- boolean shouldSyncCalendar = PrefUtils.shouldSyncCalendar(this);
+ public static class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
+ public SettingsFragment() {
+ }
- Intent intent;
- if (PrefUtils.shouldSyncCalendar(this)) {
- // Add all calendar entries
- intent = new Intent(SessionCalendarService.ACTION_UPDATE_ALL_SESSIONS_CALENDAR);
- } else {
- // Remove all calendar entries
- intent = new Intent(SessionCalendarService.ACTION_CLEAR_ALL_SESSIONS_CALENDAR);
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setupSimplePreferencesScreen();
+ PrefUtils.registerOnSharedPreferenceChangeListener(getActivity(), this);
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ PrefUtils.unregisterOnSharedPreferenceChangeListener(getActivity(), this);
+ }
+
+ private void setupSimplePreferencesScreen() {
+ // Add 'general' preferences.
+ addPreferencesFromResource(R.xml.preferences);
+ if (PrefUtils.hasEnabledBle(getActivity())) {
+ addPreferencesFromResource(R.xml.ble_preferences);
}
+ }
- intent.setClass(this, SessionCalendarService.class);
- startService(intent);
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+ if (PrefUtils.PREF_SYNC_CALENDAR.equals(key)) {
+ Intent intent;
+ if (PrefUtils.shouldSyncCalendar(getActivity())) {
+ // Add all calendar entries
+ intent = new Intent(SessionCalendarService.ACTION_UPDATE_ALL_SESSIONS_CALENDAR);
+ } else {
+ // Remove all calendar entries
+ intent = new Intent(SessionCalendarService.ACTION_CLEAR_ALL_SESSIONS_CALENDAR);
+ }
+
+ intent.setClass(getActivity(), SessionCalendarService.class);
+ getActivity().startService(intent);
+ }
}
}
}
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/SocialActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/SocialActivity.java
index 6acb8da..ce43a3e 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/SocialActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/SocialActivity.java
@@ -17,7 +17,6 @@
package com.google.samples.apps.iosched.ui;
import android.os.Bundle;
-import android.app.ActionBar;
import com.google.samples.apps.iosched.R;
import com.google.samples.apps.iosched.util.AnalyticsManager;
@@ -38,7 +37,7 @@
}
setContentView(R.layout.activity_social);
- getLPreviewUtils().trySetActionBar();
+
if (null == savedInstanceState) {
getFragmentManager().beginTransaction()
.replace(R.id.container, HashtagsFragment.newInstance())
@@ -56,21 +55,6 @@
overridePendingTransition(0, 0);
}
- private void updateActionBarNavigation() {
- boolean show = !isNavDrawerOpen();
- if (getLPreviewUtils().shouldChangeActionBarForDrawer()) {
- ActionBar ab = getActionBar();
- ab.setDisplayShowTitleEnabled(show);
- ab.setDisplayUseLogoEnabled(!show);
- }
- }
-
- @Override
- protected void onNavDrawerStateChanged(boolean isOpen, boolean isAnimating) {
- super.onNavDrawerStateChanged(isOpen, isAnimating);
- updateActionBarNavigation();
- }
-
@Override
protected int getSelfNavDrawerItem() {
return NAVDRAWER_ITEM_SOCIAL;
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/VideoLibraryActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/VideoLibraryActivity.java
index 3f764a8..8b1c28c 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/VideoLibraryActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/VideoLibraryActivity.java
@@ -16,7 +16,6 @@
package com.google.samples.apps.iosched.ui;
-import android.app.ActionBar;
import android.app.Fragment;
import android.os.Bundle;
import android.text.TextUtils;
@@ -35,7 +34,9 @@
import java.util.Collections;
import java.util.Comparator;
-import static com.google.samples.apps.iosched.util.LogUtils.*;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGE;
+import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
public class VideoLibraryActivity extends BaseActivity implements VideoLibraryFragment.Callbacks {
private static final String TAG = makeLogTag(VideoLibraryActivity.class);
@@ -64,7 +65,7 @@
}
setContentView(R.layout.activity_video_library);
- getLPreviewUtils().trySetActionBar();
+
mDrawShadowFrameLayout = (DrawShadowFrameLayout) findViewById(R.id.main_content);
/* [ANALYTICS:SCREEN]
@@ -87,7 +88,7 @@
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
- enableActionBarAutoHide((CollectionView)findViewById(R.id.videos_collection_view));
+ enableActionBarAutoHide((CollectionView) findViewById(R.id.videos_collection_view));
}
@Override
@@ -119,27 +120,12 @@
}
}
- private void updateActionBarNavigation() {
- boolean show = !isNavDrawerOpen();
- if (getLPreviewUtils().shouldChangeActionBarForDrawer()) {
- ActionBar ab = getActionBar();
- ab.setDisplayShowTitleEnabled(show);
- ab.setDisplayUseLogoEnabled(!show);
- }
- }
-
@Override
protected void onActionBarAutoShowOrHide(boolean shown) {
super.onActionBarAutoShowOrHide(shown);
mDrawShadowFrameLayout.setShadowVisible(shown, shown);
}
- @Override
- protected void onNavDrawerStateChanged(boolean isOpen, boolean isAnimating) {
- super.onNavDrawerStateChanged(isOpen, isAnimating);
- updateActionBarNavigation();
- }
-
private void onYearSelected(int year) {
if (mSelectedYear == year) {
return;
@@ -292,7 +278,7 @@
private void populateSpinner(Spinner spinner, ArrayList<String> items) {
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.explore_spinner_item,
android.R.id.text1, items);
- adapter.setDropDownViewResource(R.layout.explore_spinner_item_dropdown);
+ adapter.setDropDownViewResource(R.layout.video_library_spinner_item_dropdown);
spinner.setAdapter(adapter);
}
}
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/debug/actions/ShowSessionNotificationDebugAction.java b/android/src/main/java/com/google/samples/apps/iosched/ui/debug/actions/ShowSessionNotificationDebugAction.java
index b23dde8..271c677 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/debug/actions/ShowSessionNotificationDebugAction.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/debug/actions/ShowSessionNotificationDebugAction.java
@@ -26,7 +26,7 @@
import com.google.samples.apps.iosched.R;
import com.google.samples.apps.iosched.provider.ScheduleContract;
-import com.google.samples.apps.iosched.ui.MapFragment;
+import com.google.samples.apps.iosched.ui.BaseMapActivity;
import com.google.samples.apps.iosched.ui.debug.DebugAction;
import com.google.samples.apps.iosched.util.UIUtils;
@@ -46,7 +46,7 @@
UIUtils.getMapActivityClass(context));
mapIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_TASK_ON_HOME);
- mapIntent.putExtra(MapFragment.EXTRA_ROOM, "keynote");
+ mapIntent.putExtra(BaseMapActivity.EXTRA_ROOM, "keynote");
PendingIntent piMap = TaskStackBuilder
.create(context)
.addNextIntent(mapIntent)
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/phone/MapActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/phone/MapActivity.java
index 094b07e..d9b8fc3 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/phone/MapActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/phone/MapActivity.java
@@ -16,18 +16,16 @@
package com.google.samples.apps.iosched.ui.phone;
-import android.app.ActionBar;
-import android.app.Fragment;
import android.app.FragmentManager;
-import android.content.res.Resources;
-import android.graphics.Color;
-import android.graphics.drawable.ColorDrawable;
+import android.graphics.Rect;
import android.os.Bundle;
-import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.DecelerateInterpolator;
import com.google.samples.apps.iosched.R;
+import com.google.samples.apps.iosched.ui.BaseMapActivity;
import com.google.samples.apps.iosched.ui.MapFragment;
-import com.google.samples.apps.iosched.ui.NearbyActivity;
import com.google.samples.apps.iosched.ui.NearbyFragment;
import com.google.samples.apps.iosched.ui.PartnersFragment;
import com.google.samples.apps.iosched.util.AnalyticsManager;
@@ -35,19 +33,16 @@
import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
-public class MapActivity extends NearbyActivity implements MapFragment.Callbacks {
+public class MapActivity extends BaseMapActivity implements MapFragment.Callbacks {
private static final String TAG = makeLogTag(MapActivity.class);
- public static final String EXTRA_DETACHED_MODE
- = "com.google.samples.apps.iosched.EXTRA_DETACHED_MODE";
private static final String SCREEN_LABEL = "Map";
private static final String PARTNERS_FRAGMENT_TAG = "partners";
- private int mActionBarOnColor;
- private int mActionBarOffColor;
- private ColorDrawable mActionBarBgDrawable;
private boolean mPopupVisible = false; // Nearby or Partners
+ private boolean mFirstPopupAnimate = true;
+ private View mPopupContainerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -58,16 +53,7 @@
}
setContentView(R.layout.activity_map);
- getLPreviewUtils().trySetActionBar();
-
- if (null == savedInstanceState) {
- // Pass arguments to MapFragment
- MapFragment fragment = MapFragment.newInstance();
- fragment.setArguments(intentToFragmentArguments(getIntent()));
- getFragmentManager().beginTransaction()
- .replace(R.id.main_content, fragment)
- .commit();
- }
+ mPopupContainerView = findViewById(R.id.fragment_container_popup);
/* [ANALYTICS:SCREEN]
* TRIGGER: View the Map screen on a phone.
@@ -79,72 +65,55 @@
overridePendingTransition(0, 0);
- final Resources res = getResources();
- mActionBarOffColor = res.getColor(R.color.translucent_actionbar_background);
- mActionBarOnColor = res.getColor(R.color.theme_primary);
-
- // Initialise and set background drawable here explicitly to ensure the background
- // is drawn when the background color is changed on JellyBean
- mActionBarBgDrawable = new ColorDrawable(mActionBarOffColor);
- getActionBar().setBackgroundDrawable(mActionBarBgDrawable);
-
getFragmentManager().addOnBackStackChangedListener(
new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
mPopupVisible = (getFragmentManager().getBackStackEntryCount() == 1);
- updateActionBarNavigation();
+ updatePopup();
}
}
);
- updateActionBarNavigation();
+ updatePopup();
}
- @Override
- protected void onPostCreate(Bundle savedInstanceState) {
- super.onPostCreate(savedInstanceState);
- Fragment nearbyFragment = getFragmentManager().findFragmentByTag(NEARBY_FRAGMENT_TAG);
- Fragment partnersFragment = getFragmentManager().findFragmentByTag(PARTNERS_FRAGMENT_TAG);
- mPopupVisible = nearbyFragment != null || partnersFragment != null;
- updateActionBarNavigation();
- }
-
- private void updateActionBarNavigation() {
- boolean show = !isNavDrawerOpen();
- ActionBar ab = getActionBar();
- if (getLPreviewUtils().shouldChangeActionBarForDrawer()) {
- ab.setDisplayShowTitleEnabled(show);
- ab.setDisplayUseLogoEnabled(!show);
+ private void updatePopup() {
+ View mapContainerView = findViewById(R.id.fragment_container_map);
+ if (mFirstPopupAnimate) {
+ if (mPopupVisible) {
+ mPopupContainerView.setTranslationY(mapContainerView.getHeight());
+ mPopupContainerView.setVisibility(View.VISIBLE);
+ mFirstPopupAnimate = false;
+ } else {
+ return;
+ }
}
+ mPopupContainerView.animate()
+ .translationY(mPopupVisible ? 0 : mapContainerView.getHeight())
+ .setInterpolator(new DecelerateInterpolator())
+ .setDuration(250);
+ }
- if (mPopupVisible) {
- ab.hide();
- } else {
- ab.show();
+ @Override
+ public void onInsetsChanged(Rect insets) {
+ super.onInsetsChanged(insets);
+ ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams)
+ mPopupContainerView.getLayoutParams();
+ lp.topMargin= insets.top;
+ mPopupContainerView.setLayoutParams(lp);
+ }
+
+ @Override
+ public void onBackPressed() {
+ // Force checking the native fragment manager for a backstack rather than
+ // the support lib fragment manager.
+ if (!getFragmentManager().popBackStackImmediate()) {
+ super.onBackPressed();
}
}
@Override
- protected void onNavDrawerStateChanged(boolean isOpen, boolean isAnimating) {
- super.onNavDrawerStateChanged(isOpen, isAnimating);
- updateActionBarNavigation();
- }
-
- @Override
- protected void onNavDrawerSlide(float offset) {
- super.onNavDrawerSlide(offset);
- // Make Action Bar gradually fade into the theme color
- mActionBarBgDrawable.setColor(Color.argb(
- Color.alpha(mActionBarOffColor) + (int) (offset * (Color.alpha(mActionBarOnColor) - Color.alpha(mActionBarOffColor))),
- Color.red(mActionBarOffColor) + (int) (offset * (Color.red(mActionBarOnColor) - Color.red(mActionBarOffColor))),
- Color.green(mActionBarOffColor) + (int) (offset * (Color.green(mActionBarOnColor) - Color.green(mActionBarOffColor))),
- Color.blue(mActionBarOffColor) + (int) (offset * (Color.blue(mActionBarOnColor) - Color.blue(mActionBarOffColor)))
- ));
- getActionBar().setBackgroundDrawable(mActionBarBgDrawable);
- }
-
- @Override
public void onSessionRoomSelected(String roomId, String roomTitle) {
// we no longer have a screen that shows sessions on a given room
}
@@ -152,36 +121,17 @@
@Override
public void onShowPartners() {
getFragmentManager().beginTransaction()
- .replace(R.id.main_content, PartnersFragment.newInstance(true),
+ .add(R.id.fragment_container_popup, PartnersFragment.newInstance(true),
PARTNERS_FRAGMENT_TAG)
.addToBackStack(null)
.commit();
}
- @Override
- protected int getSelfNavDrawerItem() {
- if (getIntent().getBooleanExtra(EXTRA_DETACHED_MODE, false)) {
- // in detached mode, we don't have a nav drawer
- return NAVDRAWER_ITEM_INVALID;
- } else {
- return NAVDRAWER_ITEM_MAP;
- }
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if (getIntent().getBooleanExtra(EXTRA_DETACHED_MODE, false)
- && item.getItemId() == android.R.id.home) {
- finish();
- }
- return super.onOptionsItemSelected(item);
- }
-
// Show whichever Fragment has been provided by NearbyActivity.
@Override
protected void showNearbyFragment(String tag) {
getFragmentManager().beginTransaction()
- .replace(R.id.main_content, NearbyFragment.newInstance(true), tag)
+ .add(R.id.fragment_container_popup, NearbyFragment.newInstance(true), tag)
.addToBackStack(null)
.commit();
}
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/tablet/MapMultiPaneActivity.java b/android/src/main/java/com/google/samples/apps/iosched/ui/tablet/MapMultiPaneActivity.java
index 259ec84..fe132e5 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/tablet/MapMultiPaneActivity.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/tablet/MapMultiPaneActivity.java
@@ -16,19 +16,12 @@
package com.google.samples.apps.iosched.ui.tablet;
-import android.app.ActionBar;
-import android.app.Fragment;
import android.app.FragmentBreadCrumbs;
import android.app.FragmentManager;
import android.content.Intent;
import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.graphics.Color;
-import android.graphics.drawable.ColorDrawable;
-import android.net.Uri;
import android.os.Bundle;
import android.view.Gravity;
-import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
@@ -36,8 +29,12 @@
import com.google.samples.apps.iosched.R;
import com.google.samples.apps.iosched.model.TagMetadata;
import com.google.samples.apps.iosched.provider.ScheduleContract;
-import com.google.samples.apps.iosched.ui.*;
-import com.google.samples.apps.iosched.ui.phone.MapActivity;
+import com.google.samples.apps.iosched.ui.BaseMapActivity;
+import com.google.samples.apps.iosched.ui.MapFragment;
+import com.google.samples.apps.iosched.ui.NearbyFragment;
+import com.google.samples.apps.iosched.ui.PartnersFragment;
+import com.google.samples.apps.iosched.ui.SessionDetailActivity;
+import com.google.samples.apps.iosched.ui.SessionsFragment;
import com.google.samples.apps.iosched.util.AnalyticsManager;
import com.google.samples.apps.iosched.util.UIUtils;
@@ -45,11 +42,10 @@
/**
* A multi-pane activity, where the primary navigation pane is a
- * {@link MapFragment}, that shows {@link SessionsFragment},
- * {@link SessionDetailFragment} as popups. This activity requires API level 11
- * or greater because of its use of {@link FragmentBreadCrumbs}.
+ * {@link MapFragment}, that shows {@link NearbyFragment},
+ * {@link PartnersFragment} as popups.
*/
-public class MapMultiPaneActivity extends NearbyActivity implements
+public class MapMultiPaneActivity extends BaseMapActivity implements
FragmentManager.OnBackStackChangedListener,
MapFragment.Callbacks,
SessionsFragment.Callbacks {
@@ -61,17 +57,10 @@
private FragmentBreadCrumbs mFragmentBreadCrumbs;
private String mSelectedRoomName;
- private MapFragment mMapFragment;
-
- private int mActionBarOnColor;
- private int mActionBarOffColor;
- private ColorDrawable mActionBarBgDrawable;
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
- getLPreviewUtils().trySetActionBar();
FragmentManager fm = getFragmentManager();
fm.addOnBackStackChangedListener(this);
@@ -79,16 +68,6 @@
mFragmentBreadCrumbs = (FragmentBreadCrumbs) findViewById(R.id.breadcrumbs);
mFragmentBreadCrumbs.setActivity(this);
- mMapFragment = (MapFragment) fm.findFragmentByTag("map");
- if (mMapFragment == null) {
- mMapFragment = MapFragment.newInstance();
- mMapFragment.setArguments(intentToFragmentArguments(getIntent()));
-
- fm.beginTransaction()
- .add(R.id.fragment_container_map, mMapFragment, "map")
- .commit();
- }
-
findViewById(R.id.close_button).setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
clearBackStack(false);
@@ -107,53 +86,6 @@
LOGD("Tracker", SCREEN_LABEL);
overridePendingTransition(0, 0);
-
- final Resources res = getResources();
- mActionBarOffColor = res.getColor(R.color.translucent_actionbar_background);
- mActionBarOnColor = res.getColor(R.color.theme_primary);
-
- // Initialise and set background drawable here explicitly to ensure the background
- // is drawn when the background color is changed on JellyBean
- mActionBarBgDrawable = new ColorDrawable(mActionBarOffColor);
- getActionBar().setBackgroundDrawable(mActionBarBgDrawable);
- }
-
- private void updateActionBarNavigation() {
- boolean show = !isNavDrawerOpen();
- if (getLPreviewUtils().shouldChangeActionBarForDrawer()) {
- ActionBar ab = getActionBar();
- ab.setDisplayShowTitleEnabled(show);
- ab.setDisplayUseLogoEnabled(!show);
- }
- }
-
- @Override
- protected void onNavDrawerStateChanged(boolean isOpen, boolean isAnimating) {
- super.onNavDrawerStateChanged(isOpen, isAnimating);
- updateActionBarNavigation();
- }
-
- @Override
- protected void onNavDrawerSlide(float offset) {
- super.onNavDrawerSlide(offset);
- // Make Action Bar gradually fade into the theme color
- mActionBarBgDrawable.setColor(Color.argb(
- Color.alpha(mActionBarOffColor) + (int) (offset * (Color.alpha(mActionBarOnColor) - Color.alpha(mActionBarOffColor))),
- Color.red(mActionBarOffColor) + (int) (offset * (Color.red(mActionBarOnColor) - Color.red(mActionBarOffColor))),
- Color.green(mActionBarOffColor) + (int) (offset * (Color.green(mActionBarOnColor) - Color.green(mActionBarOffColor))),
- Color.blue(mActionBarOffColor) + (int) (offset * (Color.blue(mActionBarOnColor) - Color.blue(mActionBarOffColor)))
- ));
- getActionBar().setBackgroundDrawable(mActionBarBgDrawable);
- }
-
- @Override
- protected int getSelfNavDrawerItem() {
- if (getIntent().getBooleanExtra(MapActivity.EXTRA_DETACHED_MODE, false)) {
- // in detached mode, we don't have a nav drawer
- return NAVDRAWER_ITEM_INVALID;
- } else {
- return NAVDRAWER_ITEM_MAP;
- }
}
@Override
@@ -222,10 +154,11 @@
boolean landscape = getResources().getConfiguration().orientation
== Configuration.ORIENTATION_LANDSCAPE;
boolean detailShown = findViewById(R.id.map_detail_spacer).getVisibility() == View.VISIBLE;
-
- mMapFragment.setCenterPadding(
- landscape ? (detailShown ? 0.25f : 0f) : 0,
- landscape ? 0 : (detailShown ? 0.25f : 0));
+ if (mMapFragment != null) {
+ mMapFragment.setCenterPadding(
+ landscape ? (detailShown ? 0.25f : 0f) : 0,
+ landscape ? 0 : (detailShown ? 0.25f : 0));
+ }
}
void updateBreadCrumbs() {
@@ -260,46 +193,17 @@
* [/ANALYTICS]
*/
AnalyticsManager.sendEvent(SCREEN_LABEL, "selectsession", sessionId);
- getLPreviewUtils().startActivityWithTransition(
+ getLUtils().startActivityWithTransition(
new Intent(Intent.ACTION_VIEW,
ScheduleContract.Sessions.buildSessionUri(sessionId)),
clickedView,
- SessionDetailFragment.VIEW_NAME_PHOTO
+ SessionDetailActivity.TRANSITION_NAME_PHOTO
);
}
@Override
public void onTagMetadataLoaded(TagMetadata metadata) {}
- private void showList(Fragment fragment, Uri uri){
- // Show the sessions in the room
- clearBackStack(true);
- showDetailPane(true);
- fragment.setArguments(BaseActivity.intentToFragmentArguments(
- new Intent(Intent.ACTION_VIEW,
- uri
- )));
- getFragmentManager().beginTransaction()
- .replace(R.id.fragment_container_detail, fragment)
- .addToBackStack(null)
- .commit();
- updateBreadCrumbs();
- }
-
- private void showDetails(Fragment fragment, Uri uri){
- // Show the session details
- showDetailPane(true);
- Intent intent = new Intent(Intent.ACTION_VIEW,uri);
- //intent.putExtra(SessionDetailFragment.EXTRA_VARIABLE_HEIGHT_HEADER, true);
- fragment.setArguments(BaseActivity.intentToFragmentArguments(intent));
- getFragmentManager().beginTransaction()
- .replace(R.id.fragment_container_detail, fragment)
- .addToBackStack(null)
- .commit();
- updateBreadCrumbs();
- }
-
-
// TODO: This should also update the breadcrumbs, which will likely involve a major
// refactoring of the way breadcrumbs are handled. Perhaps we can store breadcrumb titles in
// every back stack entry...
@@ -313,13 +217,4 @@
.addToBackStack(null)
.commit();
}
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if (getIntent().getBooleanExtra(MapActivity.EXTRA_DETACHED_MODE, false)
- && item.getItemId() == android.R.id.home) {
- finish();
- }
- return super.onOptionsItemSelected(item);
- }
}
diff --git a/android/src/lpreview/java/com/google/samples/apps/iosched/ui/widget/AddToScheduleFABFrameLayout.java b/android/src/main/java/com/google/samples/apps/iosched/ui/widget/AddToScheduleFABFrameLayout.java
similarity index 82%
rename from android/src/lpreview/java/com/google/samples/apps/iosched/ui/widget/AddToScheduleFABFrameLayout.java
rename to android/src/main/java/com/google/samples/apps/iosched/ui/widget/AddToScheduleFABFrameLayout.java
index 88b8a45..3087376 100644
--- a/android/src/lpreview/java/com/google/samples/apps/iosched/ui/widget/AddToScheduleFABFrameLayout.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/widget/AddToScheduleFABFrameLayout.java
@@ -18,7 +18,6 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Color;
@@ -30,10 +29,11 @@
import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.ViewGroup;
+import android.view.ViewOutlineProvider;
import com.google.samples.apps.iosched.R;
-@TargetApi(Build.VERSION_CODES.L)
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class AddToScheduleFABFrameLayout extends CheckableFrameLayout {
private View mRevealView;
private float mHotSpotX, mHotSpotY;
@@ -72,9 +72,13 @@
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
- Outline outline = new Outline();
- outline.setOval(0, 0, w, h);
- setOutline(outline);
+ ViewOutlineProvider viewOutlineProvider = new ViewOutlineProvider() {
+ @Override
+ public void getOutline(View view, Outline outline) {
+ outline.setOval(0, 0, view.getWidth(), view.getHeight());
+ }
+ };
+ setOutlineProvider(viewOutlineProvider);
setClipToOutline(true);
}
@@ -82,9 +86,11 @@
public void setChecked(boolean checked, boolean allowAnimate) {
super.setChecked(checked, allowAnimate);
if (allowAnimate) {
- ValueAnimator animator = ViewAnimationUtils.createCircularReveal(
+ // TODO: switch to mHotSpotX/mHotSpotY/getWidth if/when nested reveals can be clipped
+ // by parents. was possible in LPV79 but no longer as of this writing.
+ Animator animator = ViewAnimationUtils.createCircularReveal(
mRevealView,
- (int) mHotSpotX, (int) mHotSpotY, 0, getWidth());
+ (int) getWidth() / 2, (int) getHeight() / 2, 0, getWidth() / 2);
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/widget/CaptureInsetsFrameLayout.java b/android/src/main/java/com/google/samples/apps/iosched/ui/widget/CaptureInsetsFrameLayout.java
deleted file mode 100644
index 3c37aaa..0000000
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/widget/CaptureInsetsFrameLayout.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2014 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.
- */
-
-package com.google.samples.apps.iosched.ui.widget;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.widget.FrameLayout;
-
-/**
- * A layout that captures the insets passed to {@link #fitSystemWindows(Rect)}, i.e. the area above
- * UI chrome (status and navigation bars, overlay action bars).
- */
-public class CaptureInsetsFrameLayout extends FrameLayout {
- private OnInsetsCallback mOnInsetsCallback;
-
- public CaptureInsetsFrameLayout(Context context) {
- super(context);
- }
-
- public CaptureInsetsFrameLayout(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public CaptureInsetsFrameLayout(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- }
-
- @Override
- protected boolean fitSystemWindows(Rect insets) {
- if (mOnInsetsCallback != null) {
- mOnInsetsCallback.onInsetsChanged(insets);
- }
- return false; // don't actually consume the insets
- }
-
- /**
- * Allows the calling container to specify a callback for custom processing when insets change (i.e. when
- * {@link #fitSystemWindows(Rect)} is called. This is useful for setting padding on UI elements based on
- * UI chrome insets (e.g. a Google Map or a ListView). When using with ListView or GridView, remember to set
- * clipToPadding to false.
- */
- public void setOnInsetsCallback(OnInsetsCallback onInsetsCallback) {
- mOnInsetsCallback = onInsetsCallback;
- }
-
- public static interface OnInsetsCallback {
- public void onInsetsChanged(Rect insets);
- }
-}
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/widget/MessageCardView.java b/android/src/main/java/com/google/samples/apps/iosched/ui/widget/MessageCardView.java
index 0cac141..5e7fff0 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/ui/widget/MessageCardView.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/widget/MessageCardView.java
@@ -16,27 +16,23 @@
package com.google.samples.apps.iosched.ui.widget;
-import android.animation.Animator;
-import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Typeface;
+import android.support.v7.widget.CardView;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
-import android.widget.FrameLayout;
import android.widget.TextView;
import com.google.samples.apps.iosched.R;
-import com.google.samples.apps.iosched.util.UIUtils;
-import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
import static com.google.samples.apps.iosched.util.LogUtils.LOGW;
import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
-public class MessageCardView extends FrameLayout implements View.OnClickListener {
+public class MessageCardView extends CardView implements View.OnClickListener {
private static final String TAG = makeLogTag("MessageCardView");
private TextView mTitleView;
private TextView mMessageView;
@@ -50,16 +46,22 @@
public void onMessageCardButtonClicked(String tag);
}
- public MessageCardView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
+ public MessageCardView(Context context) {
+ super(context, null, 0);
+ initialize(context, null, 0);
}
- public MessageCardView(Context context) {
- this(context, null, 0);
+ public MessageCardView(Context context, AttributeSet attrs) {
+ super(context, attrs, 0);
+ initialize(context, attrs, 0);
}
public MessageCardView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
+ initialize(context, attrs, defStyle);
+ }
+
+ private void initialize(Context context, AttributeSet attrs, int defStyle) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
mRoot = inflater.inflate(R.layout.message_card, this, true);
@@ -76,7 +78,7 @@
button.setOnClickListener(this);
}
- TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MessageCard, 0, 0);
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MessageCard, defStyle, 0);
String title = a.getString(R.styleable.MessageCard_messageTitle);
setTitle(title);
String text = a.getString(R.styleable.MessageCard_messageText);
@@ -98,6 +100,10 @@
if (button2text != null) {
setButton(1, button2text, button2tag, button2emphasis, emphasisColor);
}
+
+ setRadius(getResources().getDimensionPixelSize(R.dimen.card_corner_radius));
+ setCardElevation(getResources().getDimensionPixelSize(R.dimen.card_elevation));
+ setPreventCornerOverlap(false);
}
public void setListener(OnMessageCardButtonClicked listener) {
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/widget/ScrimInsetsFrameLayout.java b/android/src/main/java/com/google/samples/apps/iosched/ui/widget/ScrimInsetsFrameLayout.java
new file mode 100644
index 0000000..fc59e53
--- /dev/null
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/widget/ScrimInsetsFrameLayout.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * 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.google.samples.apps.iosched.ui.widget;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.widget.FrameLayout;
+
+import com.google.samples.apps.iosched.R;
+
+/**
+ * A layout that draws something in the insets passed to {@link #fitSystemWindows(Rect)}, i.e. the area above UI chrome
+ * (status and navigation bars, overlay action bars).
+ */
+public class ScrimInsetsFrameLayout extends FrameLayout {
+ private Drawable mInsetForeground;
+
+ private Rect mInsets;
+ private Rect mTempRect = new Rect();
+ private OnInsetsCallback mOnInsetsCallback;
+
+ public ScrimInsetsFrameLayout(Context context) {
+ super(context);
+ init(context, null, 0);
+ }
+
+ public ScrimInsetsFrameLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context, attrs, 0);
+ }
+
+ public ScrimInsetsFrameLayout(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init(context, attrs, defStyle);
+ }
+
+ private void init(Context context, AttributeSet attrs, int defStyle) {
+ final TypedArray a = context.obtainStyledAttributes(attrs,
+ R.styleable.ScrimInsetsView, defStyle, 0);
+ if (a == null) {
+ return;
+ }
+ mInsetForeground = a.getDrawable(R.styleable.ScrimInsetsView_insetForeground);
+ a.recycle();
+
+ setWillNotDraw(true);
+ }
+
+ @Override
+ protected boolean fitSystemWindows(Rect insets) {
+ mInsets = new Rect(insets);
+ setWillNotDraw(mInsetForeground == null);
+ postInvalidateOnAnimation();
+ if (mOnInsetsCallback != null) {
+ mOnInsetsCallback.onInsetsChanged(insets);
+ }
+ return true; // consume insets
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ super.draw(canvas);
+
+ int width = getWidth();
+ int height = getHeight();
+ if (mInsets != null && mInsetForeground != null) {
+ int sc = canvas.save();
+ canvas.translate(getScrollX(), getScrollY());
+
+ // Top
+ mTempRect.set(0, 0, width, mInsets.top);
+ mInsetForeground.setBounds(mTempRect);
+ mInsetForeground.draw(canvas);
+
+ // Bottom
+ mTempRect.set(0, height - mInsets.bottom, width, height);
+ mInsetForeground.setBounds(mTempRect);
+ mInsetForeground.draw(canvas);
+
+ // Left
+ mTempRect.set(0, mInsets.top, mInsets.left, height - mInsets.bottom);
+ mInsetForeground.setBounds(mTempRect);
+ mInsetForeground.draw(canvas);
+
+ // Right
+ mTempRect.set(width - mInsets.right, mInsets.top, width, height - mInsets.bottom);
+ mInsetForeground.setBounds(mTempRect);
+ mInsetForeground.draw(canvas);
+
+ canvas.restoreToCount(sc);
+ }
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ if (mInsetForeground != null) {
+ mInsetForeground.setCallback(this);
+ }
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ if (mInsetForeground != null) {
+ mInsetForeground.setCallback(null);
+ }
+ }
+
+ /**
+ * Allows the calling container to specify a callback for custom processing when insets change (i.e. when
+ * {@link #fitSystemWindows(Rect)} is called. This is useful for setting padding on UI elements based on
+ * UI chrome insets (e.g. a Google Map or a ListView). When using with ListView or GridView, remember to set
+ * clipToPadding to false.
+ */
+ public void setOnInsetsCallback(OnInsetsCallback onInsetsCallback) {
+ mOnInsetsCallback = onInsetsCallback;
+ }
+
+ public static interface OnInsetsCallback {
+ public void onInsetsChanged(Rect insets);
+ }
+}
\ No newline at end of file
diff --git a/android/src/main/java/com/google/samples/apps/iosched/ui/widget/ScrimInsetsScrollView.java b/android/src/main/java/com/google/samples/apps/iosched/ui/widget/ScrimInsetsScrollView.java
new file mode 100644
index 0000000..9c83922
--- /dev/null
+++ b/android/src/main/java/com/google/samples/apps/iosched/ui/widget/ScrimInsetsScrollView.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * 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.google.samples.apps.iosched.ui.widget;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.widget.ScrollView;
+
+import com.google.samples.apps.iosched.R;
+
+/**
+ * A layout that draws something in the insets passed to {@link #fitSystemWindows(Rect)}, i.e. the area above UI chrome
+ * (status and navigation bars, overlay action bars).
+ */
+public class ScrimInsetsScrollView extends ScrollView {
+ private Drawable mInsetForeground;
+
+ private Rect mInsets;
+ private Rect mTempRect = new Rect();
+ private OnInsetsCallback mOnInsetsCallback;
+
+ public ScrimInsetsScrollView(Context context) {
+ super(context);
+ init(context, null, 0);
+ }
+
+ public ScrimInsetsScrollView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context, attrs, 0);
+ }
+
+ public ScrimInsetsScrollView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init(context, attrs, defStyle);
+ }
+
+ private void init(Context context, AttributeSet attrs, int defStyle) {
+ final TypedArray a = context.obtainStyledAttributes(attrs,
+ R.styleable.ScrimInsetsView, defStyle, 0);
+ if (a == null) {
+ return;
+ }
+ mInsetForeground = a.getDrawable(R.styleable.ScrimInsetsView_insetForeground);
+ a.recycle();
+
+ setWillNotDraw(true);
+ }
+
+ @Override
+ protected boolean fitSystemWindows(Rect insets) {
+ mInsets = new Rect(insets);
+ setWillNotDraw(mInsetForeground == null);
+ postInvalidateOnAnimation();
+ if (mOnInsetsCallback != null) {
+ mOnInsetsCallback.onInsetsChanged(insets);
+ }
+ return true; // consume insets
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ super.draw(canvas);
+
+ int width = getWidth();
+ int height = getHeight();
+ if (mInsets != null && mInsetForeground != null) {
+ int sc = canvas.save();
+ canvas.translate(getScrollX(), getScrollY());
+
+ // Top
+ mTempRect.set(0, 0, width, mInsets.top);
+ mInsetForeground.setBounds(mTempRect);
+ mInsetForeground.draw(canvas);
+
+ // Bottom
+ mTempRect.set(0, height - mInsets.bottom, width, height);
+ mInsetForeground.setBounds(mTempRect);
+ mInsetForeground.draw(canvas);
+
+ // Left
+ mTempRect.set(0, mInsets.top, mInsets.left, height - mInsets.bottom);
+ mInsetForeground.setBounds(mTempRect);
+ mInsetForeground.draw(canvas);
+
+ // Right
+ mTempRect.set(width - mInsets.right, mInsets.top, width, height - mInsets.bottom);
+ mInsetForeground.setBounds(mTempRect);
+ mInsetForeground.draw(canvas);
+
+ canvas.restoreToCount(sc);
+ }
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ if (mInsetForeground != null) {
+ mInsetForeground.setCallback(this);
+ }
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ if (mInsetForeground != null) {
+ mInsetForeground.setCallback(null);
+ }
+ }
+
+ /**
+ * Allows the calling container to specify a callback for custom processing when insets change (i.e. when
+ * {@link #fitSystemWindows(Rect)} is called. This is useful for setting padding on UI elements based on
+ * UI chrome insets (e.g. a Google Map or a ListView). When using with ListView or GridView, remember to set
+ * clipToPadding to false.
+ */
+ public void setOnInsetsCallback(OnInsetsCallback onInsetsCallback) {
+ mOnInsetsCallback = onInsetsCallback;
+ }
+
+ public static interface OnInsetsCallback {
+ public void onInsetsChanged(Rect insets);
+ }
+}
\ No newline at end of file
diff --git a/android/src/main/java/com/google/samples/apps/iosched/util/AccountUtils.java b/android/src/main/java/com/google/samples/apps/iosched/util/AccountUtils.java
index 153ff6e..ef1256f 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/util/AccountUtils.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/util/AccountUtils.java
@@ -182,6 +182,12 @@
PREFIX_PREF_PLUS_IMAGE_URL), null) : null;
}
+ public static String getPlusImageUrl(final Context context, final String accountName) {
+ SharedPreferences sp = getSharedPreferences(context);
+ return hasActiveAccount(context) ? sp.getString(makeAccountSpecificPrefKey(accountName,
+ PREFIX_PREF_PLUS_IMAGE_URL), null) : null;
+ }
+
public static void refreshAuthToken(Context mContext) {
invalidateAuthToken(mContext);
tryAuthenticateWithErrorNotification(mContext, ScheduleContract.CONTENT_AUTHORITY);
diff --git a/android/src/main/java/com/google/samples/apps/iosched/util/FeedbackUtils.java b/android/src/main/java/com/google/samples/apps/iosched/util/FeedbackUtils.java
index aff85ac..13a4c93 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/util/FeedbackUtils.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/util/FeedbackUtils.java
@@ -22,6 +22,7 @@
import android.net.Uri;
import com.google.samples.apps.iosched.provider.ScheduleContract;
+import com.google.samples.apps.iosched.service.FeedbackListenerService;
import com.google.samples.apps.iosched.service.SessionAlarmService;
import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
@@ -72,7 +73,8 @@
* should result in removal of the corresponding notifications on both ends.
*/
public static void dismissFeedbackNotification(Context context, String sessionId) {
- Intent dismissalIntent = new Intent(SessionAlarmService.ACTION_NOTIFICATION_DISMISSAL);
+ Intent dismissalIntent = new Intent(context, FeedbackListenerService.class);
+ dismissalIntent.setAction(SessionAlarmService.ACTION_NOTIFICATION_DISMISSAL);
dismissalIntent.putExtra(SessionAlarmService.KEY_SESSION_ID, sessionId);
context.startService(dismissalIntent);
}
diff --git a/android/src/main/java/com/google/samples/apps/iosched/util/ImageLoader.java b/android/src/main/java/com/google/samples/apps/iosched/util/ImageLoader.java
index b264867..2285f79 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/util/ImageLoader.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/util/ImageLoader.java
@@ -26,7 +26,7 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import com.bumptech.glide.DrawableRequestBuilder;
+import com.bumptech.glide.BitmapRequestBuilder;
import com.bumptech.glide.Glide;
import com.bumptech.glide.ModelRequest;
import com.bumptech.glide.load.Transformation;
@@ -103,7 +103,7 @@
*/
public void loadImage(String url, ImageView imageView, RequestListener<String> requestListener,
Drawable placeholderOverride, boolean crop) {
- DrawableRequestBuilder<String> request = beginImageLoad(url, requestListener, crop)
+ BitmapRequestBuilder request = beginImageLoad(url, requestListener, crop)
.animate(R.anim.image_fade_in);
if (placeholderOverride != null) {
request.placeholder(placeholderOverride);
@@ -113,11 +113,12 @@
request.into(imageView);
}
- public DrawableRequestBuilder<String> beginImageLoad(String url,
+ public BitmapRequestBuilder beginImageLoad(String url,
RequestListener<String> requestListener, boolean crop) {
return mGlideModelRequest.load(url)
+ .asBitmap() // don't allow animated GIFs
.listener(requestListener)
- .bitmapTransform(crop ? mCenterCrop : mNone);
+ .transform(crop ? mCenterCrop : mNone);
}
/**
diff --git a/android/src/main/java/com/google/samples/apps/iosched/util/LPreviewUtilsBase.java b/android/src/main/java/com/google/samples/apps/iosched/util/LPreviewUtilsBase.java
deleted file mode 100644
index e4fa0ae..0000000
--- a/android/src/main/java/com/google/samples/apps/iosched/util/LPreviewUtilsBase.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright 2014 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.
- */
-
-package com.google.samples.apps.iosched.util;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.app.Activity;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.graphics.Color;
-import android.graphics.Typeface;
-import android.os.Handler;
-import android.support.v4.app.ActionBarDrawerToggle;
-import android.support.v4.widget.DrawerLayout;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.google.samples.apps.iosched.R;
-
-public class LPreviewUtilsBase {
- protected Activity mActivity;
- private ActionBarDrawerToggle mDrawerToggle;
- private ActionBarDrawerToggleWrapper mDrawerToggleWrapper;
- private Handler mHandler = new Handler();
-
- LPreviewUtilsBase(Activity activity) {
- mActivity = activity;
- }
-
- public ActionBarDrawerToggleWrapper setupDrawerToggle(DrawerLayout drawerLayout,
- final DrawerLayout.DrawerListener drawerListener) {
- mDrawerToggle = new ActionBarDrawerToggle(mActivity, drawerLayout,
- R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) {
- @Override
- public void onDrawerClosed(View drawerView) {
- super.onDrawerClosed(drawerView);
- drawerListener.onDrawerClosed(drawerView);
- }
-
- @Override
- public void onDrawerOpened(View drawerView) {
- super.onDrawerOpened(drawerView);
- drawerListener.onDrawerOpened(drawerView);
- }
-
- @Override
- public void onDrawerStateChanged(int newState) {
- super.onDrawerStateChanged(newState);
- drawerListener.onDrawerStateChanged(newState);
- }
-
- @Override
- public void onDrawerSlide(View drawerView, float slideOffset) {
- super.onDrawerSlide(drawerView, slideOffset);
- drawerListener.onDrawerSlide(drawerView, slideOffset);
- }
- };
- drawerLayout.setDrawerListener(mDrawerToggle);
- mDrawerToggleWrapper = new ActionBarDrawerToggleWrapper();
- return mDrawerToggleWrapper;
- }
-
- public void trySetActionBar() {
- // Do nothing pre-L
- }
-
- public boolean hasLPreviewAPIs() {
- return false;
- }
-
- public boolean shouldChangeActionBarForDrawer() {
- return true;
- }
-
- public void showHideActionBarIfPartOfDecor(boolean show) {
- // pre-L, action bar is always part of the window decor
- if (show) {
- mActivity.getActionBar().show();
- } else {
- mActivity.getActionBar().hide();
- }
- }
-
- public void setMediumTypeface(TextView textView) {
- textView.setTypeface(Typeface.SANS_SERIF, Typeface.BOLD);
- }
-
- public class ActionBarDrawerToggleWrapper {
- public void syncState() {
- if (mDrawerToggle != null) {
- mDrawerToggle.syncState();
- }
- }
-
- public void onConfigurationChanged(Configuration newConfig) {
- if (mDrawerToggle != null) {
- mDrawerToggle.onConfigurationChanged(newConfig);
- }
- }
-
- public boolean onOptionsItemSelected(MenuItem item) {
- if (mDrawerToggle != null) {
- return mDrawerToggle.onOptionsItemSelected(item);
- }
- return false;
- }
- }
-
- public void startActivityWithTransition(Intent intent, View clickedView,
- String sharedElementName) {
- mActivity.startActivity(intent);
- }
-
- public void setViewName(View v, String viewName) {
- // Can't do this pre-L
- }
-
- public void postponeEnterTransition() {
- // Can't do this pre-L
- }
-
- public void startPostponedEnterTransition() {
- // Can't do this pre-L
- }
-
- public int getStatusBarColor() {
- // On pre-L devices, you can have any status bar color so long as it's black.
- return Color.BLACK;
- }
-
- public void setStatusBarColor(int color) {
- // Only black.
- }
-
- public void setViewElevation(View v, float elevation) {
- // Can't do this pre-L
- }
-
- public void setOrAnimatePlusCheckIcon(final ImageView imageView, boolean isCheck,
- boolean allowAnimate) {
- final int imageResId = isCheck
- ? R.drawable.add_schedule_button_icon_checked
- : R.drawable.add_schedule_button_icon_unchecked;
-
- if (imageView.getTag() != null) {
- if (imageView.getTag() instanceof Animator) {
- Animator anim = (Animator) imageView.getTag();
- anim.end();
- imageView.setAlpha(1f);
- }
- }
-
- if (allowAnimate && isCheck) {
- int duration = mActivity.getResources().getInteger(
- android.R.integer.config_shortAnimTime);
-
- Animator outAnimator = ObjectAnimator.ofFloat(imageView, View.ALPHA, 0f);
- outAnimator.setDuration(duration / 2);
- outAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- imageView.setImageResource(imageResId);
- }
- });
-
- AnimatorSet inAnimator = new AnimatorSet();
- outAnimator.setDuration(duration);
- inAnimator.playTogether(
- ObjectAnimator.ofFloat(imageView, View.ALPHA, 1f),
- ObjectAnimator.ofFloat(imageView, View.SCALE_X, 0f, 1f),
- ObjectAnimator.ofFloat(imageView, View.SCALE_Y, 0f, 1f)
- );
-
- AnimatorSet set = new AnimatorSet();
- set.playSequentially(outAnimator, inAnimator);
- set.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- imageView.setTag(null);
- }
- });
- imageView.setTag(set);
- set.start();
- } else {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- imageView.setImageResource(imageResId);
- }
- });
- }
- }
-}
diff --git a/android/src/main/java/com/google/samples/apps/iosched/util/LUtils.java b/android/src/main/java/com/google/samples/apps/iosched/util/LUtils.java
new file mode 100644
index 0000000..f34fcff
--- /dev/null
+++ b/android/src/main/java/com/google/samples/apps/iosched/util/LUtils.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2014 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.
+ */
+
+package com.google.samples.apps.iosched.util;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.annotation.TargetApi;
+import android.app.ActivityOptions;
+import android.content.Intent;
+import android.graphics.Color;
+import android.graphics.Typeface;
+import android.graphics.drawable.AnimatedStateListDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.os.Handler;
+import android.support.v7.app.ActionBarActivity;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.google.samples.apps.iosched.R;
+
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
+public class LUtils {
+ private static final int[] STATE_CHECKED = new int[]{android.R.attr.state_checked};
+ private static final int[] STATE_UNCHECKED = new int[]{};
+
+ private static Typeface sMediumTypeface;
+
+ protected ActionBarActivity mActivity;
+ private Handler mHandler = new Handler();
+
+ private LUtils(ActionBarActivity activity) {
+ mActivity = activity;
+ }
+
+ public static LUtils getInstance(ActionBarActivity activity) {
+ return new LUtils(activity);
+ }
+
+ private static boolean hasL() {
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
+ }
+
+ public void startActivityWithTransition(Intent intent, final View clickedView,
+ final String transitionName) {
+ ActivityOptions options = null;
+ if (hasL() && clickedView != null && !TextUtils.isEmpty(transitionName)) {
+// options = ActivityOptions.makeSceneTransitionAnimation(
+// mActivity, clickedView, transitionName);
+ }
+
+ mActivity.startActivity(intent, (options != null) ? options.toBundle() : null);
+ }
+
+ public void setMediumTypeface(TextView textView) {
+ if (hasL()) {
+ if (sMediumTypeface == null) {
+ sMediumTypeface = Typeface.create("sans-serif-medium", Typeface.NORMAL);
+ }
+
+ textView.setTypeface(sMediumTypeface);
+ } else {
+ textView.setTypeface(Typeface.SANS_SERIF, Typeface.BOLD);
+ }
+ }
+
+ public int getStatusBarColor() {
+ if (!hasL()) {
+ // On pre-L devices, you can have any status bar color so long as it's black.
+ return Color.BLACK;
+ }
+
+ return mActivity.getWindow().getStatusBarColor();
+ }
+
+ public void setStatusBarColor(int color) {
+ if (!hasL()) {
+ return;
+ }
+
+ mActivity.getWindow().setStatusBarColor(color);
+ }
+
+ public void setOrAnimatePlusCheckIcon(final ImageView imageView, boolean isCheck,
+ boolean allowAnimate) {
+ if (!hasL()) {
+ compatSetOrAnimatePlusCheckIcon(imageView, isCheck, allowAnimate);
+ return;
+ }
+
+ Drawable drawable = imageView.getDrawable();
+ if (!(drawable instanceof AnimatedStateListDrawable)) {
+ drawable = mActivity.getResources().getDrawable(R.drawable.add_schedule_fab_icon_anim);
+ imageView.setImageDrawable(drawable);
+ }
+ imageView.setColorFilter(isCheck ?
+ mActivity.getResources().getColor(R.color.theme_accent_1) : Color.WHITE);
+ if (allowAnimate) {
+ imageView.setImageState(isCheck ? STATE_UNCHECKED : STATE_CHECKED, false);
+ drawable.jumpToCurrentState();
+ imageView.setImageState(isCheck ? STATE_CHECKED : STATE_UNCHECKED, false);
+ } else {
+ imageView.setImageState(isCheck ? STATE_CHECKED : STATE_UNCHECKED, false);
+ drawable.jumpToCurrentState();
+ }
+ }
+
+ public void compatSetOrAnimatePlusCheckIcon(final ImageView imageView, boolean isCheck,
+ boolean allowAnimate) {
+
+ final int imageResId = isCheck
+ ? R.drawable.add_schedule_button_icon_checked
+ : R.drawable.add_schedule_button_icon_unchecked;
+
+ if (imageView.getTag() != null) {
+ if (imageView.getTag() instanceof Animator) {
+ Animator anim = (Animator) imageView.getTag();
+ anim.end();
+ imageView.setAlpha(1f);
+ }
+ }
+
+ if (allowAnimate && isCheck) {
+ int duration = mActivity.getResources().getInteger(
+ android.R.integer.config_shortAnimTime);
+
+ Animator outAnimator = ObjectAnimator.ofFloat(imageView, View.ALPHA, 0f);
+ outAnimator.setDuration(duration / 2);
+ outAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ imageView.setImageResource(imageResId);
+ }
+ });
+
+ AnimatorSet inAnimator = new AnimatorSet();
+ outAnimator.setDuration(duration);
+ inAnimator.playTogether(
+ ObjectAnimator.ofFloat(imageView, View.ALPHA, 1f),
+ ObjectAnimator.ofFloat(imageView, View.SCALE_X, 0f, 1f),
+ ObjectAnimator.ofFloat(imageView, View.SCALE_Y, 0f, 1f)
+ );
+
+ AnimatorSet set = new AnimatorSet();
+ set.playSequentially(outAnimator, inAnimator);
+ set.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ imageView.setTag(null);
+ }
+ });
+ imageView.setTag(set);
+ set.start();
+ } else {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ imageView.setImageResource(imageResId);
+ }
+ });
+ }
+ }
+}
diff --git a/android/src/main/java/com/google/samples/apps/iosched/util/LoginAndAuthHelper.java b/android/src/main/java/com/google/samples/apps/iosched/util/LoginAndAuthHelper.java
index 094010e..7426b11 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/util/LoginAndAuthHelper.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/util/LoginAndAuthHelper.java
@@ -21,6 +21,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
+import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
@@ -43,7 +44,10 @@
import java.io.IOException;
import java.lang.ref.WeakReference;
-import static com.google.samples.apps.iosched.util.LogUtils.*;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGE;
+import static com.google.samples.apps.iosched.util.LogUtils.LOGW;
+import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
/**
* This helper handles the UI flow for signing in and authenticating an account. It handles
@@ -303,8 +307,13 @@
// Record profile ID, image URL and name
LOGD(TAG, "Saving plus profile ID: " + currentUser.getId());
AccountUtils.setPlusProfileId(mAppContext, mAccountName, currentUser.getId());
- LOGD(TAG, "Saving plus image URL: " + currentUser.getImage().getUrl());
- AccountUtils.setPlusImageUrl(mAppContext, mAccountName, currentUser.getImage().getUrl());
+ String imageUrl = currentUser.getImage().getUrl();
+ if (imageUrl != null) {
+ imageUrl = Uri.parse(imageUrl)
+ .buildUpon().appendQueryParameter("sz", "256").build().toString();
+ }
+ LOGD(TAG, "Saving plus image URL: " + imageUrl);
+ AccountUtils.setPlusImageUrl(mAppContext, mAccountName, imageUrl);
LOGD(TAG, "Saving plus display name: " + currentUser.getDisplayName());
AccountUtils.setPlusName(mAppContext, mAccountName, currentUser.getDisplayName());
Person.Cover cover = currentUser.getCover();
diff --git a/android/src/main/java/com/google/samples/apps/iosched/util/PrefUtils.java b/android/src/main/java/com/google/samples/apps/iosched/util/PrefUtils.java
index 87725fa..750240a 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/util/PrefUtils.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/util/PrefUtils.java
@@ -161,7 +161,7 @@
public static void markUserRefusedSignIn(final Context context, final boolean refused) {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
- sp.edit().putBoolean(PREF_USER_REFUSED_SIGN_IN, refused).apply();
+ sp.edit().putBoolean(PREF_USER_REFUSED_SIGN_IN, refused).commit();
}
public static boolean hasUserRefusedSignIn(final Context context) {
@@ -313,8 +313,8 @@
sp.registerOnSharedPreferenceChangeListener(listener);
}
- public static void unrgisterOnSharedPreferenceChangeListener(final Context context,
- SharedPreferences.OnSharedPreferenceChangeListener listener) {
+ public static void unregisterOnSharedPreferenceChangeListener(final Context context,
+ SharedPreferences.OnSharedPreferenceChangeListener listener) {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
sp.unregisterOnSharedPreferenceChangeListener(listener);
}
diff --git a/android/src/main/java/com/google/samples/apps/iosched/util/RecentTasksStyler.java b/android/src/main/java/com/google/samples/apps/iosched/util/RecentTasksStyler.java
new file mode 100644
index 0000000..c16779f
--- /dev/null
+++ b/android/src/main/java/com/google/samples/apps/iosched/util/RecentTasksStyler.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2014 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.
+ */
+
+package com.google.samples.apps.iosched.util;
+
+import android.annotation.TargetApi;
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Build;
+
+import com.google.samples.apps.iosched.R;
+
+/**
+ * Helper class that applies the proper icon, title and background color to recent tasks list.
+ */
+public class RecentTasksStyler {
+ private static Bitmap sIcon = null;
+
+ private RecentTasksStyler() {
+ }
+
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ public static void styleRecentTasksEntry(Activity activity) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
+ return;
+ }
+
+ Resources resources = activity.getResources();
+ String label = resources.getString(activity.getApplicationInfo().labelRes);
+ int colorPrimary = resources.getColor(R.color.theme_primary);
+
+ if (sIcon == null) {
+ // Cache to avoid decoding the same bitmap on every Activity change
+ sIcon = BitmapFactory.decodeResource(resources, R.drawable.ic_stat_notification);
+ }
+
+ activity.setTaskDescription(new ActivityManager.TaskDescription(label, sIcon, colorPrimary));
+ }
+}
\ No newline at end of file
diff --git a/android/src/main/java/com/google/samples/apps/iosched/util/SessionsHelper.java b/android/src/main/java/com/google/samples/apps/iosched/util/SessionsHelper.java
index 8d70429..aa98f11 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/util/SessionsHelper.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/util/SessionsHelper.java
@@ -16,25 +16,20 @@
package com.google.samples.apps.iosched.util;
-import android.annotation.TargetApi;
import android.app.Activity;
import android.content.AsyncQueryHandler;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
-import android.os.Build;
import android.support.v4.app.ShareCompat;
import android.view.MenuItem;
import com.google.samples.apps.iosched.R;
import com.google.samples.apps.iosched.appwidget.ScheduleWidgetProvider;
-import com.google.samples.apps.iosched.gcm.ServerUtilities;
import com.google.samples.apps.iosched.provider.ScheduleContract;
import com.google.samples.apps.iosched.sync.SyncHelper;
-import com.google.samples.apps.iosched.sync.TriggerSyncReceiver;
-import com.google.samples.apps.iosched.ui.MapFragment;
-import com.google.samples.apps.iosched.ui.phone.MapActivity;
+import com.google.samples.apps.iosched.ui.BaseMapActivity;
import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
@@ -55,8 +50,8 @@
public void startMapActivity(String roomId) {
Intent intent = new Intent(mActivity.getApplicationContext(),
UIUtils.getMapActivityClass(mActivity));
- intent.putExtra(MapFragment.EXTRA_ROOM, roomId);
- intent.putExtra(MapActivity.EXTRA_DETACHED_MODE, true);
+ intent.putExtra(BaseMapActivity.EXTRA_ROOM, roomId);
+ intent.putExtra(BaseMapActivity.EXTRA_DETACHED_MODE, true);
mActivity.startActivity(intent);
}
@@ -71,27 +66,7 @@
public void tryConfigureShareMenuItem(MenuItem menuItem, int messageTemplateResId,
final String title, String hashtags, String url) {
- // Intentionally removed by Roman
-// if (UIUtils.hasICS()) {
-// ActionProvider itemProvider = menuItem.getActionProvider();
-// ShareActionProvider provider;
-// if (!(itemProvider instanceof ShareActionProvider)) {
-// provider = new ShareActionProvider(mActivity);
-// } else {
-// provider = (ShareActionProvider) itemProvider;
-// }
-// provider.setShareIntent(createShareIntent(messageTemplateResId, title, hashtags, url));
-// provider.setOnShareTargetSelectedListener(
-// new ShareActionProvider.OnShareTargetSelectedListener() {
-// @Override
-// public boolean onShareTargetSelected(ShareActionProvider source, Intent intent) {
-// AnalyticsManager.sendEvent("Session", "Shared", title, 0L);
-// return false;
-// }
-// });
-//
-// menuItem.setActionProvider(provider);
-// }
+ // TODO: remove
}
public void shareSession(Context context, int messageTemplateResId, String title,
diff --git a/android/src/main/java/com/google/samples/apps/iosched/util/UIUtils.java b/android/src/main/java/com/google/samples/apps/iosched/util/UIUtils.java
index 2cafde5..6440085 100644
--- a/android/src/main/java/com/google/samples/apps/iosched/util/UIUtils.java
+++ b/android/src/main/java/com/google/samples/apps/iosched/util/UIUtils.java
@@ -26,11 +26,12 @@
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
-import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
-import android.graphics.*;
-import android.graphics.drawable.Drawable;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.ColorMatrixColorFilter;
+import android.graphics.Typeface;
import android.net.Uri;
import android.os.Build;
import android.preference.PreferenceManager;
@@ -74,9 +75,10 @@
* Factor applied to session color to derive the background color on panels and when
* a session photo could not be downloaded (or while it is being downloaded)
*/
- public static final float SESSION_BG_COLOR_SCALE_FACTOR = 0.65f;
- public static final float SESSION_PHOTO_SCRIM_ALPHA = 0.75f;
+ public static final float SESSION_BG_COLOR_SCALE_FACTOR = 0.75f;
+ private static final float SESSION_PHOTO_SCRIM_ALPHA = 0.25f; // 0=invisible, 1=visible image
+ private static final float SESSION_PHOTO_SCRIM_SATURATION = 0.2f; // 0=gray, 1=color image
public static final String TARGET_FORM_FACTOR_ACTIVITY_METADATA =
"com.google.samples.apps.iosched.meta.TARGET_FORM_FACTOR";
@@ -294,9 +296,7 @@
}
public static boolean isTablet(Context context) {
- return (context.getResources().getConfiguration().screenLayout
- & Configuration.SCREENLAYOUT_SIZE_MASK)
- >= Configuration.SCREENLAYOUT_SIZE_LARGE;
+ return context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
}
// Whether a feedback notification was fired for a particular session. In the event that a
@@ -429,7 +429,7 @@
}
}
- private static final int[] RES_IDS_ACTION_BAR_SIZE = { android.R.attr.actionBarSize };
+ private static final int[] RES_IDS_ACTION_BAR_SIZE = { R.attr.actionBarSize };
/** Calculates the Action Bar height in pixels. */
public static int calculateActionBarSize(Context context) {
@@ -467,10 +467,6 @@
return scaleColor(color, SESSION_BG_COLOR_SCALE_FACTOR, false);
}
- public static boolean hasActionBar(Activity activity) {
- return activity.getActionBar() != null;
- }
-
public static void showHashtagStream(final Context context, String hashTag) {
final String hashTagsString = getSessionHashtagsString(hashTag);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(
@@ -537,4 +533,16 @@
return (value - min) / (float) (max - min);
}
+
+ // Desaturates and color-scrims the image
+ public static ColorFilter makeSessionImageScrimColorFilter(int sessionColor) {
+ float a = SESSION_PHOTO_SCRIM_ALPHA;
+ float sat = SESSION_PHOTO_SCRIM_SATURATION; // saturation (0=gray, 1=color)
+ return new ColorMatrixColorFilter(new float[]{
+ ((1 - 0.213f) * sat + 0.213f) * a, ((0 - 0.715f) * sat + 0.715f) * a, ((0 - 0.072f) * sat + 0.072f) * a, 0, Color.red(sessionColor) * (1 - a),
+ ((0 - 0.213f) * sat + 0.213f) * a, ((1 - 0.715f) * sat + 0.715f) * a, ((0 - 0.072f) * sat + 0.072f) * a, 0, Color.green(sessionColor) * (1 - a),
+ ((0 - 0.213f) * sat + 0.213f) * a, ((0 - 0.715f) * sat + 0.715f) * a, ((1 - 0.072f) * sat + 0.072f) * a, 0, Color.blue(sessionColor) * (1 - a),
+ 0, 0, 0, 0, 255
+ });
+ }
}
diff --git a/android/src/main/res/anim-v21/add_schedule_fab_state_list_anim.xml b/android/src/main/res/anim-v21/add_schedule_fab_state_list_anim.xml
new file mode 100644
index 0000000..2c6e6dc
--- /dev/null
+++ b/android/src/main/res/anim-v21/add_schedule_fab_state_list_anim.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ Copyright 2014 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:state_enabled="true"
+ android:state_pressed="true">
+ <set>
+ <objectAnimator
+ android:duration="@android:integer/config_shortAnimTime"
+ android:propertyName="translationZ"
+ android:valueTo="@dimen/fab_press_translation_z"
+ android:valueType="floatType" />
+ </set>
+ </item>
+ <item>
+ <set>
+ <objectAnimator
+ android:duration="@android:integer/config_shortAnimTime"
+ android:propertyName="translationZ"
+ android:valueTo="0"
+ android:valueType="floatType" />
+ </set>
+ </item>
+</selector>
diff --git a/android/src/main/res/drawable-hdpi/ic_launcher.png b/android/src/main/res/drawable-hdpi/ic_launcher.png
deleted file mode 100755
index 633e56f..0000000
--- a/android/src/main/res/drawable-hdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/android/src/main/res/drawable-mdpi/ic_launcher.png b/android/src/main/res/drawable-mdpi/ic_launcher.png
deleted file mode 100755
index 786a92f..0000000
--- a/android/src/main/res/drawable-mdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/android/src/lpreview/res/drawable-v21/add_schedule_fab_icon_anim.xml b/android/src/main/res/drawable-v21/add_schedule_fab_icon_anim.xml
similarity index 70%
rename from android/src/lpreview/res/drawable-v21/add_schedule_fab_icon_anim.xml
rename to android/src/main/res/drawable-v21/add_schedule_fab_icon_anim.xml
index 809878e..b161902 100644
--- a/android/src/lpreview/res/drawable-v21/add_schedule_fab_icon_anim.xml
+++ b/android/src/main/res/drawable-v21/add_schedule_fab_icon_anim.xml
@@ -15,267 +15,209 @@
-->
<animated-selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_checked="true" android:id="@+id/state_on">
- <bitmap android:src="@drawable/ic_done_anim_030"
- android:tint="@color/theme_accent_1" />
+ <item
+ android:id="@+id/state_on"
+ android:state_checked="true">
+ <bitmap android:src="@drawable/ic_done_anim_030" />
</item>
<item android:id="@+id/state_off">
- <bitmap android:src="@drawable/ic_plus_anim_030"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_030" />
</item>
- <transition android:fromId="@+id/state_on" android:toId="@+id/state_off">
+ <transition
+ android:fromId="@+id/state_on"
+ android:toId="@+id/state_off">
<animation-list>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_000"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_000" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_001"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_001" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_002"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_002" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_003"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_003" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_004"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_004" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_005"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_005" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_006"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_006" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_007"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_007" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_008"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_008" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_009"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_009" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_010"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_010" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_011"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_011" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_012"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_012" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_013"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_013" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_014"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_014" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_015"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_015" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_016"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_016" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_017"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_017" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_018"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_018" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_019"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_019" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_020"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_020" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_021"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_021" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_022"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_022" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_023"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_023" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_024"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_024" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_025"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_025" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_026"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_026" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_027"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_027" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_028"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_028" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_029"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_029" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_plus_anim_030"
- android:tint="#fff" />
+ <bitmap android:src="@drawable/ic_plus_anim_030" />
</item>
</animation-list>
</transition>
- <transition android:fromId="@+id/state_off" android:toId="@+id/state_on">
+ <transition
+ android:fromId="@+id/state_off"
+ android:toId="@+id/state_on">
<animation-list>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_000"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_000" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_001"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_001" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_002"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_002" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_003"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_003" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_004"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_004" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_005"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_005" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_006"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_006" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_007"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_007" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_008"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_008" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_009"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_009" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_010"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_010" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_011"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_011" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_012"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_012" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_013"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_013" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_014"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_014" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_015"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_015" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_016"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_016" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_017"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_017" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_018"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_018" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_019"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_019" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_020"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_020" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_021"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_021" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_022"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_022" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_023"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_023" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_024"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_024" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_025"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_025" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_026"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_026" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_027"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_027" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_028"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_028" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_029"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_029" />
</item>
<item android:duration="16">
- <bitmap android:src="@drawable/ic_done_anim_030"
- android:tint="@color/theme_accent_1" />
+ <bitmap android:src="@drawable/ic_done_anim_030" />
</item>
</animation-list>
</transition>
diff --git a/android/src/lpreview/res/drawable-v21/add_schedule_fab_ripple_background_off.xml b/android/src/main/res/drawable-v21/add_schedule_fab_ripple_background_off.xml
similarity index 100%
rename from android/src/lpreview/res/drawable-v21/add_schedule_fab_ripple_background_off.xml
rename to android/src/main/res/drawable-v21/add_schedule_fab_ripple_background_off.xml
diff --git a/android/src/lpreview/res/drawable-v21/add_schedule_fab_ripple_background_on.xml b/android/src/main/res/drawable-v21/add_schedule_fab_ripple_background_on.xml
similarity index 96%
rename from android/src/lpreview/res/drawable-v21/add_schedule_fab_ripple_background_on.xml
rename to android/src/main/res/drawable-v21/add_schedule_fab_ripple_background_on.xml
index 3b2dcad..2a4d1fe 100644
--- a/android/src/lpreview/res/drawable-v21/add_schedule_fab_ripple_background_on.xml
+++ b/android/src/main/res/drawable-v21/add_schedule_fab_ripple_background_on.xml
@@ -15,7 +15,7 @@
limitations under the License.
-->
-<ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="#f1f1f1">
+<ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="#ccc">
<item>
<shape>
<solid android:color="#fff" />
diff --git a/android/src/lpreview/res/drawable-v21/photo_item_foreground.xml b/android/src/main/res/drawable-v21/photo_item_foreground.xml
similarity index 100%
rename from android/src/lpreview/res/drawable-v21/photo_item_foreground.xml
rename to android/src/main/res/drawable-v21/photo_item_foreground.xml
diff --git a/android/src/lpreview/res/values-v21/dimens.xml b/android/src/main/res/drawable-v21/photo_item_foreground_borderless.xml
similarity index 86%
rename from android/src/lpreview/res/values-v21/dimens.xml
rename to android/src/main/res/drawable-v21/photo_item_foreground_borderless.xml
index 6e4a762..7926e0a 100644
--- a/android/src/lpreview/res/values-v21/dimens.xml
+++ b/android/src/main/res/drawable-v21/photo_item_foreground_borderless.xml
@@ -14,6 +14,4 @@
limitations under the License.
-->
-<resources>
- <dimen name="spinner_left_padding">16dp</dimen>
-</resources>
+<ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="#2fff" />
diff --git a/android/src/lpreview/res/drawable-v21/popup_item_background.xml b/android/src/main/res/drawable-v21/popup_item_background.xml
similarity index 100%
rename from android/src/lpreview/res/drawable-v21/popup_item_background.xml
rename to android/src/main/res/drawable-v21/popup_item_background.xml
diff --git a/android/src/lpreview/res/drawable-v21/schedule_item_touchoverlay.xml b/android/src/main/res/drawable-v21/schedule_item_touchoverlay.xml
similarity index 100%
rename from android/src/lpreview/res/drawable-v21/schedule_item_touchoverlay.xml
rename to android/src/main/res/drawable-v21/schedule_item_touchoverlay.xml
diff --git a/android/src/lpreview/res/drawable-v21/schedule_item_touchoverlay_dark.xml b/android/src/main/res/drawable-v21/schedule_item_touchoverlay_dark.xml
similarity index 100%
rename from android/src/lpreview/res/drawable-v21/schedule_item_touchoverlay_dark.xml
rename to android/src/main/res/drawable-v21/schedule_item_touchoverlay_dark.xml
diff --git a/android/src/main/res/drawable-xhdpi/ic_launcher.png b/android/src/main/res/drawable-xhdpi/ic_launcher.png
deleted file mode 100755
index a9f7abb..0000000
--- a/android/src/main/res/drawable-xhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_000.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_000.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_000.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_000.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_001.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_001.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_001.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_001.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_002.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_002.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_002.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_002.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_003.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_003.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_003.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_003.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_004.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_004.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_004.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_004.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_005.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_005.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_005.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_005.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_006.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_006.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_006.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_006.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_007.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_007.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_007.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_007.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_008.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_008.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_008.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_008.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_009.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_009.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_009.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_009.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_010.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_010.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_010.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_010.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_011.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_011.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_011.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_011.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_012.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_012.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_012.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_012.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_013.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_013.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_013.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_013.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_014.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_014.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_014.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_014.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_015.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_015.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_015.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_015.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_016.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_016.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_016.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_016.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_017.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_017.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_017.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_017.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_018.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_018.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_018.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_018.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_019.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_019.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_019.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_019.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_020.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_020.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_020.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_020.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_021.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_021.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_021.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_021.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_022.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_022.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_022.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_022.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_023.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_023.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_023.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_023.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_024.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_024.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_024.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_024.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_025.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_025.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_025.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_025.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_026.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_026.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_026.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_026.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_027.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_027.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_027.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_027.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_028.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_028.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_028.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_028.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_029.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_029.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_029.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_029.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_030.png b/android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_030.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_done_anim_030.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_done_anim_030.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_000.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_000.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_000.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_000.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_001.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_001.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_001.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_001.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_002.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_002.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_002.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_002.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_003.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_003.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_003.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_003.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_004.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_004.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_004.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_004.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_005.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_005.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_005.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_005.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_006.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_006.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_006.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_006.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_007.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_007.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_007.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_007.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_008.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_008.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_008.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_008.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_009.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_009.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_009.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_009.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_010.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_010.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_010.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_010.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_011.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_011.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_011.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_011.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_012.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_012.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_012.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_012.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_013.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_013.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_013.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_013.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_014.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_014.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_014.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_014.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_015.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_015.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_015.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_015.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_016.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_016.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_016.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_016.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_017.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_017.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_017.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_017.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_018.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_018.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_018.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_018.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_019.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_019.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_019.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_019.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_020.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_020.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_020.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_020.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_021.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_021.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_021.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_021.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_022.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_022.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_022.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_022.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_023.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_023.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_023.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_023.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_024.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_024.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_024.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_024.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_025.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_025.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_025.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_025.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_026.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_026.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_026.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_026.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_027.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_027.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_027.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_027.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_028.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_028.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_028.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_028.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_029.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_029.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_029.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_029.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_030.png b/android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_030.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_plus_anim_030.png
rename to android/src/main/res/drawable-xxhdpi-v21/ic_plus_anim_030.png
Binary files differ
diff --git a/android/src/lpreview/res/drawable-xxhdpi-v21/ic_ab_close.png b/android/src/main/res/drawable-xxhdpi/ic_ab_close.png
similarity index 100%
rename from android/src/lpreview/res/drawable-xxhdpi-v21/ic_ab_close.png
rename to android/src/main/res/drawable-xxhdpi/ic_ab_close.png
Binary files differ
diff --git a/android/src/main/res/drawable-xxhdpi/ic_action_share.png b/android/src/main/res/drawable-xxhdpi/ic_action_share.png
index ea53bb6..343dea6 100644
--- a/android/src/main/res/drawable-xxhdpi/ic_action_share.png
+++ b/android/src/main/res/drawable-xxhdpi/ic_action_share.png
Binary files differ
diff --git a/android/src/main/res/drawable-xxhdpi/ic_action_social_stream.png b/android/src/main/res/drawable-xxhdpi/ic_action_social_stream.png
index 41f1e04..5334780 100644
--- a/android/src/main/res/drawable-xxhdpi/ic_action_social_stream.png
+++ b/android/src/main/res/drawable-xxhdpi/ic_action_social_stream.png
Binary files differ
diff --git a/android/src/main/res/drawable-xxhdpi/ic_drawer.png b/android/src/main/res/drawable-xxhdpi/ic_drawer.png
index 26420e5..19bae3e 100644
--- a/android/src/main/res/drawable-xxhdpi/ic_drawer.png
+++ b/android/src/main/res/drawable-xxhdpi/ic_drawer.png
Binary files differ
diff --git a/android/src/main/res/drawable-xxhdpi/ic_drawer_accounts_collapse.png b/android/src/main/res/drawable-xxhdpi/ic_drawer_accounts_collapse.png
index 71358dc..877de76 100644
--- a/android/src/main/res/drawable-xxhdpi/ic_drawer_accounts_collapse.png
+++ b/android/src/main/res/drawable-xxhdpi/ic_drawer_accounts_collapse.png
Binary files differ
diff --git a/android/src/main/res/drawable-xxhdpi/ic_drawer_accounts_expand.png b/android/src/main/res/drawable-xxhdpi/ic_drawer_accounts_expand.png
index 254eebb..2dad32e 100644
--- a/android/src/main/res/drawable-xxhdpi/ic_drawer_accounts_expand.png
+++ b/android/src/main/res/drawable-xxhdpi/ic_drawer_accounts_expand.png
Binary files differ
diff --git a/android/src/main/res/drawable-xxhdpi/ic_drawer_feedback.png b/android/src/main/res/drawable-xxhdpi/ic_drawer_feedback.png
deleted file mode 100644
index 71b5219..0000000
--- a/android/src/main/res/drawable-xxhdpi/ic_drawer_feedback.png
+++ /dev/null
Binary files differ
diff --git a/android/src/main/res/drawable-xxhdpi/ic_drawer_people_met.png b/android/src/main/res/drawable-xxhdpi/ic_drawer_people_met.png
index 7695310..f602193 100644
--- a/android/src/main/res/drawable-xxhdpi/ic_drawer_people_met.png
+++ b/android/src/main/res/drawable-xxhdpi/ic_drawer_people_met.png
Binary files differ
diff --git a/android/src/main/res/drawable-xxhdpi/ic_drawer_social.png b/android/src/main/res/drawable-xxhdpi/ic_drawer_social.png
index 7932aa1..541c615 100644
--- a/android/src/main/res/drawable-xxhdpi/ic_drawer_social.png
+++ b/android/src/main/res/drawable-xxhdpi/ic_drawer_social.png
Binary files differ
diff --git a/android/src/main/res/drawable-xxhdpi/ic_launcher.png b/android/src/main/res/drawable-xxhdpi/ic_launcher.png
deleted file mode 100755
index 9680dc4..0000000
--- a/android/src/main/res/drawable-xxhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/android/src/main/res/drawable-xxhdpi/ic_up.png b/android/src/main/res/drawable-xxhdpi/ic_up.png
index dc2da0b..3396894 100644
--- a/android/src/main/res/drawable-xxhdpi/ic_up.png
+++ b/android/src/main/res/drawable-xxhdpi/ic_up.png
Binary files differ
diff --git a/android/src/main/res/drawable-xxxhdpi/ic_launcher.png b/android/src/main/res/drawable-xxxhdpi/ic_launcher.png
deleted file mode 100644
index 3864db3..0000000
--- a/android/src/main/res/drawable-xxxhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/android/src/main/res/layout-sw600dp/activity_map.xml b/android/src/main/res/layout-sw600dp/activity_map.xml
index 2e7ff8a..427032e 100644
--- a/android/src/main/res/layout-sw600dp/activity_map.xml
+++ b/android/src/main/res/layout-sw600dp/activity_map.xml
@@ -16,14 +16,20 @@
<android.support.v4.widget.DrawerLayout
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"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:fitsSystemWindows="true"
tools:context=".ui.phone.MapActivity">
- <FrameLayout android:layout_width="match_parent"
- android:layout_height="match_parent">
+ <com.google.samples.apps.iosched.ui.widget.ScrimInsetsFrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/capture_insets_frame_layout"
+ app:insetForeground="@color/translucent_statusbar_background"
+ android:fitsSystemWindows="true">
<FrameLayout
android:id="@+id/fragment_container_map"
@@ -34,9 +40,9 @@
<View android:layout_width="fill_parent"
android:layout_height="fill_parent" />
- <include layout="@layout/toolbar_actionbar_with_translucent_background" />
+ <include layout="@layout/toolbar_actionbar_translucent" />
- </FrameLayout>
+ </com.google.samples.apps.iosched.ui.widget.ScrimInsetsFrameLayout>
<LinearLayout android:id="@+id/map_detail_spacer"
android:visibility="gone"
@@ -46,46 +52,58 @@
android:orientation="horizontal"
android:weightSum="2"
android:gravity="end"
- android:baselineAligned="false">
+ android:baselineAligned="false"
+ android:clipToPadding="false">
- <RelativeLayout android:id="@+id/map_detail_popup"
+ <android.support.v7.widget.CardView android:id="@+id/map_detail_popup"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_marginLeft="@dimen/multipane_half_padding"
android:layout_marginBottom="@dimen/multipane_half_padding"
android:layout_marginRight="@dimen/map_multipane_right_padding"
- android:background="@drawable/card_bg">
+ app:cardBackgroundColor="#fff"
+ app:cardCornerRadius="@dimen/card_corner_radius"
+ app:cardElevation="@dimen/card_elevation"
+ app:cardPreventCornerOverlap="false">
- <ImageButton android:id="@+id/close_button"
- android:layout_alignParentTop="true"
- android:layout_alignParentRight="true"
- android:src="@drawable/ic_pane_close"
- android:background="?selectableItemBackgroundBorderless"
- android:layout_width="48dp"
- android:layout_height="@dimen/detail_breadcrumb_height"
- android:contentDescription="@string/close_detail_pane" />
-
- <android.app.FragmentBreadCrumbs android:id="@+id/breadcrumbs"
- android:layout_alignParentTop="true"
- android:layout_alignParentLeft="true"
- android:layout_toLeftOf="@id/close_button"
- android:paddingLeft="8dp"
- android:layout_height="@dimen/detail_breadcrumb_height"
+ <RelativeLayout
android:layout_width="match_parent"
- android:gravity="center_vertical|left" />
+ android:layout_height="match_parent">
- <FrameLayout android:id="@+id/fragment_container_detail"
- android:layout_alignParentBottom="true"
- android:layout_alignParentLeft="true"
- android:layout_alignParentRight="true"
- android:layout_below="@id/breadcrumbs"
- android:layout_width="match_parent"
- android:layout_height="0dp" />
- </RelativeLayout>
+ <ImageButton
+ android:id="@+id/close_button"
+ android:layout_width="48dp"
+ android:layout_height="@dimen/detail_breadcrumb_height"
+ android:layout_alignParentRight="true"
+ android:layout_alignParentTop="true"
+ android:background="?selectableItemBackgroundBorderless"
+ android:contentDescription="@string/close_detail_pane"
+ android:src="@drawable/ic_pane_close" />
+
+ <android.app.FragmentBreadCrumbs
+ android:id="@+id/breadcrumbs"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/detail_breadcrumb_height"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentTop="true"
+ android:layout_toLeftOf="@id/close_button"
+ android:gravity="center_vertical|left"
+ android:paddingLeft="8dp" />
+
+ <FrameLayout
+ android:id="@+id/fragment_container_detail"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentRight="true"
+ android:layout_below="@id/breadcrumbs" />
+ </RelativeLayout>
+ </android.support.v7.widget.CardView>
</LinearLayout>
<!-- Nav drawer -->
- <include layout="@layout/navdrawer_for_ab_overlay" />
+ <include layout="@layout/navdrawer" />
</android.support.v4.widget.DrawerLayout>
diff --git a/android/src/main/res/layout-sw600dp/activity_welcome.xml b/android/src/main/res/layout-sw600dp/activity_welcome.xml
index 9c314fe..d2e234b 100644
--- a/android/src/main/res/layout-sw600dp/activity_welcome.xml
+++ b/android/src/main/res/layout-sw600dp/activity_welcome.xml
@@ -15,6 +15,7 @@
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:iosched="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
@@ -30,92 +31,98 @@
android:tint="#7000"
android:layout_gravity="center|top" />
- <LinearLayout
+ <android.support.v7.widget.CardView
android:layout_width="500dp"
android:layout_height="wrap_content"
- android:orientation="vertical"
- android:background="@drawable/card_bg"
- android:layout_gravity="center">
+ android:layout_gravity="center"
+ iosched:cardBackgroundColor="#fff"
+ iosched:cardCornerRadius="@dimen/card_corner_radius"
+ iosched:cardElevation="@dimen/card_elevation"
+ iosched:cardPreventCornerOverlap="false">
- <ScrollView
+ <LinearLayout
android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1">
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+ <ScrollView
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingBottom="48dp"
+ android:paddingLeft="72dp"
+ android:paddingRight="72dp"
+ android:paddingTop="48dp">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:fontFamily="@string/font_fontFamily_medium"
+ android:text="@string/welcome_to_google_i_o_app"
+ android:textColor="@color/theme_primary"
+ android:textSize="@dimen/text_size_xlarge"
+ android:textStyle="@integer/font_textStyle_medium" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:autoLink="web"
+ android:text="@string/welcome_text"
+ android:textColor="@color/body_text_2"
+ android:textSize="@dimen/text_size_medium" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:autoLink="web"
+ android:text="@string/eula_legal_text"
+ android:textColor="@color/body_text_2"
+ android:textSize="@dimen/text_size_medium" />
+
+ </LinearLayout>
+ </ScrollView>
+
+ <!-- Button bar -->
<LinearLayout
android:layout_width="match_parent"
- android:paddingLeft="72dp"
- android:paddingRight="72dp"
- android:paddingTop="48dp"
- android:paddingBottom="48dp"
- android:orientation="vertical"
- android:layout_height="wrap_content">
+ android:layout_height="48dp"
+ android:layout_gravity="bottom"
+ android:background="@color/theme_primary">
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textSize="@dimen/text_size_xlarge"
- android:textColor="@color/theme_primary"
- android:textStyle="@integer/font_textStyle_medium"
+ <Button
+ android:id="@+id/button_decline"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:background="?photoItemForeground"
android:fontFamily="@string/font_fontFamily_medium"
- android:text="@string/welcome_to_google_i_o_app" />
-
- <TextView
- android:layout_height="wrap_content"
- android:layout_marginTop="16dp"
- android:layout_width="match_parent"
- android:textColor="@color/body_text_2"
- android:autoLink="web"
+ android:text="@string/decline"
+ android:textAllCaps="true"
+ android:textColor="#8fff"
android:textSize="@dimen/text_size_medium"
- android:text="@string/welcome_text" />
+ android:textStyle="@integer/font_textStyle_medium" />
- <TextView
- android:layout_height="wrap_content"
- android:layout_marginTop="16dp"
- android:layout_width="match_parent"
- android:textColor="@color/body_text_2"
+ <Button
+ android:id="@+id/button_accept"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:background="?photoItemForeground"
+ android:fontFamily="@string/font_fontFamily_medium"
+ android:text="@string/accept"
+ android:textAllCaps="true"
+ android:textColor="#fff"
android:textSize="@dimen/text_size_medium"
- android:autoLink="web"
- android:text="@string/eula_legal_text" />
+ android:textStyle="@integer/font_textStyle_medium" />
</LinearLayout>
- </ScrollView>
-
- <!-- Button bar -->
- <LinearLayout
- android:layout_height="48dp"
- android:background="@color/theme_primary"
- android:layout_gravity="bottom"
- android:layout_width="match_parent">
-
- <Button
- android:layout_width="0dp"
- android:layout_weight="1"
- android:layout_height="match_parent"
- android:background="?photoItemForeground"
- android:text="@string/decline"
- android:textColor="#8fff"
- android:textSize="@dimen/text_size_medium"
- android:textStyle="@integer/font_textStyle_medium"
- android:fontFamily="@string/font_fontFamily_medium"
- android:textAllCaps="true"
- android:id="@+id/button_decline" />
-
- <Button
- android:id="@+id/button_accept"
- android:layout_width="0dp"
- android:layout_weight="1"
- android:layout_height="match_parent"
- android:background="?photoItemForeground"
- android:text="@string/accept"
- android:textSize="@dimen/text_size_medium"
- android:textStyle="@integer/font_textStyle_medium"
- android:fontFamily="@string/font_fontFamily_medium"
- android:textAllCaps="true"
- android:textColor="#fff" />
-
</LinearLayout>
-
- </LinearLayout>
-
+ </android.support.v7.widget.CardView>
</FrameLayout>
diff --git a/android/src/lpreview/res/layout-v21/include_add_schedule_fab.xml b/android/src/main/res/layout-v21/include_add_schedule_fab.xml
similarity index 100%
rename from android/src/lpreview/res/layout-v21/include_add_schedule_fab.xml
rename to android/src/main/res/layout-v21/include_add_schedule_fab.xml
diff --git a/android/src/main/res/layout/activity_browse_sessions.xml b/android/src/main/res/layout/activity_browse_sessions.xml
index c5f3e62..6d2089a 100644
--- a/android/src/main/res/layout/activity_browse_sessions.xml
+++ b/android/src/main/res/layout/activity_browse_sessions.xml
@@ -20,6 +20,7 @@
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:fitsSystemWindows="true"
tools:context=".ui.BrowseSessionsActivity">
<!-- Main layout -->
@@ -56,11 +57,9 @@
<LinearLayout
android:id="@+id/filters_box"
android:visibility="gone"
- android:layout_marginTop="?actionBarOverlayTopOffset"
android:paddingLeft="?spinnerBarInsetStart"
android:layout_width="match_parent"
android:layout_height="@dimen/filterbar_height"
- android:background="@color/theme_primary"
android:orientation="horizontal">
<Spinner style="@style/Widget.IOSched.HeaderBar.Spinner"
@@ -82,12 +81,12 @@
<FrameLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
- android:layout_marginTop="?android:actionBarSize">
+ android:layout_marginTop="?actionBarSize">
<include layout="@layout/include_butter_bar" />
</FrameLayout>
</com.google.samples.apps.iosched.ui.widget.DrawShadowFrameLayout>
<!-- Nav drawer -->
- <include layout="@layout/navdrawer_for_ab_overlay" />
+ <include layout="@layout/navdrawer" />
</android.support.v4.widget.DrawerLayout>
diff --git a/android/src/main/res/layout/activity_experts_directory.xml b/android/src/main/res/layout/activity_experts_directory.xml
index ffef6a7..6095f23 100644
--- a/android/src/main/res/layout/activity_experts_directory.xml
+++ b/android/src/main/res/layout/activity_experts_directory.xml
@@ -20,6 +20,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
+ android:fitsSystemWindows="true"
tools:context=".ui.ExpertsDirectoryActivity"
android:layout_height="match_parent">
@@ -49,11 +50,9 @@
<!-- Spinners for additional filters -->
<LinearLayout
android:id="@+id/filters_box"
- android:layout_marginTop="?actionBarOverlayTopOffset"
android:paddingLeft="?spinnerBarInsetStart"
android:layout_width="match_parent"
android:layout_height="@dimen/filterbar_height"
- android:background="@color/theme_primary"
android:orientation="horizontal">
<Spinner style="@style/Widget.IOSched.HeaderBar.Spinner"
@@ -73,6 +72,6 @@
</com.google.samples.apps.iosched.ui.widget.DrawShadowFrameLayout>
<!-- Nav drawer -->
- <include layout="@layout/navdrawer_for_ab_overlay" />
+ <include layout="@layout/navdrawer" />
</android.support.v4.widget.DrawerLayout>
diff --git a/android/src/main/res/layout/activity_feedback.xml b/android/src/main/res/layout/activity_feedback.xml
new file mode 100644
index 0000000..a19e57e
--- /dev/null
+++ b/android/src/main/res/layout/activity_feedback.xml
@@ -0,0 +1,30 @@
+<!--
+ Copyright 2014 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.
+ -->
+
+<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"
+ tools:context=".ui.SessionFeedbackActivity">
+
+ <include layout="@layout/toolbar_actionbar_with_headerbar" />
+
+ <FrameLayout
+ android:id="@+id/root_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+</LinearLayout>
\ No newline at end of file
diff --git a/android/src/main/res/layout/activity_map.xml b/android/src/main/res/layout/activity_map.xml
index 4c63eb7..6312b32 100644
--- a/android/src/main/res/layout/activity_map.xml
+++ b/android/src/main/res/layout/activity_map.xml
@@ -15,30 +15,39 @@
-->
<android.support.v4.widget.DrawerLayout
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"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:fitsSystemWindows="true"
tools:context=".ui.phone.MapActivity">
- <FrameLayout android:layout_width="match_parent"
- android:layout_height="match_parent">
+ <com.google.samples.apps.iosched.ui.widget.ScrimInsetsFrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:id="@+id/capture_insets_frame_layout"
+ app:insetForeground="@color/translucent_statusbar_background"
+ android:fitsSystemWindows="true">
<!-- Main layout -->
<FrameLayout
- android:id="@+id/main_content"
+ android:id="@+id/fragment_container_map"
android:layout_width="match_parent"
android:layout_height="match_parent" />
- <!-- Empty view on top of map to avoid rendering issues with navigation drawer pre-JB -->
- <View android:layout_width="match_parent"
+ <include layout="@layout/toolbar_actionbar_translucent" />
+
+ <android.support.v7.widget.CardView
+ android:id="@+id/fragment_container_popup"
+ android:visibility="gone"
+ android:clickable="true"
+ android:layout_width="match_parent"
android:layout_height="match_parent" />
- <include layout="@layout/toolbar_actionbar_with_translucent_background" />
-
- </FrameLayout>
+ </com.google.samples.apps.iosched.ui.widget.ScrimInsetsFrameLayout>
<!-- Nav drawer -->
- <include layout="@layout/navdrawer_for_ab_overlay" />
+ <include layout="@layout/navdrawer" />
</android.support.v4.widget.DrawerLayout>
diff --git a/android/src/main/res/layout/activity_my_schedule_narrow.xml b/android/src/main/res/layout/activity_my_schedule_narrow.xml
index 428bd36..31734cf 100644
--- a/android/src/main/res/layout/activity_my_schedule_narrow.xml
+++ b/android/src/main/res/layout/activity_my_schedule_narrow.xml
@@ -20,6 +20,7 @@
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:fitsSystemWindows="true"
tools:context=".ui.MyScheduleActivity">
<!-- Main layout -->
diff --git a/android/src/main/res/layout/activity_my_schedule_wide.xml b/android/src/main/res/layout/activity_my_schedule_wide.xml
index 35442e2..c8d4c92 100644
--- a/android/src/main/res/layout/activity_my_schedule_wide.xml
+++ b/android/src/main/res/layout/activity_my_schedule_wide.xml
@@ -20,6 +20,7 @@
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:fitsSystemWindows="true"
tools:context=".ui.MyScheduleActivity">
<!-- Main layout -->
diff --git a/android/src/main/res/layout/activity_nearby_eula.xml b/android/src/main/res/layout/activity_nearby_eula.xml
index eb52681..e63ed99 100644
--- a/android/src/main/res/layout/activity_nearby_eula.xml
+++ b/android/src/main/res/layout/activity_nearby_eula.xml
@@ -15,6 +15,7 @@
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:iosched="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
@@ -42,37 +43,46 @@
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingTop="100dp"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
- android:paddingRight="16dp">
+ android:paddingRight="16dp"
+ android:paddingTop="100dp"
+ android:clipToPadding="false">
- <LinearLayout
+ <android.support.v7.widget.CardView
android:layout_width="match_parent"
- android:padding="24dp"
- android:orientation="vertical"
- android:background="@drawable/card_bg"
- android:layout_height="wrap_content">
+ android:layout_height="wrap_content"
+ iosched:cardBackgroundColor="#fff"
+ iosched:cardCornerRadius="@dimen/card_corner_radius"
+ iosched:cardElevation="@dimen/card_elevation"
+ iosched:cardPreventCornerOverlap="false">
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textSize="@dimen/text_size_xlarge"
- android:textColor="@color/theme_primary"
- android:textStyle="@integer/font_textStyle_medium"
- android:fontFamily="@string/font_fontFamily_medium"
- android:text="@string/physicalweb_intro_title" />
-
- <TextView
- android:layout_height="wrap_content"
- android:layout_marginTop="16dp"
+ <LinearLayout
android:layout_width="match_parent"
- android:textColor="@color/body_text_2"
- android:textSize="@dimen/text_size_medium"
- android:autoLink="web"
- android:text="@string/physicalweb_intro_text" />
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:padding="24dp">
- </LinearLayout>
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:fontFamily="@string/font_fontFamily_medium"
+ android:text="@string/physicalweb_intro_title"
+ android:textColor="@color/theme_primary"
+ android:textSize="@dimen/text_size_xlarge"
+ android:textStyle="@integer/font_textStyle_medium" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:autoLink="web"
+ android:text="@string/physicalweb_intro_text"
+ android:textColor="@color/body_text_2"
+ android:textSize="@dimen/text_size_medium" />
+
+ </LinearLayout>
+ </android.support.v7.widget.CardView>
</FrameLayout>
</ScrollView>
diff --git a/android/src/main/res/layout/activity_people_ive_met.xml b/android/src/main/res/layout/activity_people_ive_met.xml
index 04bb368..ad8c28a 100644
--- a/android/src/main/res/layout/activity_people_ive_met.xml
+++ b/android/src/main/res/layout/activity_people_ive_met.xml
@@ -22,6 +22,7 @@
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
tools:context=".ui.PeopleIveMetActivity"
+ android:fitsSystemWindows="true"
android:layout_height="match_parent">
<!-- Main layout -->
diff --git a/android/src/main/res/layout/activity_search.xml b/android/src/main/res/layout/activity_search.xml
index 5275ef4..f46faea 100644
--- a/android/src/main/res/layout/activity_search.xml
+++ b/android/src/main/res/layout/activity_search.xml
@@ -14,9 +14,18 @@
limitations under the License.
-->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
- android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
- tools:context=".ui.SearchActivity"/>
+ android:orientation="vertical">
+
+ <include layout="@layout/toolbar_actionbar_with_headerbar" />
+
+ <FrameLayout
+ android:id="@+id/fragment_container"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ tools:context=".ui.SearchActivity" />
+</LinearLayout>
\ No newline at end of file
diff --git a/android/src/main/res/layout/fragment_session_detail.xml b/android/src/main/res/layout/activity_session_detail.xml
similarity index 79%
rename from android/src/main/res/layout/fragment_session_detail.xml
rename to android/src/main/res/layout/activity_session_detail.xml
index c4c0764..e1a8207 100644
--- a/android/src/main/res/layout/fragment_session_detail.xml
+++ b/android/src/main/res/layout/activity_session_detail.xml
@@ -13,6 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
+
<com.google.samples.apps.iosched.ui.widget.ObservableScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:iosched="http://schemas.android.com/apk/res-auto"
@@ -33,8 +34,7 @@
<!-- Background photo -->
<FrameLayout android:id="@+id/session_photo_container"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:foreground="@drawable/photo_banner_scrim">
+ android:layout_height="wrap_content">
<ImageView
android:id="@+id/session_photo"
@@ -63,6 +63,7 @@
iosched:button2tag="WATCH_NOW"
iosched:button2emphasis="true"
iosched:emphasisColor="@color/theme_accent_2"
+ iosched:cardBackgroundColor="#fff"
android:layout_marginLeft="@dimen/keyline_2_session_detail"
android:layout_marginBottom="16dp"
android:visibility="gone"
@@ -77,6 +78,7 @@
iosched:button2text="@string/give_feedback"
iosched:button2tag="GIVE_FEEDBACK"
iosched:button2emphasis="true"
+ iosched:cardBackgroundColor="#fff"
android:layout_marginLeft="@dimen/keyline_2_session_detail"
android:layout_marginBottom="16dp"
android:visibility="gone"
@@ -191,9 +193,6 @@
<LinearLayout android:orientation="vertical"
android:id="@+id/links_container"
- android:divider="?android:dividerHorizontal"
- android:showDividers="middle"
- android:dividerPadding="16dp"
android:layout_marginLeft="@dimen/keyline_2_session_detail"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
@@ -212,63 +211,48 @@
</LinearLayout>
<!-- Title/subtitle bar (floating; position determined at run time as the content view scrolls) -->
- <FrameLayout android:layout_width="match_parent"
+ <LinearLayout
+ android:id="@+id/header_session"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false"
- android:id="@+id/header_session">
+ android:orientation="vertical"
+ android:paddingBottom="16dp">
- <!-- height assigned dynamically -->
- <View android:id="@+id/header_background"
+ <include layout="@layout/toolbar_actionbar" />
+
+ <!-- Session title -->
+ <TextView android:layout_height="wrap_content"
android:layout_width="match_parent"
- android:layout_height="0dp" />
+ android:layout_marginBottom="0dp"
+ android:layout_marginLeft="@dimen/keyline_2_session_detail"
+ android:layout_marginRight="@dimen/keyline_1"
+ android:text="@string/placeholder_session_title"
+ android:id="@+id/session_title"
+ android:maxLines="4"
+ android:ellipsize="end"
+ android:textSize="@dimen/text_size_large"
+ android:lineSpacingMultiplier="1.1"
+ android:textStyle="@integer/font_textStyle_medium"
+ android:fontFamily="@string/font_fontFamily_medium"
+ android:textColor="@color/body_text_1_inverse"
+ android:textAlignment="viewStart" />
- <LinearLayout
- android:id="@+id/header_session_contents"
+ <!-- Session subtitle -->
+ <TextView android:layout_height="wrap_content"
android:layout_width="match_parent"
- android:orientation="vertical"
- android:paddingLeft="@dimen/keyline_2_session_detail"
- android:paddingTop="16dp"
- android:paddingRight="@dimen/keyline_1"
- android:paddingBottom="16dp"
- android:layout_height="wrap_content">
+ android:layout_marginLeft="@dimen/keyline_2_session_detail"
+ android:layout_marginRight="@dimen/keyline_1"
+ android:text="@string/placeholder_session_subtitle"
+ android:id="@+id/session_subtitle"
+ android:maxLines="2"
+ android:ellipsize="end"
+ android:textSize="16sp"
+ android:textColor="@color/body_text_2_inverse"
+ android:textAlignment="viewStart" />
- <!-- Session title -->
- <TextView android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:layout_marginBottom="0dp"
- android:text="@string/placeholder_session_title"
- android:id="@+id/session_title"
- android:maxLines="4"
- android:ellipsize="end"
- android:textSize="@dimen/text_size_large"
- android:lineSpacingMultiplier="1.1"
- android:textStyle="@integer/font_textStyle_medium"
- android:fontFamily="@string/font_fontFamily_medium"
- android:textColor="@color/body_text_1_inverse"
- android:textAlignment="viewStart" />
-
- <!-- Session subtitle -->
- <TextView android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:text="@string/placeholder_session_subtitle"
- android:id="@+id/session_subtitle"
- android:maxLines="2"
- android:ellipsize="end"
- android:textSize="16sp"
- android:textColor="@color/body_text_2_inverse"
- android:textAlignment="viewStart" />
-
- </LinearLayout>
-
- <View android:id="@+id/header_shadow"
- android:layout_width="match_parent"
- android:layout_height="6dp"
- android:layout_gravity="bottom"
- android:layout_marginBottom="-6dp"
- android:background="@drawable/bottom_shadow" />
-
- </FrameLayout>
+ </LinearLayout>
<!-- FAB -->
<include layout="@layout/include_add_schedule_fab" />
diff --git a/android/src/main/res/layout/activity_settings.xml b/android/src/main/res/layout/activity_settings.xml
new file mode 100644
index 0000000..26be77d
--- /dev/null
+++ b/android/src/main/res/layout/activity_settings.xml
@@ -0,0 +1,31 @@
+<!--
+ Copyright 2014 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.
+ -->
+
+<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"
+ tools:context=".ui.SettingsActivity">
+
+ <include layout="@layout/toolbar_actionbar_with_headerbar" />
+
+ <FrameLayout
+ android:id="@+id/container"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+</LinearLayout>
diff --git a/android/src/main/res/layout/activity_social.xml b/android/src/main/res/layout/activity_social.xml
index 53f4141..3cb29b0 100644
--- a/android/src/main/res/layout/activity_social.xml
+++ b/android/src/main/res/layout/activity_social.xml
@@ -20,6 +20,7 @@
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:fitsSystemWindows="true"
tools:context=".ui.SocialActivity">
<!-- Main layout -->
diff --git a/android/src/main/res/layout/activity_video_library.xml b/android/src/main/res/layout/activity_video_library.xml
index 3f424d8..7e58d24 100644
--- a/android/src/main/res/layout/activity_video_library.xml
+++ b/android/src/main/res/layout/activity_video_library.xml
@@ -20,6 +20,7 @@
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:fitsSystemWindows="true"
tools:context=".ui.VideoLibraryActivity">
<!-- Main layout -->
@@ -49,11 +50,9 @@
<!-- Spinners for additional filters -->
<LinearLayout
android:id="@+id/filters_box"
- android:layout_marginTop="?actionBarOverlayTopOffset"
android:paddingLeft="?spinnerBarInsetStart"
android:layout_width="match_parent"
android:layout_height="@dimen/filterbar_height"
- android:background="@color/theme_primary"
android:orientation="horizontal">
<Spinner style="@style/Widget.IOSched.HeaderBar.Spinner"
@@ -73,6 +72,6 @@
</com.google.samples.apps.iosched.ui.widget.DrawShadowFrameLayout>
<!-- Nav drawer -->
- <include layout="@layout/navdrawer_for_ab_overlay" />
+ <include layout="@layout/navdrawer" />
</android.support.v4.widget.DrawerLayout>
diff --git a/android/src/main/res/layout/activity_welcome.xml b/android/src/main/res/layout/activity_welcome.xml
index 582c29e..0edeeea 100644
--- a/android/src/main/res/layout/activity_welcome.xml
+++ b/android/src/main/res/layout/activity_welcome.xml
@@ -15,6 +15,7 @@
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:iosched="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
@@ -42,46 +43,55 @@
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingTop="100dp"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
- android:paddingRight="16dp">
+ android:paddingRight="16dp"
+ android:paddingTop="100dp"
+ android:clipToPadding="false">
- <LinearLayout
+ <android.support.v7.widget.CardView
android:layout_width="match_parent"
- android:padding="24dp"
- android:orientation="vertical"
- android:background="@drawable/card_bg"
- android:layout_height="wrap_content">
+ android:layout_height="wrap_content"
+ iosched:cardBackgroundColor="#fff"
+ iosched:cardCornerRadius="@dimen/card_corner_radius"
+ iosched:cardElevation="@dimen/card_elevation"
+ iosched:cardPreventCornerOverlap="false">
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textSize="@dimen/text_size_xlarge"
- android:textColor="@color/theme_primary"
- android:textStyle="@integer/font_textStyle_medium"
- android:fontFamily="@string/font_fontFamily_medium"
- android:text="@string/welcome_to_google_i_o_app" />
-
- <TextView
- android:layout_height="wrap_content"
- android:layout_marginTop="16dp"
+ <LinearLayout
android:layout_width="match_parent"
- android:textColor="@color/body_text_2"
- android:autoLink="web"
- android:textSize="@dimen/text_size_medium"
- android:text="@string/welcome_text" />
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:padding="24dp">
- <TextView
- android:layout_height="wrap_content"
- android:layout_marginTop="16dp"
- android:layout_width="match_parent"
- android:textColor="@color/body_text_2"
- android:textSize="@dimen/text_size_medium"
- android:autoLink="web"
- android:text="@string/eula_legal_text" />
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:fontFamily="@string/font_fontFamily_medium"
+ android:text="@string/welcome_to_google_i_o_app"
+ android:textColor="@color/theme_primary"
+ android:textSize="@dimen/text_size_xlarge"
+ android:textStyle="@integer/font_textStyle_medium" />
- </LinearLayout>
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:autoLink="web"
+ android:text="@string/welcome_text"
+ android:textColor="@color/body_text_2"
+ android:textSize="@dimen/text_size_medium" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:autoLink="web"
+ android:text="@string/eula_legal_text"
+ android:textColor="@color/body_text_2"
+ android:textSize="@dimen/text_size_medium" />
+
+ </LinearLayout>
+ </android.support.v7.widget.CardView>
</FrameLayout>
</ScrollView>
diff --git a/android/src/main/res/layout/dialog_about.xml b/android/src/main/res/layout/dialog_about.xml
index c030704..d502ca2 100644
--- a/android/src/main/res/layout/dialog_about.xml
+++ b/android/src/main/res/layout/dialog_about.xml
@@ -18,7 +18,5 @@
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:padding="16dp"
- android:textSize="@dimen/text_size_medium"
- android:background="@android:color/white"
- android:textColor="@android:color/black" />
+ android:padding="24dp"
+ android:textSize="@dimen/text_size_medium" />
diff --git a/android/src/main/res/layout/explore_spinner_item_dropdown.xml b/android/src/main/res/layout/explore_spinner_item_dropdown.xml
index f11c1c8..d81bc6b 100644
--- a/android/src/main/res/layout/explore_spinner_item_dropdown.xml
+++ b/android/src/main/res/layout/explore_spinner_item_dropdown.xml
@@ -39,7 +39,7 @@
android:textColor="@color/body_text_3" />
<TextView
- android:id="@+id/normal_text"
+ android:id="@android:id/text1"
android:layout_height="@dimen/explore_dropdown_item_height"
android:layout_width="match_parent"
android:paddingLeft="16dp"
diff --git a/android/src/main/res/layout/fragment_experts_directory.xml b/android/src/main/res/layout/fragment_experts_directory.xml
index 5d1efc2..63846e9 100644
--- a/android/src/main/res/layout/fragment_experts_directory.xml
+++ b/android/src/main/res/layout/fragment_experts_directory.xml
@@ -20,7 +20,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:iosched="http://schemas.android.com/apk/res-auto"
- android:padding="@dimen/half_explore_grid_padding"
+ android:padding="@dimen/explore_grid_padding_half"
android:clipToPadding="false"
android:scrollbarStyle="outsideOverlay"
iosched:internalPadding="@dimen/explore_grid_padding" />
diff --git a/android/src/main/res/layout/fragment_hashtags.xml b/android/src/main/res/layout/fragment_hashtags.xml
index 939e4f9..e482470 100644
--- a/android/src/main/res/layout/fragment_hashtags.xml
+++ b/android/src/main/res/layout/fragment_hashtags.xml
@@ -23,9 +23,11 @@
android:id="@+id/social_collection_vew"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:padding="@dimen/social_grid_padding"
+ android:paddingTop="@dimen/explore_grid_padding"
+ android:paddingLeft="@dimen/explore_grid_padding_half"
+ android:paddingRight="@dimen/explore_grid_padding_half"
+ iosched:internalPadding="@dimen/explore_grid_padding"
android:layout_marginStart="@dimen/social_hz_margin"
android:layout_marginEnd="@dimen/social_hz_margin"
android:clipToPadding="false"
- iosched:internalPadding="@dimen/social_grid_padding"
tools:context="com.google.samples.apps.iosched.ui.HashtagsFragment" />
diff --git a/android/src/main/res/layout/fragment_map.xml b/android/src/main/res/layout/fragment_map.xml
index 6580e3f..b7deaea 100644
--- a/android/src/main/res/layout/fragment_map.xml
+++ b/android/src/main/res/layout/fragment_map.xml
@@ -17,6 +17,4 @@
android:id="@+id/map_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@color/theme_primary" >
-
-</FrameLayout>
+ android:background="@color/theme_primary" />
\ No newline at end of file
diff --git a/android/src/main/res/layout/fragment_nearby.xml b/android/src/main/res/layout/fragment_nearby.xml
index c40e7db..d5b257b 100644
--- a/android/src/main/res/layout/fragment_nearby.xml
+++ b/android/src/main/res/layout/fragment_nearby.xml
@@ -20,28 +20,28 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <LinearLayout android:id="@+id/headerbar"
+ <FrameLayout android:id="@+id/headerbar"
android:layout_width="match_parent"
- android:layout_height="?android:actionBarSize"
- android:orientation="horizontal"
+ android:layout_height="?actionBarSize"
+ android:elevation="@dimen/headerbar_elevation"
android:background="#e5e5e5">
<ImageButton android:id="@+id/close_button"
- android:layout_width="48dp"
+ android:layout_width="56dp"
android:layout_height="match_parent"
android:background="?selectableItemBackgroundBorderless"
android:src="@drawable/ic_pane_close"
android:contentDescription="@string/close_detail_pane" />
- <TextView android:layout_width="wrap_content"
+ <TextView android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_marginLeft="4dp"
+ android:layout_marginLeft="@dimen/keyline_2"
android:textSize="@dimen/text_size_large"
android:textColor="@color/body_text_1"
android:gravity="center_vertical"
android:text="@string/map_nearby_button" />
- </LinearLayout>
+ </FrameLayout>
<FrameLayout android:id="@+id/list_container"
android:layout_width="match_parent"
diff --git a/android/src/main/res/layout/fragment_partners.xml b/android/src/main/res/layout/fragment_partners.xml
index 0b70e32..1eef654 100644
--- a/android/src/main/res/layout/fragment_partners.xml
+++ b/android/src/main/res/layout/fragment_partners.xml
@@ -21,14 +21,15 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <LinearLayout android:id="@+id/headerbar"
+ <FrameLayout android:id="@+id/headerbar"
android:layout_width="match_parent"
- android:layout_height="?android:actionBarSize"
+ android:layout_height="?actionBarSize"
+ android:elevation="@dimen/headerbar_elevation"
android:orientation="horizontal"
android:background="#e5e5e5">
<ImageButton android:id="@+id/close_button"
- android:layout_width="48dp"
+ android:layout_width="56dp"
android:layout_height="match_parent"
android:background="?selectableItemBackgroundBorderless"
android:src="@drawable/ic_pane_close"
@@ -36,13 +37,13 @@
<TextView android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:layout_marginLeft="4dp"
+ android:layout_marginLeft="@dimen/keyline_2"
android:textSize="@dimen/text_size_large"
android:textColor="@color/body_text_1"
android:gravity="center_vertical"
android:text="@string/partners" />
- </LinearLayout>
+ </FrameLayout>
<FrameLayout android:layout_width="match_parent"
android:layout_height="0dp"
@@ -53,8 +54,8 @@
android:id="@+id/collection_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:paddingLeft="@dimen/half_explore_grid_padding"
- android:paddingRight="@dimen/half_explore_grid_padding"
+ android:paddingLeft="@dimen/explore_grid_padding_half"
+ android:paddingRight="@dimen/explore_grid_padding_half"
android:paddingTop="@dimen/explore_grid_padding"
android:clipToPadding="false"
android:scrollbarStyle="outsideOverlay"
diff --git a/android/src/main/res/layout/fragment_session_feedback.xml b/android/src/main/res/layout/fragment_session_feedback.xml
index 13642d7..8177731 100644
--- a/android/src/main/res/layout/fragment_session_feedback.xml
+++ b/android/src/main/res/layout/fragment_session_feedback.xml
@@ -19,7 +19,8 @@
android:id="@+id/scroll_view"
android:orientation="vertical"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:fillViewport="true">
<LinearLayout
android:orientation="vertical"
diff --git a/android/src/main/res/layout/fragment_sessions.xml b/android/src/main/res/layout/fragment_sessions.xml
index 84507fc..ffb781c 100644
--- a/android/src/main/res/layout/fragment_sessions.xml
+++ b/android/src/main/res/layout/fragment_sessions.xml
@@ -22,7 +22,7 @@
android:id="@+id/sessions_collection_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:padding="@dimen/half_explore_grid_padding"
+ android:padding="@dimen/explore_grid_padding_half"
android:clipToPadding="false"
android:scrollbarStyle="outsideOverlay"
iosched:internalPadding="@dimen/explore_grid_padding" />
@@ -30,7 +30,7 @@
<ProgressBar
android:id="@+id/loading"
android:visibility="gone"
- android:paddingTop="?android:actionBarSize"
+ android:paddingTop="?actionBarSize"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -39,7 +39,7 @@
<TextView
android:id="@+id/empty_text"
android:visibility="gone"
- android:paddingTop="?android:actionBarSize"
+ android:paddingTop="?actionBarSize"
android:layout_gravity="center"
android:gravity="center"
android:layout_width="match_parent"
diff --git a/android/src/main/res/layout/fragment_video_library.xml b/android/src/main/res/layout/fragment_video_library.xml
index a596f1c..95e8a9f 100644
--- a/android/src/main/res/layout/fragment_video_library.xml
+++ b/android/src/main/res/layout/fragment_video_library.xml
@@ -25,9 +25,9 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
- android:paddingLeft="@dimen/explore_grid_padding"
- android:paddingRight="@dimen/explore_grid_padding"
- android:paddingBottom="@dimen/explore_grid_padding"
+ android:paddingTop="@dimen/explore_grid_padding"
+ android:paddingLeft="@dimen/explore_grid_padding_half"
+ android:paddingRight="@dimen/explore_grid_padding_half"
iosched:internalPadding="@dimen/explore_grid_padding" />
<!-- Empty view -->
@@ -40,7 +40,7 @@
android:textSize="@dimen/text_size_medium"
android:textColor="@color/body_text_2"
android:text="@string/no_matching_videos"
- android:paddingTop="?android:actionBarSize" />
+ android:paddingTop="?actionBarSize" />
</FrameLayout>
diff --git a/android/src/main/res/layout/header_experts_directory.xml b/android/src/main/res/layout/header_experts_directory.xml
index f655a68..56bbea9 100644
--- a/android/src/main/res/layout/header_experts_directory.xml
+++ b/android/src/main/res/layout/header_experts_directory.xml
@@ -33,5 +33,6 @@
iosched:messageTitle="@string/experts_directory_header_title"
iosched:messageText="@string/experts_directory_header_body"
iosched:button1text="@string/experts_directory_header_dismiss"
- iosched:button1emphasis="true" />
+ iosched:button1emphasis="true"
+ iosched:cardBackgroundColor="#fff" />
</FrameLayout>
diff --git a/android/src/main/res/layout/include_link_row.xml b/android/src/main/res/layout/include_link_row.xml
index 19c837e..4c4255d 100644
--- a/android/src/main/res/layout/include_link_row.xml
+++ b/android/src/main/res/layout/include_link_row.xml
@@ -17,7 +17,4 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:showDividers="middle"
- android:divider="?android:dividerVertical"
- android:dividerPadding="8dp" />
+ android:layout_height="wrap_content" />
diff --git a/android/src/main/res/layout/list_item_session.xml b/android/src/main/res/layout/list_item_session.xml
index ad10d4f..19b5d30 100644
--- a/android/src/main/res/layout/list_item_session.xml
+++ b/android/src/main/res/layout/list_item_session.xml
@@ -17,71 +17,53 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="300dp"
- android:id="@+id/session_target"
- android:foreground="?photoItemForeground">
+ android:foreground="?photoItemForeground"
+ android:id="@+id/session_target">
- <!-- Session info -->
- <LinearLayout
- android:orientation="vertical"
+ <!-- Session image -->
+ <ImageView android:id="@+id/session_photo_colored"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent" />
- <!-- Session image -->
- <FrameLayout android:layout_width="match_parent"
- android:layout_height="0dp"
- android:layout_weight="1">
+ <!-- Session category/group if non-default (e.g. "Workshop") -->
+ <TextView android:id="@+id/session_category"
+ style="@style/ExploreItem.Category"
+ android:padding="16dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
- <ImageView android:id="@+id/session_photo"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:scaleType="centerCrop" />
+ <!-- Info box -->
+ <LinearLayout
+ android:id="@+id/info_box"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
+ android:padding="16dp"
+ android:orientation="vertical">
- <!-- Live Now indicator -->
- <include layout="@layout/include_live_now_badge" />
-
- <!-- Session category/group if non-default (e.g. "Workshop") -->
- <TextView android:id="@+id/session_category"
- style="@style/ExploreItem.Category"
- android:padding="16dp"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
-
- </FrameLayout>
-
- <!-- Info box -->
- <LinearLayout
- android:id="@+id/info_box"
+ <!-- Session title -->
+ <TextView android:id="@+id/session_title"
+ style="@style/ExploreItem.Title"
android:layout_width="match_parent"
- android:layout_height="120dp"
- android:gravity="center"
- android:padding="16dp"
- android:orientation="vertical"
- android:background="@color/theme_primary">
+ android:layout_height="wrap_content"
+ android:text="@string/placeholder_session_title" />
- <!-- Session title -->
- <TextView android:id="@+id/session_title"
- style="@style/ExploreItem.Title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/placeholder_session_title" />
+ <!-- Subtitle -->
+ <TextView android:id="@+id/session_subtitle_short"
+ style="@style/ExploreItem.Subtitle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingBottom="8dp"
+ android:text="@string/placeholder_session_subtitle" />
- <!-- Subtitle -->
- <TextView android:id="@+id/session_subtitle"
- style="@style/ExploreItem.Subtitle"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingBottom="8dp"
- android:text="@string/placeholder_session_subtitle" />
+ <!-- Abstract snippet -->
+ <TextView android:id="@+id/session_snippet"
+ style="@style/ExploreItem.Snippet"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:maxLines="5"
+ android:text="@string/placeholder_lorem_ipsum" />
- <!-- Abstract snippet -->
- <TextView android:id="@+id/session_snippet"
- style="@style/ExploreItem.Snippet"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:maxLines="3"
- android:text="@string/placeholder_lorem_ipsum" />
-
- </LinearLayout>
</LinearLayout>
<!-- "In schedule" indicator -->
@@ -92,4 +74,6 @@
android:src="@drawable/indicator_in_schedule"
android:contentDescription="@null" />
+ <!-- Live Now indicator -->
+ <include layout="@layout/include_live_now_badge" />
</FrameLayout>
diff --git a/android/src/main/res/layout/list_item_session_hero_narrow.xml b/android/src/main/res/layout/list_item_session_hero_narrow.xml
index c5b9cff..2912c96 100644
--- a/android/src/main/res/layout/list_item_session_hero_narrow.xml
+++ b/android/src/main/res/layout/list_item_session_hero_narrow.xml
@@ -23,6 +23,7 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:iosched="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
@@ -99,6 +100,7 @@
android:layout_marginBottom="8dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
+ iosched:cardBackgroundColor="#fff"
android:visibility="visible"
android:layout_height="wrap_content"
/>
diff --git a/android/src/main/res/layout/list_item_session_hero_wide.xml b/android/src/main/res/layout/list_item_session_hero_wide.xml
index cbd2a4d..be1d337 100644
--- a/android/src/main/res/layout/list_item_session_hero_wide.xml
+++ b/android/src/main/res/layout/list_item_session_hero_wide.xml
@@ -21,6 +21,7 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:iosched="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
@@ -110,6 +111,7 @@
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
+ iosched:cardBackgroundColor="#fff"
/>
</FrameLayout>
</FrameLayout>
diff --git a/android/src/main/res/layout/message_card.xml b/android/src/main/res/layout/message_card.xml
index 9a494c1..c7f70a1 100644
--- a/android/src/main/res/layout/message_card.xml
+++ b/android/src/main/res/layout/message_card.xml
@@ -19,8 +19,7 @@
android:id="@+id/card_root"
android:orientation="vertical"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/card_bg">
+ android:layout_height="match_parent">
<TextView
android:id="@+id/title"
@@ -91,4 +90,4 @@
</LinearLayout>
-</LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/android/src/main/res/layout/my_schedule_item.xml b/android/src/main/res/layout/my_schedule_item.xml
index b09d0d1..c39991d 100644
--- a/android/src/main/res/layout/my_schedule_item.xml
+++ b/android/src/main/res/layout/my_schedule_item.xml
@@ -115,6 +115,5 @@
android:scaleType="center"
android:src="@drawable/ic_schedule_feedback"
android:background="?photoItemForeground" />
-
- </FrameLayout>
+ </FrameLayout>
</LinearLayout>
diff --git a/android/src/main/res/layout/navdrawer.xml b/android/src/main/res/layout/navdrawer.xml
index 0d7027b..f05fe26 100644
--- a/android/src/main/res/layout/navdrawer.xml
+++ b/android/src/main/res/layout/navdrawer.xml
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2014 Google Inc. All rights reserved.
@@ -15,19 +14,114 @@
limitations under the License.
-->
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+<com.google.samples.apps.iosched.ui.widget.ScrimInsetsScrollView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="@dimen/navdrawer_width"
android:layout_height="match_parent"
- android:id="@+id/navdrawer"
android:layout_gravity="start"
- android:background="@color/navdrawer_background">
+ android:id="@+id/navdrawer"
+ android:background="@color/navdrawer_background"
+ android:fitsSystemWindows="true"
+ app:insetForeground="#4000">
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
- <include layout="@layout/navdrawer_content" />
+ <FrameLayout
+ android:id="@+id/chosen_account_view"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/navdrawer_chosen_account_height"
+ android:foreground="?photoItemForeground">
+ <ImageView android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:scaleType="centerCrop"
+ android:src="@drawable/default_cover"
+ android:tint="@color/session_photo_scrim"
+ android:id="@+id/profile_cover_image" />
+
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="@dimen/keyline_1"
+ android:paddingRight="@dimen/keyline_1"
+ android:paddingTop="@dimen/keyline_1"
+ android:id="@+id/chosen_account_content_view">
+
+ <com.google.samples.apps.iosched.ui.widget.BezelImageView
+ android:id="@+id/profile_image"
+ android:layout_width="@dimen/navdrawer_profile_image_size"
+ android:layout_height="@dimen/navdrawer_profile_image_size"
+ android:src="@drawable/person_image_empty"
+ android:scaleType="centerCrop"
+ app:maskDrawable="@drawable/circle_mask" />
+
+ <ImageView
+ android:id="@+id/expand_account_box_indicator"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:visibility="gone"
+ android:layout_marginLeft="16dp"
+ android:paddingBottom="16dp"
+ android:layout_alignParentEnd="true"
+ android:layout_alignParentBottom="true"
+ android:scaleType="center"
+ android:src="@drawable/ic_drawer_accounts_expand" />
+
+ <TextView
+ android:id="@+id/profile_email_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignLeft="@id/profile_image"
+ android:layout_toLeftOf="@id/expand_account_box_indicator"
+ android:layout_alignParentBottom="true"
+ android:paddingBottom="16dp"
+ android:textSize="@dimen/text_size_medium"
+ android:textColor="@color/body_text_2_inverse"
+ android:maxLines="1"
+ android:singleLine="true"
+ android:ellipsize="end" />
+
+ <TextView
+ android:id="@+id/profile_name_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_above="@id/profile_email_text"
+ android:layout_alignLeft="@id/profile_image"
+ android:layout_toLeftOf="@id/expand_account_box_indicator"
+ android:textSize="@dimen/text_size_large"
+ android:textColor="@color/body_text_1_inverse"
+ android:maxLines="1"
+ android:singleLine="true"
+ android:ellipsize="end" />
+
+ </RelativeLayout>
+
+ </FrameLayout>
+
+ <FrameLayout android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <!-- Account items -->
+ <LinearLayout
+ android:id="@+id/account_list"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dp"
+ android:orientation="vertical"
+ android:visibility="invisible" />
+
+ <!-- Drawer items -->
+ <LinearLayout
+ android:id="@+id/navdrawer_items_list"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="8dp"
+ android:layout_marginBottom="8dp"
+ android:orientation="vertical" />
+ </FrameLayout>
</LinearLayout>
-</ScrollView>
+</com.google.samples.apps.iosched.ui.widget.ScrimInsetsScrollView>
\ No newline at end of file
diff --git a/android/src/main/res/layout/navdrawer_content.xml b/android/src/main/res/layout/navdrawer_content.xml
deleted file mode 100644
index ddba93d..0000000
--- a/android/src/main/res/layout/navdrawer_content.xml
+++ /dev/null
@@ -1,113 +0,0 @@
-<!--
- Copyright 2014 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.
- -->
-
-<merge xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:iosched="http://schemas.android.com/apk/res-auto">
-
- <FrameLayout
- android:id="@+id/chosen_account_view"
- android:layout_width="match_parent"
- android:layout_height="@dimen/navdrawer_chosen_account_height"
- android:foreground="?photoItemForeground">
-
- <ImageView android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:scaleType="centerCrop"
- android:src="@drawable/default_cover"
- android:tint="@color/session_photo_scrim"
- android:id="@+id/profile_cover_image" />
-
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingLeft="@dimen/keyline_1"
- android:paddingRight="@dimen/keyline_1"
- android:paddingTop="@dimen/keyline_1">
-
- <com.google.samples.apps.iosched.ui.widget.BezelImageView
- android:id="@+id/profile_image"
- android:layout_width="@dimen/navdrawer_profile_image_size"
- android:layout_height="@dimen/navdrawer_profile_image_size"
- android:src="@drawable/person_image_empty"
- android:scaleType="centerCrop"
- iosched:maskDrawable="@drawable/circle_mask" />
-
- <ImageView
- android:id="@+id/expand_account_box_indicator"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:visibility="gone"
- android:layout_marginLeft="16dp"
- android:paddingBottom="16dp"
- android:layout_alignParentEnd="true"
- android:layout_alignParentBottom="true"
- android:scaleType="center"
- android:src="@drawable/ic_drawer_accounts_expand" />
-
- <TextView
- android:id="@+id/profile_email_text"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignLeft="@id/profile_image"
- android:layout_toLeftOf="@id/expand_account_box_indicator"
- android:layout_alignParentBottom="true"
- android:paddingBottom="16dp"
- android:textSize="@dimen/text_size_medium"
- android:textColor="@color/body_text_1_inverse"
- android:maxLines="1"
- android:singleLine="true"
- android:ellipsize="end" />
-
- <TextView
- android:id="@+id/profile_name_text"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_above="@id/profile_email_text"
- android:layout_alignLeft="@id/profile_image"
- android:layout_toLeftOf="@id/expand_account_box_indicator"
- android:textSize="@dimen/text_size_large"
- android:textStyle="bold"
- android:textColor="@color/body_text_1_inverse"
- android:maxLines="1"
- android:singleLine="true"
- android:ellipsize="end" />
-
- </RelativeLayout>
-
- </FrameLayout>
-
- <FrameLayout android:layout_width="match_parent"
- android:layout_height="wrap_content">
-
- <!-- Account items -->
- <LinearLayout
- android:id="@+id/account_list"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
- android:orientation="vertical"
- android:visibility="invisible" />
-
- <!-- Drawer items -->
- <LinearLayout
- android:id="@+id/navdrawer_items_list"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
- android:layout_marginBottom="8dp"
- android:orientation="vertical" />
- </FrameLayout>
-</merge>
diff --git a/android/src/main/res/layout/navdrawer_for_ab_overlay.xml b/android/src/main/res/layout/navdrawer_for_ab_overlay.xml
deleted file mode 100644
index 1b7a090..0000000
--- a/android/src/main/res/layout/navdrawer_for_ab_overlay.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2014 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.
--->
-
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="@dimen/navdrawer_width"
- android:layout_height="match_parent"
- android:id="@+id/navdrawer"
- android:layout_gravity="start"
- android:background="@color/navdrawer_background"
- android:paddingTop="?actionBarOverlayTopOffset"
- android:clipToPadding="false">
-
- <LinearLayout android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
-
- <include layout="@layout/navdrawer_content" />
-
- </LinearLayout>
-
-</ScrollView>
diff --git a/android/src/main/res/layout/navdrawer_item.xml b/android/src/main/res/layout/navdrawer_item.xml
index a734953..bda2962 100644
--- a/android/src/main/res/layout/navdrawer_item.xml
+++ b/android/src/main/res/layout/navdrawer_item.xml
@@ -33,11 +33,11 @@
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:gravity="start|center_vertical"
android:layout_gravity="start|center_vertical"
+ android:gravity="start|center_vertical"
+ android:fontFamily="@string/font_fontFamily_medium"
+ android:textStyle="@integer/font_textStyle_medium"
android:textSize="14sp"
- android:textStyle="@integer/font_textStyle_drawer_item"
- android:fontFamily="@string/font_fontFamily_drawer_item"
android:text="@string/placeholder_lorem_ipsum" />
</LinearLayout>
diff --git a/android/src/main/res/layout/nearby_button.xml b/android/src/main/res/layout/nearby_button.xml
index 20baf93..4965c5b 100644
--- a/android/src/main/res/layout/nearby_button.xml
+++ b/android/src/main/res/layout/nearby_button.xml
@@ -32,6 +32,7 @@
android:textStyle="@integer/font_textStyle_medium"
android:fontFamily="@string/font_fontFamily_medium"
android:textAllCaps="true"
+ android:stateListAnimator="@null"
android:background="@drawable/nearby_button_background"
android:textColor="@color/body_text_1_inverse"/>
diff --git a/android/src/main/res/layout/toolbar_actionbar.xml b/android/src/main/res/layout/toolbar_actionbar.xml
index 57d3173..7717e34 100644
--- a/android/src/main/res/layout/toolbar_actionbar.xml
+++ b/android/src/main/res/layout/toolbar_actionbar.xml
@@ -14,6 +14,13 @@
limitations under the License.
-->
-<merge xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="0dp"
- android:layout_height="0dp" />
+<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:iosched="http://schemas.android.com/apk/res-auto"
+ iosched:theme="@style/ActionBarThemeOverlay"
+ iosched:popupTheme="@style/ActionBarPopupThemeOverlay"
+ android:id="@+id/toolbar_actionbar"
+ android:background="@null"
+ iosched:titleTextAppearance="@style/ActionBar.TitleText"
+ iosched:contentInsetStart="?actionBarInsetStart"
+ android:layout_width="match_parent"
+ android:layout_height="?actionBarSize" />
diff --git a/android/src/lpreview/res/layout-v21/toolbar_actionbar_with_translucent_background.xml b/android/src/main/res/layout/toolbar_actionbar_translucent.xml
similarity index 63%
rename from android/src/lpreview/res/layout-v21/toolbar_actionbar_with_translucent_background.xml
rename to android/src/main/res/layout/toolbar_actionbar_translucent.xml
index aca3d8e..5861831 100644
--- a/android/src/lpreview/res/layout-v21/toolbar_actionbar_with_translucent_background.xml
+++ b/android/src/main/res/layout/toolbar_actionbar_translucent.xml
@@ -14,9 +14,13 @@
limitations under the License.
-->
-<Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
- android:theme="@style/ActionBarThemeOverlay"
- android:background="@color/translucent_actionbar_background"
+<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:iosched="http://schemas.android.com/apk/res-auto"
+ iosched:theme="@style/ActionBarThemeOverlay"
+ iosched:popupTheme="@style/ActionBarPopupThemeOverlay"
android:id="@+id/toolbar_actionbar"
+ android:background="@color/translucent_actionbar_background"
+ iosched:titleTextAppearance="@style/ActionBar.TitleText"
+ iosched:contentInsetStart="?actionBarInsetStart"
android:layout_width="match_parent"
- android:layout_height="?android:actionBarSize" />
+ android:layout_height="?actionBarSize" />
diff --git a/android/src/lpreview/res/layout-v21/toolbar_actionbar_with_headerbar.xml b/android/src/main/res/layout/toolbar_actionbar_with_headerbar.xml
similarity index 62%
rename from android/src/lpreview/res/layout-v21/toolbar_actionbar_with_headerbar.xml
rename to android/src/main/res/layout/toolbar_actionbar_with_headerbar.xml
index 47c3296..578aea0 100644
--- a/android/src/lpreview/res/layout-v21/toolbar_actionbar_with_headerbar.xml
+++ b/android/src/main/res/layout/toolbar_actionbar_with_headerbar.xml
@@ -14,9 +14,13 @@
limitations under the License.
-->
-<Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
+<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:iosched="http://schemas.android.com/apk/res-auto"
style="@style/HeaderBar"
- android:theme="@style/ActionBarThemeOverlay"
+ iosched:theme="@style/ActionBarThemeOverlay"
+ iosched:popupTheme="@style/ActionBarPopupThemeOverlay"
android:id="@+id/toolbar_actionbar"
+ iosched:titleTextAppearance="@style/ActionBar.TitleText"
+ iosched:contentInsetStart="?actionBarInsetStart"
android:layout_width="match_parent"
- android:layout_height="?android:actionBarSize" />
+ android:layout_height="?actionBarSize" />
diff --git a/android/src/main/res/layout/video_library_spinner_item_dropdown.xml b/android/src/main/res/layout/video_library_spinner_item_dropdown.xml
new file mode 100644
index 0000000..d1b38d0
--- /dev/null
+++ b/android/src/main/res/layout/video_library_spinner_item_dropdown.xml
@@ -0,0 +1,32 @@
+<!--
+ Copyright 2014 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.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <TextView
+ android:id="@android:id/text1"
+ android:layout_height="@dimen/explore_dropdown_item_height"
+ android:layout_width="match_parent"
+ android:paddingLeft="16dp"
+ android:paddingRight="16dp"
+ android:drawablePadding="8dp"
+ android:gravity="center_vertical|start"
+ android:textSize="16sp"
+ android:textColor="@color/list_dropdown_foreground_color" />
+</LinearLayout>
diff --git a/android/src/main/res/menu/browse_sessions.xml b/android/src/main/res/menu/browse_sessions.xml
index 5185805..82b0f70 100644
--- a/android/src/main/res/menu/browse_sessions.xml
+++ b/android/src/main/res/menu/browse_sessions.xml
@@ -13,50 +13,51 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:iosched="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/menu_search"
android:icon="@drawable/ic_action_search"
- android:title="@string/description_search"
android:orderInCategory="1"
- android:showAsAction="always" />
+ android:title="@string/description_search"
+ iosched:showAsAction="always" />
<item android:id="@+id/menu_refresh"
- android:title="@string/description_refresh"
android:orderInCategory="1"
- android:showAsAction="never" />
+ android:title="@string/description_refresh"
+ iosched:showAsAction="never" />
<item android:id="@+id/menu_wifi"
- android:title="@string/description_configure_wifi"
android:orderInCategory="98"
- android:showAsAction="never" />
+ android:title="@string/description_configure_wifi"
+ iosched:showAsAction="never" />
<item android:id="@+id/menu_i_o_hunt"
- android:title="@string/description_i_o_hunt"
android:orderInCategory="99"
- android:showAsAction="never" />
+ android:title="@string/description_i_o_hunt"
+ iosched:showAsAction="never" />
<item android:id="@+id/menu_io_extended"
- android:visible="false"
- android:title="@string/description_i_o_extended"
android:orderInCategory="99"
- android:showAsAction="never" />
+ android:title="@string/description_i_o_extended"
+ android:visible="false"
+ iosched:showAsAction="never" />
<item android:id="@+id/menu_map"
- android:visible="false"
- android:title="@string/description_map"
android:orderInCategory="100"
- android:showAsAction="never" />
+ android:title="@string/description_map"
+ android:visible="false"
+ iosched:showAsAction="never" />
<item android:id="@+id/menu_debug"
- android:visible="false"
- android:title="@string/description_debug"
android:orderInCategory="101"
- android:showAsAction="never" />
+ android:title="@string/description_debug"
+ android:visible="false"
+ iosched:showAsAction="never" />
<item android:id="@+id/menu_about"
- android:title="@string/description_about"
android:orderInCategory="99"
- android:showAsAction="never" />
+ android:title="@string/description_about"
+ iosched:showAsAction="never" />
</menu>
diff --git a/android/src/main/res/menu/my_schedule.xml b/android/src/main/res/menu/my_schedule.xml
index 23707a0..0f9463a 100644
--- a/android/src/main/res/menu/my_schedule.xml
+++ b/android/src/main/res/menu/my_schedule.xml
@@ -13,49 +13,50 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:iosched="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/menu_search"
android:icon="@drawable/ic_action_search"
android:title="@string/description_search"
android:orderInCategory="1"
- android:showAsAction="always" />
+ iosched:showAsAction="always" />
<item android:id="@+id/menu_refresh"
android:title="@string/description_refresh"
android:orderInCategory="1"
- android:showAsAction="never" />
+ iosched:showAsAction="never" />
<item android:id="@+id/menu_wifi"
android:title="@string/description_configure_wifi"
android:orderInCategory="98"
- android:showAsAction="never" />
+ iosched:showAsAction="never" />
<item android:id="@+id/menu_i_o_hunt"
android:title="@string/description_i_o_hunt"
android:orderInCategory="99"
- android:showAsAction="never" />
+ iosched:showAsAction="never" />
<item android:id="@+id/menu_io_extended"
android:visible="false"
android:title="@string/description_i_o_extended"
android:orderInCategory="99"
- android:showAsAction="never" />
+ iosched:showAsAction="never" />
<item android:id="@+id/menu_map"
android:visible="false"
android:title="@string/description_map"
android:orderInCategory="100"
- android:showAsAction="never" />
+ iosched:showAsAction="never" />
<item android:id="@+id/menu_debug"
android:visible="false"
android:title="@string/description_debug"
android:orderInCategory="101"
- android:showAsAction="never" />
+ iosched:showAsAction="never" />
<item android:id="@+id/menu_about"
android:title="@string/description_about"
android:orderInCategory="99"
- android:showAsAction="never" />
+ iosched:showAsAction="never" />
</menu>
diff --git a/android/src/main/res/menu/nearby.xml b/android/src/main/res/menu/nearby.xml
index 256d9d7..247e692 100644
--- a/android/src/main/res/menu/nearby.xml
+++ b/android/src/main/res/menu/nearby.xml
@@ -1,5 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
-
<!--
Copyright 2014 Google Inc. All rights reserved.
@@ -16,10 +14,11 @@
limitations under the License.
-->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:iosched="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/menu_nearby"
android:title="@string/map_nearby_button"
android:orderInCategory="1"
- android:showAsAction="ifRoom"
- android:actionLayout="@layout/nearby_button" />
+ iosched:showAsAction="ifRoom"
+ iosched:actionLayout="@layout/nearby_button" />
</menu>
diff --git a/android/src/main/res/menu/search.xml b/android/src/main/res/menu/search.xml
index e473f9a..6b41dbe 100644
--- a/android/src/main/res/menu/search.xml
+++ b/android/src/main/res/menu/search.xml
@@ -13,11 +13,12 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:iosched="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/menu_search"
android:icon="@drawable/ic_action_search"
android:title="@string/description_search"
android:orderInCategory="0"
- android:actionViewClass="android.widget.SearchView"
- android:showAsAction="always" />
+ iosched:actionViewClass="android.support.v7.widget.SearchView"
+ iosched:showAsAction="always" />
</menu>
diff --git a/android/src/main/res/menu/session_detail.xml b/android/src/main/res/menu/session_detail.xml
index 224f894..8cef605 100644
--- a/android/src/main/res/menu/session_detail.xml
+++ b/android/src/main/res/menu/session_detail.xml
@@ -13,21 +13,22 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:iosched="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/menu_map_room"
android:icon="@drawable/ic_action_map"
android:title="@string/description_map"
android:orderInCategory="1"
- android:showAsAction="ifRoom" />
+ iosched:showAsAction="ifRoom" />
<item android:id="@+id/menu_share"
android:icon="@drawable/ic_action_share"
android:title="@string/description_share"
android:orderInCategory="1"
- android:showAsAction="ifRoom" />
+ iosched:showAsAction="ifRoom" />
<item android:id="@+id/menu_social_stream"
android:icon="@drawable/ic_action_social_stream"
android:title="@string/description_social_stream"
android:orderInCategory="1"
android:visible="false"
- android:showAsAction="ifRoom" />
+ iosched:showAsAction="ifRoom" />
</menu>
diff --git a/android/src/main/res/menu/session_livestream.xml b/android/src/main/res/menu/session_livestream.xml
index 4ea44ed..9bf002e 100644
--- a/android/src/main/res/menu/session_livestream.xml
+++ b/android/src/main/res/menu/session_livestream.xml
@@ -13,26 +13,27 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:iosched="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/menu_presentation"
android:icon="@drawable/ic_media_route_off_holo_light"
android:title="@string/description_presentation"
android:orderInCategory="1"
android:visible="false"
- android:showAsAction="ifRoom" />
+ iosched:showAsAction="ifRoom" />
<item android:id="@+id/menu_captions"
android:icon="@drawable/ic_action_captions"
android:title="@string/description_captions"
android:orderInCategory="1"
android:visible="false"
- android:showAsAction="ifRoom" />
+ iosched:showAsAction="ifRoom" />
<item android:id="@+id/menu_share"
android:icon="@drawable/ic_action_share"
android:title="@string/description_share"
android:orderInCategory="1"
- android:showAsAction="ifRoom" />
+ iosched:showAsAction="ifRoom" />
</menu>
diff --git a/android/src/main/res/menu/sessions_context.xml b/android/src/main/res/menu/sessions_context.xml
index 53ea059..88da537 100644
--- a/android/src/main/res/menu/sessions_context.xml
+++ b/android/src/main/res/menu/sessions_context.xml
@@ -13,25 +13,26 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:iosched="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/menu_star"
android:icon="@drawable/ic_action_add_schedule"
android:title="@string/description_add_schedule"
android:orderInCategory="1"
- android:showAsAction="ifRoom" />
+ iosched:showAsAction="ifRoom" />
<item android:id="@+id/menu_map_room"
android:icon="@drawable/ic_action_map"
android:title="@string/description_map"
android:orderInCategory="2"
- android:showAsAction="ifRoom" />
+ iosched:showAsAction="ifRoom" />
<item android:id="@+id/menu_share"
android:icon="@drawable/ic_action_share"
android:title="@string/description_share"
android:orderInCategory="3"
- android:showAsAction="ifRoom" />
+ iosched:showAsAction="ifRoom" />
<item android:id="@+id/menu_social_stream"
android:icon="@drawable/ic_action_social_stream"
android:title="@string/description_social_stream"
android:orderInCategory="3"
- android:showAsAction="ifRoom" />
+ iosched:showAsAction="ifRoom" />
</menu>
diff --git a/android/src/main/res/mipmap-hdpi/ic_launcher.png b/android/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..494089c
--- /dev/null
+++ b/android/src/main/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/android/src/main/res/mipmap-mdpi/ic_launcher.png b/android/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..09a8ae6
--- /dev/null
+++ b/android/src/main/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/android/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..8f2bd09
--- /dev/null
+++ b/android/src/main/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/android/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..ec08ac7
--- /dev/null
+++ b/android/src/main/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/android/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..6d13883
--- /dev/null
+++ b/android/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/android/src/lpreview/res/transition-v21/shared_element.xml b/android/src/main/res/transition-v21/shared_element.xml
similarity index 100%
rename from android/src/lpreview/res/transition-v21/shared_element.xml
rename to android/src/main/res/transition-v21/shared_element.xml
diff --git a/android/src/lpreview/res/transition-v21/window_enter_exit.xml b/android/src/main/res/transition-v21/window_enter_exit.xml
similarity index 100%
rename from android/src/lpreview/res/transition-v21/window_enter_exit.xml
rename to android/src/main/res/transition-v21/window_enter_exit.xml
diff --git a/android/src/main/res/values-sw360dp/dimens.xml b/android/src/main/res/values-sw360dp/dimens.xml
index 9cb8340..880cdef 100644
--- a/android/src/main/res/values-sw360dp/dimens.xml
+++ b/android/src/main/res/values-sw360dp/dimens.xml
@@ -18,4 +18,8 @@
<!-- Live Stream -->
<dimen name="livestream_spinner_width">240dp</dimen>
+ <dimen name="navdrawer_chosen_account_height">164dp</dimen>
+ <dimen name="navdrawer_width">304dp</dimen>
+ <dimen name="navdrawer_profile_image_size">64dp</dimen>
+
</resources>
diff --git a/android/src/lpreview/res/values-v21/fonts.xml b/android/src/main/res/values-sw600dp-v21/styles.xml
similarity index 67%
copy from android/src/lpreview/res/values-v21/fonts.xml
copy to android/src/main/res/values-sw600dp-v21/styles.xml
index 2680a08..934a527 100644
--- a/android/src/lpreview/res/values-v21/fonts.xml
+++ b/android/src/main/res/values-sw600dp-v21/styles.xml
@@ -15,9 +15,12 @@
-->
<resources>
- <integer name="font_textStyle_medium">0</integer> <!-- normal -->
- <string name="font_fontFamily_medium">sans-serif-medium</string>
- <integer name="font_textStyle_drawer_item">0</integer> <!-- normal -->
- <string name="font_fontFamily_drawer_item">sans-serif-medium</string>
+ <style name="Theme.IOSched.SessionDetails" parent="Theme.IOSched.SessionDetails.Base">
+ <item name="android:windowBackground">@android:color/white</item>
+ <item name="android:windowFullscreen">true</item>
+
+ <item name="android:windowElevation">16dp</item>
+ </style>
+
</resources>
diff --git a/android/src/main/res/values-sw600dp/dimens.xml b/android/src/main/res/values-sw600dp/dimens.xml
index f2b9883..25434d0 100644
--- a/android/src/main/res/values-sw600dp/dimens.xml
+++ b/android/src/main/res/values-sw600dp/dimens.xml
@@ -21,8 +21,6 @@
<dimen name="add_to_schedule_button_height">72dp</dimen> <!-- including padding -->
<dimen name="add_to_schedule_button_height_no_padding">56dp</dimen>
- <dimen name="navdrawer_chosen_account_height">140dp</dimen>
-
<dimen name="filter_spinner_width">200dp</dimen>
<integer name="filter_spinner_weight">0</integer>
diff --git a/android/src/main/res/values-sw600dp/styles.xml b/android/src/main/res/values-sw600dp/styles.xml
index 4966da1..d5a4d6d 100644
--- a/android/src/main/res/values-sw600dp/styles.xml
+++ b/android/src/main/res/values-sw600dp/styles.xml
@@ -28,4 +28,6 @@
<item name="android:colorBackgroundCacheHint">@null</item>
</style>
+ <style name="Theme.IOSched.SessionDetails" parent="Theme.IOSched.SessionDetails.Base" />
+
</resources>
diff --git a/android/src/main/res/values-v17/styles.xml b/android/src/main/res/values-v17/styles.xml
index fe3e0e3..d6e7971 100644
--- a/android/src/main/res/values-v17/styles.xml
+++ b/android/src/main/res/values-v17/styles.xml
@@ -18,7 +18,7 @@
<!-- Enable RTL support on newer devices -->
<!-- Prevents crash on certain devices to namespace conflict -->
- <style name="FrameworkRoot.Theme" parent="android:Theme.Holo.Light.DarkActionBar">
+ <style name="FrameworkRoot.Theme" parent="Theme.AppCompat.Light">
<item name="android:paddingStart">?android:attr/paddingLeft</item>
<item name="android:paddingEnd">?android:attr/paddingRight</item>
<item name="android:layout_marginStart">?android:attr/layout_marginLeft</item>
diff --git a/android/src/lpreview/res/values-v21/fonts.xml b/android/src/main/res/values-v21/fonts.xml
similarity index 83%
rename from android/src/lpreview/res/values-v21/fonts.xml
rename to android/src/main/res/values-v21/fonts.xml
index 2680a08..9b6c194 100644
--- a/android/src/lpreview/res/values-v21/fonts.xml
+++ b/android/src/main/res/values-v21/fonts.xml
@@ -17,7 +17,4 @@
<resources>
<integer name="font_textStyle_medium">0</integer> <!-- normal -->
<string name="font_fontFamily_medium">sans-serif-medium</string>
-
- <integer name="font_textStyle_drawer_item">0</integer> <!-- normal -->
- <string name="font_fontFamily_drawer_item">sans-serif-medium</string>
</resources>
diff --git a/android/src/lpreview/res/values-v21/refs.xml b/android/src/main/res/values-v21/refs.xml
similarity index 100%
rename from android/src/lpreview/res/values-v21/refs.xml
rename to android/src/main/res/values-v21/refs.xml
diff --git a/android/src/main/res/values-v21/styles.xml b/android/src/main/res/values-v21/styles.xml
new file mode 100644
index 0000000..361f4dd
--- /dev/null
+++ b/android/src/main/res/values-v21/styles.xml
@@ -0,0 +1,49 @@
+<!--
+ Copyright 2014 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.
+ -->
+
+<resources>
+
+ <style name="Theme" parent="FrameworkRoot.Theme" /> <!-- doesn't contain the pre-L code from the values/styles.xml -->
+
+ <style name="Theme.IOSched" parent="Theme.IOSched.Base">
+ <item name="popupItemBackground">@drawable/popup_item_background</item>
+ <item name="photoItemForeground">@drawable/photo_item_foreground</item>
+ <item name="photoItemForegroundBorderless">@drawable/photo_item_foreground_borderless</item>
+
+ <item name="android:navigationBarColor">#000</item>
+ <item name="android:statusBarColor">?colorPrimaryDark</item>
+
+ <item name="android:alertDialogTheme">@style/Theme.IOSched.AlertDialog</item>
+ </style>
+
+ <style name="Theme.IOSched.WithNavDrawer" parent="Theme.IOSched">
+ <item name="android:statusBarColor">@android:color/transparent</item>
+ </style>
+
+ <style name="Theme.IOSched.AlertDialog" parent="android:Theme.Material.Light.Dialog.Alert">
+ <item name="android:colorPrimary">@color/theme_primary</item>
+ <item name="android:colorPrimaryDark">@color/theme_primary_dark</item>
+ <item name="android:colorAccent">@color/theme_accent_2</item>
+ </style>
+
+ <style name="Widget.IOSched.HeaderBar.Spinner" parent="Widget.IOSched.HeaderBar.Spinner.Base">
+ <item name="android:theme">@style/ActionBarThemeOverlay</item>
+ </style>
+
+ <style name="TabIndicator">
+ <item name="android:theme">@style/ActionBarThemeOverlay</item>
+ </style>
+</resources>
diff --git a/android/src/main/res/values/attrs.xml b/android/src/main/res/values/attrs.xml
index 73eb02c..dde6599 100644
--- a/android/src/main/res/values/attrs.xml
+++ b/android/src/main/res/values/attrs.xml
@@ -16,12 +16,12 @@
<resources>
<declare-styleable name="BaseTheme">
- <attr name="actionBarOverlayTopOffset" format="dimension" />
+ <attr name="actionBarIconColor" format="color" />
<attr name="actionBarInsetStart" format="dimension" />
<attr name="spinnerBarInsetStart" format="dimension" />
- <attr name="selectableItemBackgroundBorderless" format="dimension" />
- <attr name="popupItemBackground" format="dimension" />
- <attr name="photoItemForeground" format="dimension" />
+ <attr name="popupItemBackground" format="reference" />
+ <attr name="photoItemForeground" format="reference" />
+ <attr name="photoItemForegroundBorderless" format="reference" />
</declare-styleable>
<declare-styleable name="MultiSwipeRefreshLayout">
@@ -33,6 +33,10 @@
<attr name="shadowVisible" format="boolean" />
</declare-styleable>
+ <declare-styleable name="ScrimInsetsView">
+ <attr name="insetForeground" format="reference|color" />
+ </declare-styleable>
+
<declare-styleable name="BezelImageView">
<attr name="maskDrawable" format="reference" />
<attr name="borderDrawable" format="reference" />
diff --git a/android/src/main/res/values/colors.xml b/android/src/main/res/values/colors.xml
index fd57b75..cc9a095 100644
--- a/android/src/main/res/values/colors.xml
+++ b/android/src/main/res/values/colors.xml
@@ -50,7 +50,7 @@
<color name="navdrawer_background">#ffffffff</color>
<color name="navdrawer_text_color">@color/body_text_1</color>
<color name="navdrawer_text_color_selected">@color/theme_primary</color>
- <color name="navdrawer_icon_tint">#808080</color>
+ <color name="navdrawer_icon_tint">#888</color>
<color name="navdrawer_icon_tint_selected">@color/theme_primary</color>
<color name="refresh_progress_1">@color/theme_accent_2</color>
@@ -66,6 +66,8 @@
<color name="session_photo_scrim">#6000</color>
<color name="default_session_color">@color/theme_primary</color>
+ <color name="no_track_branding_session_tile_overlay">#8333</color>
+ <color name="no_track_branding_session_color">#333</color>
<color name="nearby_header_color">#00c</color>
<color name="nearby_url_color">#0a0</color>
@@ -76,6 +78,7 @@
<color name="butter_bar_light">#eee0e0e0</color>
<color name="translucent_actionbar_background">#cc3f51b5</color>
+ <color name="translucent_statusbar_background">#cc3f51b5</color>
<color name="tab_background">@color/theme_primary</color>
<color name="tab_selected_strip">@color/theme_accent_1</color>
diff --git a/android/src/main/res/values/dimens.xml b/android/src/main/res/values/dimens.xml
index 6933048..91dd3c1 100644
--- a/android/src/main/res/values/dimens.xml
+++ b/android/src/main/res/values/dimens.xml
@@ -51,7 +51,7 @@
<dimen name="list_item_action_height">90dp</dimen>
<dimen name="list_item_action_margin">2dp</dimen>
<dimen name="action_button_padding">10dp</dimen>
- <dimen name="spinner_left_padding">4dp</dimen>
+ <dimen name="spinner_left_padding">16dp</dimen>
<!-- body content -->
<dimen name="element_spacing_normal">8dp</dimen>
@@ -71,7 +71,7 @@
<dimen name="map_content_padding">8dp</dimen>
<dimen name="map_infowindow_width">260dp</dimen>
- <dimen name="navdrawer_chosen_account_height">120dp</dimen>
+ <dimen name="navdrawer_chosen_account_height">140dp</dimen>
<dimen name="navdrawer_width">260dp</dimen>
<dimen name="navdrawer_profile_image_size">40dp</dimen>
@@ -89,7 +89,8 @@
<dimen name="explore_dropdown_item_height">48dp</dimen>
<dimen name="explore_spinner_width">200dp</dimen>
<dimen name="explore_grid_padding">4dp</dimen>
- <dimen name="half_explore_grid_padding">2dp</dimen>
+ <dimen name="explore_grid_padding_half">2dp</dimen>
+
<dimen name="explore_hero_item_height">240dp</dimen>
<dimen name="filter_spinner_width">0dp</dimen>
@@ -113,17 +114,19 @@
<dimen name="keyline_2_session_detail">@dimen/keyline_2</dimen>
<dimen name="session_detail_speaker_left_offset">@dimen/keyline_1</dimen>
- <dimen name="fab_elevation">2dp</dimen>
- <dimen name="fab_press_translation_z">2dp</dimen>
- <dimen name="session_detail_max_header_elevation">2dp</dimen>
- <dimen name="headerbar_elevation">2dp</dimen>
+ <dimen name="fab_elevation">8dp</dimen>
+ <dimen name="fab_press_translation_z">6dp</dimen>
+ <dimen name="headerbar_elevation">4dp</dimen>
+ <dimen name="session_detail_max_header_elevation">@dimen/headerbar_elevation</dimen>
+ <dimen name="card_elevation">2dp</dimen>
+
+ <dimen name="card_corner_radius">2dp</dimen>
<!-- Social -->
<dimen name="hashtag_line_height">1dp</dimen>
<dimen name="hashtag_height">120dp</dimen>
<dimen name="hashtag_desc_size">40dp</dimen>
- <dimen name="social_grid_padding">4dp</dimen>
<dimen name="social_hz_margin">0dp</dimen>
<dimen name="hashtag_text_size">14sp</dimen>
<dimen name="hashtag_hero_text_size">45sp</dimen>
diff --git a/android/src/main/res/values/fonts.xml b/android/src/main/res/values/fonts.xml
index dd12fd4..9e33312 100644
--- a/android/src/main/res/values/fonts.xml
+++ b/android/src/main/res/values/fonts.xml
@@ -17,7 +17,4 @@
<resources>
<integer name="font_textStyle_medium">1</integer> <!-- bold -->
<string name="font_fontFamily_medium">sans-serif</string>
-
- <integer name="font_textStyle_drawer_item">0</integer> <!-- normal -->
- <string name="font_fontFamily_drawer_item">sans-serif</string>
</resources>
diff --git a/android/src/main/res/values/refs.xml b/android/src/main/res/values/refs.xml
index 5269692..a627782 100644
--- a/android/src/main/res/values/refs.xml
+++ b/android/src/main/res/values/refs.xml
@@ -15,8 +15,6 @@
-->
<resources>
- <item name="toolbar_actionbar_with_headerbar" type="layout">@layout/toolbar_actionbar</item>
- <item name="toolbar_actionbar_with_translucent_background" type="layout">@layout/toolbar_actionbar</item>
<item name="schedule_item_touchoverlay_dark" type="drawable">@drawable/schedule_item_touchoverlay</item>
<item name="header_shadow" type="drawable">@drawable/bottom_shadow</item>
</resources>
diff --git a/android/src/main/res/values/strings.xml b/android/src/main/res/values/strings.xml
index 4a8438d..6f11514 100644
--- a/android/src/main/res/values/strings.xml
+++ b/android/src/main/res/values/strings.xml
@@ -32,6 +32,12 @@
<item quantity="other">%d sessions are about to start.</item>
</plurals>
+ <!-- Indicates a certain number of sessions. -->
+ <plurals name="session_plurals">
+ <item quantity="one">1 session</item>
+ <item quantity="other">%1$d sessions</item>
+ </plurals>
+
<!-- Title for the notification that alerts the user that some of their sessions are about to begin. -->
<plurals name="session_notification_title">
<item quantity="one">1 session is starting in <xliff:g id="remaining_time">%1$d</xliff:g> min.</item>
diff --git a/android/src/main/res/values/styles.xml b/android/src/main/res/values/styles.xml
index ffd2b15..e33f9ba 100644
--- a/android/src/main/res/values/styles.xml
+++ b/android/src/main/res/values/styles.xml
@@ -18,49 +18,50 @@
<!-- Root styles that vary by API level -->
<!-- Disable RTL support on older devices -->
<!-- Prevents crash on certain devices to namespace conflict -->
- <style name="FrameworkRoot.Theme" parent="android:Theme.Holo.Light.DarkActionBar" />
- <style name="FrameworkRoot.ActionBar" parent="android:Widget.Holo.ActionBar" />
- <style name="FrameworkRoot.ActionBar.TitleText" parent="android:TextAppearance.Holo.Widget.ActionBar.Title" />
- <style name="FrameworkRoot.ActionBar.TabBar" parent="android:Widget.Holo.ActionBar.TabBar" />
- <style name="FrameworkRoot.EditText" parent="android:Widget.Holo.Light.EditText" />
- <style name="FrameworkRoot.Widget" parent="android:Theme.Holo" />
- <style name="FrameworkRoot.Widget.ActionButton.Overflow" parent="android:Widget.Holo.ActionButton.Overflow" />
- <style name="FrameworkRoot.Widget.Spinner" parent="android:Widget.Holo.Light.Spinner" />
- <style name="FrameworkRoot.Widget.ListView.DropDown" parent="android:Widget.Holo.Light.ListView.DropDown" />
- <style name="FrameworkRoot.Widget.PopupMenu" parent="android:Widget.Holo.Light.PopupMenu" />
- <style name="FrameworkRoot.TextAppearance.Widget.PopupMenu.Large" parent="android:TextAppearance.Holo.Widget.PopupMenu.Large" />
+ <style name="FrameworkRoot.Theme" parent="Theme.AppCompat.Light" />
+ <style name="FrameworkRoot.Widget" parent="Theme.AppCompat" />
<!-- Immediate parent theme to specify base values for custom attributes -->
<style name="Theme" parent="FrameworkRoot.Theme">
<!-- Only needed for pre-L -->
- <item name="android:actionOverflowButtonStyle">@style/ActionButton.Overflow</item>
<item name="android:editTextBackground">@drawable/edit_text</item>
<item name="android:editTextStyle">@style/Widget.IOSched.EditText</item>
- <item name="android:actionBarWidgetTheme">@style/Theme.IOSched.Widget</item>
- <item name="android:actionDropDownStyle">@style/Widget.IOSched.HeaderBar.Spinner</item>
</style>
<style name="Theme.IOSched.Base" parent="Theme">
- <item name="actionBarOverlayTopOffset">?android:actionBarSize</item>
- <item name="actionBarInsetStart">?android:actionBarSize</item>
- <item name="spinnerBarInsetStart">?android:actionBarSize</item>
- <item name="selectableItemBackgroundBorderless">?android:selectableItemBackground</item>
+ <item name="actionBarIconColor">#fff</item>
+ <item name="actionBarInsetStart">@dimen/keyline_2</item>
+ <item name="homeAsUpIndicator">@drawable/ic_up</item>
+ <item name="spinnerBarInsetStart">@dimen/keyline_2_minus_16dp</item>
<item name="popupItemBackground">?android:selectableItemBackground</item>
<item name="photoItemForeground">?android:selectableItemBackground</item>
+ <item name="photoItemForegroundBorderless">?android:selectableItemBackground</item>
+
+ <item name="colorPrimary">@color/theme_primary</item>
+ <item name="colorPrimaryDark">@color/theme_primary_dark</item>
+ <item name="colorAccent">@color/theme_accent_2</item>
+
+ <item name="android:textColorLink">@color/theme_accent_2</item>
+
+ <item name="windowActionBar">false</item>
+ <item name="android:windowNoTitle">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowBackground">@android:color/white</item>
- <item name="android:actionBarStyle">@style/ActionBar</item>
<item name="android:homeAsUpIndicator">@drawable/ic_up</item>
<item name="android:popupMenuStyle">@style/Widget.IOSched.PopupMenu</item>
<item name="android:listPopupWindowStyle">@style/Widget.IOSched.PopupMenu</item>
<item name="android:dropDownListViewStyle">@style/Widget.IOSched.ListView.DropDown</item>
<item name="android:textAppearanceLargePopupMenu">@style/TextAppearance.LargePopupMenu</item>
+
+ <item name="searchViewStyle">@style/Widget.IOSched.SearchView</item>
</style>
<style name="Theme.IOSched" parent="Theme.IOSched.Base" />
+ <style name="Theme.IOSched.WithNavDrawer" parent="Theme.IOSched" />
+
<style name="Theme.IOSched.Widget" parent="FrameworkRoot.Widget">
<item name="android:popupMenuStyle">@style/Widget.IOSched.PopupMenu</item>
<item name="android:listPopupWindowStyle">@style/Widget.IOSched.PopupMenu</item>
@@ -68,55 +69,67 @@
<item name="android:textAppearanceLargePopupMenu">@style/TextAppearance.LargePopupMenu</item>
</style>
- <style name="ActionButton.Overflow" parent="FrameworkRoot.Widget.ActionButton.Overflow">
- <item name="android:src">@drawable/ic_action_overflow</item>
+ <style name="ActionBarThemeOverlay" parent="">
+ <item name="android:textColorPrimary">#fff</item>
+ <item name="colorControlNormal">?actionBarIconColor</item>
+ <item name="colorControlHighlight">#3fff</item>
</style>
- <style name="Theme.IOSched.Welcome" parent="Theme.IOSched">
- <item name="android:windowActionBar">false</item>
- <item name="android:windowNoTitle">true</item>
+ <style name="ActionBarPopupThemeOverlay" parent="ThemeOverlay.AppCompat.Light" />
+
+ <style name="ActionBar.TitleText" parent="TextAppearance.AppCompat.Widget.ActionBar.Title">
+ <item name="android:textColor">#fff</item>
+ <item name="android:textSize">18sp</item>
</style>
- <style name="Theme.IOSched.Sessions.Base" parent="Theme.IOSched">
- <item name="android:windowActionBarOverlay">true</item>
+ <style name="Theme.IOSched.Welcome" parent="Theme.IOSched" />
+
+ <style name="Theme.IOSched.Sessions" parent="Theme.IOSched.WithNavDrawer">
+ <item name="actionBarInsetStart">@dimen/keyline_2_minus_16dp</item>
+ <item name="spinnerBarInsetStart">@dimen/keyline_2_minus_16dp</item>
<item name="android:windowBackground">@color/gray_background</item>
</style>
<style name="Theme.IOSched.Search" parent="Theme.IOSched">
<item name="android:windowBackground">@color/gray_background</item>
+ <item name="android:autoCompleteTextViewStyle">@style/Widget.IOSched.Search.AutoCompleteTextView</item>
+ <item name="colorControlActivated">@color/theme_accent_1</item>
</style>
- <style name="Theme.IOSched.Sessions" parent="Theme.IOSched.Sessions.Base" />
-
- <style name="Theme.IOSched.VideoLibrary" parent="Theme.IOSched">
- <item name="android:windowActionBarOverlay">true</item>
+ <style name="Widget.IOSched.Search.AutoCompleteTextView" parent="Widget.AppCompat.Light.AutoCompleteTextView">
+ <item name="android:textColorHint">#5fff</item>
</style>
- <style name="Widget.IOSched.HeaderBar.Spinner.Base" parent="FrameworkRoot.Widget.Spinner">
+ <style name="Theme.IOSched.VideoLibrary" parent="Theme.IOSched.WithNavDrawer" />
+
+ <style name="Widget.IOSched.HeaderBar.Spinner.Base" parent="Widget.AppCompat.Light.Spinner.DropDown.ActionBar">
<item name="android:background">?android:selectableItemBackground</item>
<item name="android:dropDownSelector">?android:selectableItemBackground</item>
<item name="android:divider">@null</item>
<item name="android:dividerHeight">0dp</item>
+ <item name="android:overlapAnchor">true</item>
</style>
<style name="Widget.IOSched.HeaderBar.Spinner" parent="Widget.IOSched.HeaderBar.Spinner.Base" />
- <style name="Widget.IOSched.PopupMenu" parent="FrameworkRoot.Widget.PopupMenu">
+ <style name="Widget.IOSched.PopupMenu" parent="Widget.AppCompat.Light.PopupMenu">
<item name="android:dropDownSelector">?popupItemBackground</item>
</style>
- <style name="Widget.IOSched.ListView.DropDown" parent="FrameworkRoot.Widget.ListView.DropDown">
+ <style name="Widget.IOSched.ListView.DropDown" parent="Widget.AppCompat.Light.ListView.DropDown">
<item name="android:listSelector">?popupItemBackground</item>
<item name="android:divider">@null</item>
<item name="android:dividerHeight">0dp</item>
</style>
- <style name="TextAppearance.LargePopupMenu" parent="FrameworkRoot.TextAppearance.Widget.PopupMenu.Large">
+ <style name="TextAppearance.LargePopupMenu" parent="TextAppearance.AppCompat.Widget.PopupMenu.Large">
<item name="android:textColor">@color/body_text_1</item>
</style>
+ <style name="Widget.IOSched.SearchView" parent="Widget.AppCompat.SearchView" />
+
<!-- My Schedule -->
- <style name="Theme.IOSched.MySchedule" parent="Theme.IOSched" />
+ <style name="Theme.IOSched.MySchedule" parent="Theme.IOSched.WithNavDrawer" />
<!-- Intermediary theme for SessionDetails (so we can override it on large screens) -->
<style name="Theme.IOSched.SessionDetails.Base" parent="Theme.IOSched">
@@ -124,15 +137,11 @@
</style>
<!-- Session Details -->
- <style name="Theme.IOSched.SessionDetails" parent="Theme.IOSched.SessionDetails.Base">
- <item name="android:actionBarStyle">@style/TransparentActionBar</item>
- <item name="android:windowActionBarOverlay">true</item>
- </style>
+ <style name="Theme.IOSched.SessionDetails" parent="Theme.IOSched.SessionDetails.Base" />
<!-- Social -->
- <style name="Theme.IOSched.Social" parent="Theme.IOSched">
+ <style name="Theme.IOSched.Social" parent="Theme.IOSched.WithNavDrawer">
<item name="android:windowBackground">@color/gray_background</item>
- <item name="android:windowContentOverlay">@drawable/header_shadow</item>
</style>
<!-- Account chooser -->
@@ -140,55 +149,32 @@
<item name="android:actionBarStyle">@style/ActionBar.Accounts</item>
</style>
- <style name="ActionBar.Accounts" parent="ActionBar">
+ <style name="ActionBar.Accounts" parent="">
<item name="android:displayOptions">showHome|useLogo</item>
</style>
<!-- People I've Met -->
- <style name="Theme.IOSched.PeopleIveMet" parent="Theme.IOSched">
- <item name="android:windowContentOverlay">@drawable/header_shadow</item>
- </style>
+ <style name="Theme.IOSched.PeopleIveMet" parent="Theme.IOSched.WithNavDrawer" />
<!-- Experts -->
- <style name="Theme.IOSched.ExpertsDirectory" parent="Theme.IOSched">
- <item name="android:windowActionBarOverlay">true</item>
- </style>
+ <style name="Theme.IOSched.ExpertsDirectory" parent="Theme.IOSched.WithNavDrawer" />
- <!-- Action bar -->
- <style name="ActionBar.Base" parent="FrameworkRoot.ActionBar">
- <item name="android:background">@drawable/actionbar_background</item>
- <item name="android:icon">@drawable/actionbar_icon</item>
- <item name="android:displayOptions">showHome|showTitle</item>
- <item name="android:titleTextStyle">@style/ActionBar.TitleText</item>
- <item name="android:logo">@drawable/actionbar_logo</item>
- </style>
-
- <style name="ActionBar" parent="ActionBar.Base" />
-
- <style name="ActionBar.TitleText" parent="FrameworkRoot.ActionBar.TitleText">
- <item name="android:textColor">#fff</item>
- <item name="android:textSize">18sp</item>
- </style>
-
+ <!-- Misc -->
<style name="TabIndicator" />
<!-- Transparent Action Bar -->
- <style name="TransparentActionBar" parent="ActionBar">
+ <style name="TransparentActionBar" parent="">
<item name="android:background">@null</item>
</style>
- <style name="TranslucentActionBar" parent="ActionBar">
+ <style name="TranslucentActionBar" parent="">
<item name="android:background">@color/translucent_actionbar_background</item>
</style>
<!-- Live stream -->
<style name="Theme.IOSched.Livestream" parent="Theme.IOSched">
<item name="android:windowBackground">@color/gray_background</item>
- </style>
-
- <!-- Etc. -->
- <style name="Theme.IOSched.WithElevatedHeader" parent="Theme.IOSched">
- <item name="android:windowContentOverlay">@drawable/header_shadow</item>
+ <item name="actionBarInsetStart">@dimen/keyline_2_minus_16dp</item>
</style>
<!-- Empty views -->
@@ -278,10 +264,7 @@
</style>
<!-- Map -->
- <style name="Theme.IOSched.Map" parent="Theme.IOSched">
- <item name="android:actionBarStyle">@style/TranslucentActionBar</item>
- <item name="android:windowActionBarOverlay">true</item>
- </style>
+ <style name="Theme.IOSched.Map" parent="Theme.IOSched.WithNavDrawer" />
<style name="MapInfoText" parent="@style/TextHeaderSub">
<item name="android:textColor">@color/map_info_1</item>
@@ -312,7 +295,7 @@
<item name="android:shadowRadius">3</item>
</style>
- <style name="Widget.IOSched.EditText" parent="FrameworkRoot.EditText">
+ <style name="Widget.IOSched.EditText" parent="Widget.AppCompat.EditText">
<item name="android:background">@drawable/edit_text</item>
</style>
@@ -329,7 +312,10 @@
<item name="android:textColor">@color/theme_primary</item>
</style>
- <style name="HeaderBar" />
+ <style name="HeaderBar">
+ <item name="android:background">?colorPrimary</item>
+ <item name="android:elevation">@dimen/headerbar_elevation</item>
+ </style>
<!-- Session feedback -->
diff --git a/art/actionbar_action_icons.ai b/art/actionbar_action_icons.ai
index b1eac2c..316a7d4 100644
--- a/art/actionbar_action_icons.ai
+++ b/art/actionbar_action_icons.ai
Binary files differ
diff --git a/art/drawer_icons.ai b/art/drawer_icons.ai
index f0eee67..d68265e 100644
--- a/art/drawer_icons.ai
+++ b/art/drawer_icons.ai
Binary files differ
diff --git a/art/ic_launcher_material-xxxhdpi.psd b/art/ic_launcher_material-xxxhdpi.psd
new file mode 100644
index 0000000..ef8413c
--- /dev/null
+++ b/art/ic_launcher_material-xxxhdpi.psd
Binary files differ
diff --git a/art/ic_launcher_material.ai b/art/ic_launcher_material.ai
index 74bef3d..636f523 100644
--- a/art/ic_launcher_material.ai
+++ b/art/ic_launcher_material.ai
Binary files differ
diff --git a/binaries/iosched-lpreview.apk b/binaries/iosched-lpreview.apk
deleted file mode 100644
index 5c2afe9..0000000
--- a/binaries/iosched-lpreview.apk
+++ /dev/null
Binary files differ
diff --git a/doc/BUILDING.md b/doc/BUILDING.md
index 38bb756..3bbac7b 100644
--- a/doc/BUILDING.md
+++ b/doc/BUILDING.md
@@ -105,8 +105,7 @@
./gradlew -Plpreview installLpreviewDebug
-You will need a device flashed with the Android L preview system image, or
-you can use the emulator.
+You will need a device flashed with the Android L preview system image.
# Server-side setup
diff --git a/doc/IMAGES.md b/doc/IMAGES.md
index 76feba6..2fc995c 100644
--- a/doc/IMAGES.md
+++ b/doc/IMAGES.md
@@ -77,7 +77,7 @@
URL | Image size
--- | ----------
-myserver.com/images/**__w-200-400-600-800-1000__**/session1.jpg | original
+myserver.com/images/**\_\_w-200-400-600-800-1000\_\_**/session1.jpg | original
myserver.com/images/w200/session1.jpg | 200px wide
myserver.com/images/w400/session1.jpg | 400px wide
myserver.com/images/w600/session1.jpg | 600px wide
diff --git a/gcm-server/build.gradle b/gcm-server/build.gradle
index 3079d11..dc529e3 100644
--- a/gcm-server/build.gradle
+++ b/gcm-server/build.gradle
@@ -52,7 +52,6 @@
downloadSdk = true
appcfg {
- email = 'mangini@google.com'
passIn = true
oauth2 = true