summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSai Cheemalapati <saicheems@google.com>2014-06-06 20:47:30 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-06-06 20:47:30 +0000
commit49378067cde003c0443d6837c01085ee63482889 (patch)
treea704e065ec4a5c3b2c41c309a870dce41a938245
parent891c0e95e0b8839c944e3d819a35c056df3dad05 (diff)
parentc4969ea3d2ac04f58f0caccef709bc95a182c378 (diff)
Merge "Moving FAB logic to ContactsCommon."
-rw-r--r--res/values/dimens.xml1
-rw-r--r--src/com/android/dialer/DialtactsActivity.java84
-rw-r--r--src/com/android/dialer/widget/FloatingActionButtonController.java212
3 files changed, 70 insertions, 227 deletions
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 2869c62f4..5cf216c7e 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -38,7 +38,6 @@
<!-- Match call_button_height to Phone's dimens/in_call_end_button_height -->
<dimen name="call_button_height">74dp</dimen>
- <dimen name="floating_action_button_dialpad_margin_bottom_offset">4dp</dimen>
<!-- Dimensions for speed dial tiles -->
<dimen name="contact_tile_divider_width">1dp</dimen>
diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java
index 43b2c5874..53e438d6d 100644
--- a/src/com/android/dialer/DialtactsActivity.java
+++ b/src/com/android/dialer/DialtactsActivity.java
@@ -73,6 +73,7 @@ import com.android.contacts.common.dialog.ClearFrequentsDialog;
import com.android.contacts.common.interactions.ImportExportDialogFragment;
import com.android.contacts.common.list.OnPhoneNumberPickerActionListener;
import com.android.contacts.common.util.ViewUtil;
+import com.android.contacts.common.widget.FloatingActionButtonController;
import com.android.dialer.calllog.CallLogActivity;
import com.android.dialer.database.DialerDatabaseHelper;
import com.android.dialer.dialpad.DialpadFragment;
@@ -90,7 +91,6 @@ import com.android.dialer.list.RemoveView;
import com.android.dialer.list.SearchFragment;
import com.android.dialer.list.SmartDialSearchFragment;
import com.android.dialer.widget.ActionBarController;
-import com.android.dialer.widget.FloatingActionButtonController;
import com.android.dialer.widget.SearchEditTextLayout;
import com.android.dialer.widget.SearchEditTextLayout.OnBackButtonClickedListener;
import com.android.dialerbind.DatabaseHelperManager;
@@ -234,7 +234,15 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
private DialerDatabaseHelper mDialerDatabaseHelper;
private DragDropController mDragDropController;
private ActionBarController mActionBarController;
+
+ private String mDescriptionDialButtonStr;
+ private String mActionMenuDialpadButtonStr;
+ private ImageButton mFloatingActionButton;
private FloatingActionButtonController mFloatingActionButtonController;
+ /**
+ * Additional offset for FAB to be lowered when dialpad is open.
+ */
+ private int mFloatingActionButtonDialpadMarginBottomOffset;
private int mActionBarHeight;
@@ -350,6 +358,8 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
final Resources resources = getResources();
mActionBarHeight = resources.getDimensionPixelSize(R.dimen.action_bar_height);
+ mDescriptionDialButtonStr = resources.getString(R.string.description_dial_button);
+ mActionMenuDialpadButtonStr = resources.getString(R.string.action_menu_dialpad_button);
setContentView(R.layout.dialtacts_activity);
getWindow().setBackgroundDrawable(null);
@@ -381,13 +391,18 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
}
});
- boolean mIsLandscape = getResources().getConfiguration().orientation
+ mIsLandscape = getResources().getConfiguration().orientation
== Configuration.ORIENTATION_LANDSCAPE;
- View floatingActionButtonContainer = findViewById(R.id.floating_action_button_container);
- ImageButton floatingActionButton = (ImageButton) findViewById(R.id.floating_action_button);
- floatingActionButton.setOnClickListener(this);
- mFloatingActionButtonController = new FloatingActionButtonController(this, mIsLandscape,
+ final View floatingActionButtonContainer = findViewById(
+ R.id.floating_action_button_container);
+ mFloatingActionButton = (ImageButton) findViewById(R.id.floating_action_button);
+ int floatingActionButtonWidth = resources.getDimensionPixelSize(
+ R.dimen.floating_action_button_width);
+ mFloatingActionButton.setOnClickListener(this);
+ mFloatingActionButtonController = new FloatingActionButtonController(this,
floatingActionButtonContainer);
+ mFloatingActionButtonDialpadMarginBottomOffset = resources.getDimensionPixelOffset(
+ R.dimen.floating_action_button_dialpad_margin_bottom_offset);
ImageButton optionsMenuButton =
(ImageButton) searchEditTextLayout.findViewById(R.id.dialtacts_options_menu_button);
@@ -409,7 +424,6 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
mFirstLaunch = savedInstanceState.getBoolean(KEY_FIRST_LAUNCH);
mShowDialpadOnResume = savedInstanceState.getBoolean(KEY_IS_DIALPAD_SHOWN);
mActionBarController.restoreInstanceState(savedInstanceState);
- mFloatingActionButtonController.restoreInstanceState(savedInstanceState);
}
mSlideIn = AnimationUtils.loadAnimation(this,
@@ -422,13 +436,19 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
parentLayout = (RelativeLayout) findViewById(R.id.dialtacts_mainlayout);
parentLayout.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
parentLayout.setOnDragListener(new LayoutOnDragListener());
- parentLayout.getViewTreeObserver().addOnGlobalLayoutListener(
+ floatingActionButtonContainer.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
+ final ViewTreeObserver observer = floatingActionButtonContainer
+ .getViewTreeObserver();
+ if (!observer.isAlive()) {
+ return;
+ }
+ observer.removeOnGlobalLayoutListener(this);
int screenWidth = parentLayout.getWidth();
mFloatingActionButtonController.setScreenWidth(screenWidth);
- parentLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+ updateFloatingActionButtonControllerAlignment(false /* animate */);
}
});
@@ -468,6 +488,7 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
mFirstLaunch = false;
prepareVoiceSearchButton();
mDialerDatabaseHelper.startSmartDialUpdateThread();
+ updateFloatingActionButtonControllerAlignment(false /* animate */);
}
@Override
@@ -488,7 +509,6 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
outState.putBoolean(KEY_FIRST_LAUNCH, mFirstLaunch);
outState.putBoolean(KEY_IS_DIALPAD_SHOWN, mIsDialpadShown);
mActionBarController.saveInstanceState(outState);
- mFloatingActionButtonController.saveInstanceState(outState);
}
@Override
@@ -639,7 +659,9 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
* Callback from child DialpadFragment when the dialpad is shown.
*/
public void onDialpadShown() {
- mFloatingActionButtonController.updateByDialpadVisibility(true);
+ mFloatingActionButton.setImageResource(R.drawable.fab_ic_call);
+ mFloatingActionButton.setContentDescription(mDescriptionDialButtonStr);
+ updateFloatingActionButtonControllerAlignment(mDialpadFragment.getAnimate());
if (mDialpadFragment.getAnimate()) {
mDialpadFragment.getView().startAnimation(mSlideIn);
} else {
@@ -668,7 +690,10 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
mDialpadFragment.setAnimate(animate);
updateSearchFragmentPosition();
- mFloatingActionButtonController.updateByDialpadVisibility(false);
+ mFloatingActionButton.setImageResource(R.drawable.fab_ic_dial);
+ mFloatingActionButton.setContentDescription(mActionMenuDialpadButtonStr);
+
+ updateFloatingActionButtonControllerAlignment(animate);
if (animate) {
mDialpadFragment.getView().startAnimation(mSlideOut);
} else {
@@ -1100,13 +1125,23 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
- mFloatingActionButtonController.onPageScrolled(position, positionOffset);
+ // Only scroll the button when the first tab is selected. The button should scroll from
+ // the middle to right position only on the transition from the first tab to the second
+ // tab.
+ if (position == ListsFragment.TAB_INDEX_SPEED_DIAL) {
+ mFloatingActionButtonController.onPageScrolled(positionOffset);
+ }
}
@Override
public void onPageSelected(int position) {
mCurrentTabPosition = position;
- mFloatingActionButtonController.updateByTab(position);
+ // Prevents jittery movement when clicking on tabs.
+ if (mCurrentTabPosition != ListsFragment.TAB_INDEX_SPEED_DIAL) {
+ mFloatingActionButtonController.manuallyTranslate(
+ mFloatingActionButtonController.getTranslationXForAlignment(
+ FloatingActionButtonController.ALIGN_RIGHT), 0);
+ }
}
@Override
@@ -1140,4 +1175,25 @@ public class DialtactsActivity extends TransactionSafeActivity implements View.O
public void setActionBarHideOffset(int hideOffset) {
getActionBar().setHideOffset(hideOffset);
}
+
+ /**
+ * Updates controller based on currently known information.
+ *
+ * @param animate Whether or not to animate the transition.
+ */
+ private void updateFloatingActionButtonControllerAlignment(boolean animate) {
+ int align;
+ if (mIsDialpadShown) {
+ align = mIsLandscape ? FloatingActionButtonController.ALIGN_QUARTER_RIGHT
+ : FloatingActionButtonController.ALIGN_MIDDLE;
+ } else {
+ align = mCurrentTabPosition == ListsFragment.TAB_INDEX_SPEED_DIAL
+ ? FloatingActionButtonController.ALIGN_MIDDLE
+ : FloatingActionButtonController.ALIGN_RIGHT;
+ }
+ mFloatingActionButtonController.align(align,
+ 0 /* offsetX */,
+ mIsDialpadShown ? mFloatingActionButtonDialpadMarginBottomOffset : 0 /* offsetY */,
+ animate);
+ }
}
diff --git a/src/com/android/dialer/widget/FloatingActionButtonController.java b/src/com/android/dialer/widget/FloatingActionButtonController.java
deleted file mode 100644
index 3f59153ef..000000000
--- a/src/com/android/dialer/widget/FloatingActionButtonController.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dialer.widget;
-
-import android.app.Activity;
-import android.content.res.Resources;
-import android.os.Bundle;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
-import android.view.View;
-import android.widget.ImageButton;
-
-import com.android.contacts.common.util.ViewUtil;
-import com.android.dialer.R;
-import com.android.dialer.list.ListsFragment;
-
-/**
- * Controls the movement and appearance of the FAB.
- */
-public class FloatingActionButtonController {
- private static final String KEY_IS_DIALPAD_VISIBLE = "key_is_dialpad_visible";
- private static final String KEY_CURRENT_TAB_POSITION = "key_current_tab_position";
- private static final int ANIMATION_DURATION = 250;
-
- private int mScreenWidth;
-
- private int mCurrentTabPosition;
-
- private ImageButton mFloatingActionButton;
- private View mFloatingActionButtonContainer;
-
- private boolean mIsLandscape;
- private boolean mIsDialpadVisible;
- private boolean mAnimateFloatingActionButton;
-
- private String mDescriptionDialButtonStr;
- private String mActionMenuDialpadButtonStr;
-
- /**
- * Interpolator for FAB animations.
- */
- private Interpolator mFabInterpolator;
-
- /**
- * Additional offset for FAB to be lowered when dialpad is open.
- */
- private int mFloatingActionButtonDialpadMarginBottomOffset;
-
- public FloatingActionButtonController(Activity activity, boolean isLandscape,
- View container) {
- Resources resources = activity.getResources();
- mIsLandscape = isLandscape;
- mFabInterpolator = AnimationUtils.loadInterpolator(activity,
- android.R.interpolator.fast_out_slow_in);
- mFloatingActionButtonDialpadMarginBottomOffset = resources.getDimensionPixelOffset(
- R.dimen.floating_action_button_dialpad_margin_bottom_offset);
- mFloatingActionButton = (ImageButton) activity.
- findViewById(R.id.floating_action_button);
- mDescriptionDialButtonStr = resources.getString(R.string.description_dial_button);
- mActionMenuDialpadButtonStr = resources.getString(R.string.action_menu_dialpad_button);
- mFloatingActionButtonContainer = container;
- ViewUtil.setupFloatingActionButton(mFloatingActionButtonContainer, resources);
- }
-
- /**
- * Passes the screen width into the class. Necessary for translation calculations.
- *
- * @param screenWidth the width of the screen
- */
- public void setScreenWidth(int screenWidth) {
- mScreenWidth = screenWidth;
- updateByDialpadVisibility(mIsDialpadVisible);
- }
-
- public void setVisible(boolean visible) {
- mFloatingActionButtonContainer.setVisibility(visible ? View.VISIBLE : View.GONE);
- }
-
- /**
- * Updates the FAB location (middle to right position) as the PageView scrolls.
- *
- * @param position tab position to align for
- * @param positionOffset a fraction used to calculate position of the FAB during page scroll
- */
- public void onPageScrolled(int position, float positionOffset) {
- // As the page is scrolling, if we're on the first tab, update the FAB position so it
- // moves along with it.
- if (position == ListsFragment.TAB_INDEX_SPEED_DIAL) {
- mFloatingActionButtonContainer.setTranslationX(
- (int) (positionOffset * (mScreenWidth / 2f
- - mFloatingActionButton.getWidth())));
- mFloatingActionButtonContainer.setTranslationY(0);
- }
- }
-
- /**
- * Updates the FAB location given a tab position.
- *
- * @param position tab position to align for
- */
- public void updateByTab(int position) {
- // If the screen width hasn't been set yet, don't do anything.
- if (mScreenWidth == 0 || mIsDialpadVisible) return;
- alignFloatingActionButtonByTab(position, false);
- mAnimateFloatingActionButton = true;
- }
-
- /**
- * Updates the FAB location to the proper location given whether or not the dialer is open.
- *
- * @param dialpadVisible whether or not the dialpad is currently open
- */
- public void updateByDialpadVisibility(boolean dialpadVisible) {
- // If the screen width hasn't been set yet, don't do anything.
- if (mScreenWidth == 0) return;
- mIsDialpadVisible = dialpadVisible;
-
- moveFloatingActionButton(mAnimateFloatingActionButton);
- mAnimateFloatingActionButton = true;
- }
-
- /**
- * Moves the FAB to the best known location given what the class currently knows.
- *
- * @param animate whether or not to smoothly animate the button
- */
- private void moveFloatingActionButton(boolean animate) {
- if (mIsDialpadVisible) {
- mFloatingActionButton.setImageResource(R.drawable.fab_ic_call);
- mFloatingActionButton.setContentDescription(mDescriptionDialButtonStr);
- alignFloatingActionButton(animate);
- } else {
- mFloatingActionButton.setImageResource(R.drawable.fab_ic_dial);
- mFloatingActionButton.setContentDescription(mActionMenuDialpadButtonStr);
- alignFloatingActionButtonByTab(mCurrentTabPosition, mAnimateFloatingActionButton);
- }
- }
-
- /**
- * Aligns the FAB to the position for the indicated tab.
- *
- * @param position tab position to align for
- * @param animate whether or not to smoothly animate the button
- */
- private void alignFloatingActionButtonByTab(int position, boolean animate) {
- mCurrentTabPosition = position;
- alignFloatingActionButton(animate);
- }
-
- /**
- * Aligns the FAB to the correct position.
- *
- * @param animate whether or not to smoothly animate the button
- */
- private void alignFloatingActionButton(boolean animate) {
- int translationX = calculateTranslationX();
- int translationY = mIsDialpadVisible ? mFloatingActionButtonDialpadMarginBottomOffset : 0;
- if (animate) {
- mFloatingActionButtonContainer.animate()
- .translationX(translationX)
- .translationY(translationY)
- .setInterpolator(mFabInterpolator)
- .setDuration(ANIMATION_DURATION).start();
- } else {
- mFloatingActionButtonContainer.setTranslationX(translationX);
- mFloatingActionButtonContainer.setTranslationY(translationY);
- }
- }
-
- /**
- * Calculates the translationX distance for the FAB.
- */
- private int calculateTranslationX() {
- if (mIsDialpadVisible) {
- return mIsLandscape ? mScreenWidth / 4 : 0;
- }
- if (mCurrentTabPosition == ListsFragment.TAB_INDEX_SPEED_DIAL) {
- return 0;
- }
- return mScreenWidth / 2 - mFloatingActionButton.getWidth();
- }
-
- /**
- * Saves the current state of the floating action button into a provided {@link Bundle}
- */
- public void saveInstanceState(Bundle outState) {
- outState.putBoolean(KEY_IS_DIALPAD_VISIBLE, mIsDialpadVisible);
- outState.putInt(KEY_CURRENT_TAB_POSITION, mCurrentTabPosition);
- }
-
- /**
- * Restores the floating action button state from a provided {@link Bundle}
- */
- public void restoreInstanceState(Bundle inState) {
- mIsDialpadVisible = inState.getBoolean(KEY_IS_DIALPAD_VISIBLE);
- mCurrentTabPosition = inState.getInt(KEY_CURRENT_TAB_POSITION);
- }
-}