Merge "GridLayoutManager: fix NPE when adapter changed in scrolling" into lmp-preview-dev
diff --git a/v17/leanback/res/layout/lb_browse_title.xml b/v17/leanback/res/layout/lb_browse_title.xml
index bc6a808..75068d8 100644
--- a/v17/leanback/res/layout/lb_browse_title.xml
+++ b/v17/leanback/res/layout/lb_browse_title.xml
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<android.support.v17.leanback.widget.TitleView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/browse_title_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -22,30 +22,5 @@
android:paddingRight="?attr/browsePaddingRight"
android:paddingLeft="?attr/browsePaddingLeft"
android:paddingBottom="?attr/browsePaddingTop"
- android:clipToPadding="false"
- android:clipChildren="false">
+ style="?attr/browseTitleViewStyle" />
- <ImageView
- android:id="@+id/browse_badge"
- android:layout_width="@dimen/lb_browse_title_text_width"
- android:layout_height="@dimen/lb_browse_title_height"
- android:layout_gravity="center_vertical|right"
- android:src="@null"
- android:visibility="gone"
- style="?attr/browseTitleIconStyle"/>
-
- <TextView
- android:id="@+id/browse_title"
- android:layout_width="@dimen/lb_browse_title_text_width"
- android:layout_height="@dimen/lb_browse_title_height"
- android:layout_gravity="center_vertical|right"
- style="?attr/browseTitleTextStyle"/>
-
- <android.support.v17.leanback.widget.SearchOrbView
- android:id="@+id/browse_orb"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_gravity="center_vertical|left"
- android:visibility="invisible" />
-
-</FrameLayout>
diff --git a/v17/leanback/res/layout/lb_title_view.xml b/v17/leanback/res/layout/lb_title_view.xml
new file mode 100644
index 0000000..590a683
--- /dev/null
+++ b/v17/leanback/res/layout/lb_title_view.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<merge xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <ImageView
+ android:id="@+id/browse_badge"
+ android:layout_width="@dimen/lb_browse_title_text_width"
+ android:layout_height="@dimen/lb_browse_title_height"
+ android:layout_gravity="center_vertical|right"
+ android:src="@null"
+ android:visibility="gone"
+ style="?attr/browseTitleIconStyle"/>
+
+ <TextView
+ android:id="@+id/browse_title"
+ android:layout_width="@dimen/lb_browse_title_text_width"
+ android:layout_height="@dimen/lb_browse_title_height"
+ android:layout_gravity="center_vertical|right"
+ style="?attr/browseTitleTextStyle"/>
+
+ <android.support.v17.leanback.widget.SearchOrbView
+ android:id="@+id/browse_orb"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center_vertical|left"
+ android:visibility="invisible" />
+
+</merge>
diff --git a/v17/leanback/res/values/attrs.xml b/v17/leanback/res/values/attrs.xml
index a0fed63..533ba7e 100644
--- a/v17/leanback/res/values/attrs.xml
+++ b/v17/leanback/res/values/attrs.xml
@@ -115,6 +115,11 @@
</attr>
</declare-styleable>
+ <declare-styleable name="lbTitleView">
+ <!-- Defining color of the search affordance -->
+ <attr name="searchAffordanceColor" format="reference|color" />
+ </declare-styleable>
+
<declare-styleable name="LeanbackTheme">
<!-- left padding of BrowseFragment, RowsFragment, DetailsFragment -->
@@ -138,6 +143,9 @@
<!-- BrowseFragment Title icon style -->
<attr name="browseTitleIconStyle" format="reference" />
+ <!-- BrowseFragment TitleView style -->
+ <attr name="browseTitleViewStyle" format="reference" />
+
<!-- vertical grid style inside HeadersFragment -->
<attr name="headersVerticalGridStyle" format="reference" />
<!-- header style inside HeadersFragment -->
diff --git a/v17/leanback/res/values/styles.xml b/v17/leanback/res/values/styles.xml
index 535f7e3..1074bb0 100644
--- a/v17/leanback/res/values/styles.xml
+++ b/v17/leanback/res/values/styles.xml
@@ -74,6 +74,10 @@
<item name="android:background">@color/lb_basic_card_bg_color</item>
</style>
+ <style name="Widget.Leanback.TitleView" >
+ <item name="searchAffordanceColor">?attr/defaultSearchColor</item>
+ </style>
+
<style name="Widget.Leanback.Title" />
<style name="Widget.Leanback.Title.Text">
diff --git a/v17/leanback/res/values/themes.xml b/v17/leanback/res/values/themes.xml
index a481488..aab296a 100644
--- a/v17/leanback/res/values/themes.xml
+++ b/v17/leanback/res/values/themes.xml
@@ -41,6 +41,8 @@
<item name="browseTitleTextStyle">@style/Widget.Leanback.Title.Text</item>
<item name="browseTitleIconStyle">@style/Widget.Leanback.Title.Icon</item>
+ <item name="browseTitleViewStyle">@style/Widget.Leanback.TitleView</item>
+
<item name="rowHeaderStyle">@style/Widget.Leanback.Row.Header</item>
<item name="rowHoverCardTitleStyle">@style/Widget.Leanback.Row.HoverCardTitle</item>
<item name="rowHoverCardDescriptionStyle">@style/Widget.Leanback.Row.HoverCardDescription</item>
diff --git a/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java b/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java
index 2d5f9be..02a584a 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/BrowseFragment.java
@@ -17,6 +17,7 @@
import android.support.v17.leanback.widget.HorizontalGridView;
import android.support.v17.leanback.widget.Presenter;
import android.support.v17.leanback.widget.PresenterSelector;
+import android.support.v17.leanback.widget.TitleView;
import android.support.v17.leanback.widget.VerticalGridView;
import android.support.v17.leanback.widget.Row;
import android.support.v17.leanback.widget.ObjectAdapter;
@@ -24,7 +25,6 @@
import android.support.v17.leanback.widget.OnItemClickedListener;
import android.support.v17.leanback.widget.SearchOrbView;
import android.util.Log;
-import android.util.TypedValue;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
@@ -36,9 +36,6 @@
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.MarginLayoutParams;
-import android.view.animation.DecelerateInterpolator;
-import android.widget.ImageView;
-import android.widget.TextView;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
@@ -194,10 +191,7 @@
private boolean mBrandColorSet;
private BrowseFrameLayout mBrowseFrame;
- private ImageView mBadgeView;
- private TextView mTitleView;
- private ViewGroup mBrowseTitle;
- private SearchOrbView mSearchOrbView;
+ private TitleView mTitleView;
private boolean mShowingTitle = true;
private boolean mHeadersBackStackEnabled = true;
private String mWithHeadersBackStackName;
@@ -362,8 +356,8 @@
*/
public void setOnSearchClickedListener(View.OnClickListener listener) {
mExternalOnSearchClickedListener = listener;
- if (mSearchOrbView != null) {
- mSearchOrbView.setOnOrbClickedListener(listener);
+ if (mTitleView != null) {
+ mTitleView.setOnSearchClickedListener(listener);
}
}
@@ -373,9 +367,8 @@
public void setSearchAffordanceColor(int color) {
mSearchAffordanceColor = color;
mSearchAffordanceColorSet = true;
-
- if (mSearchOrbView != null) {
- mSearchOrbView.setOrbColor(mSearchAffordanceColor);
+ if (mTitleView != null) {
+ mTitleView.setSearchAffordanceColor(mSearchAffordanceColor);
}
}
@@ -384,17 +377,13 @@
* Can be called only after an activity has been attached.
*/
public int getSearchAffordanceColor() {
- if (getActivity() == null) {
- throw new IllegalStateException("Activity must be attached");
- }
-
if (mSearchAffordanceColorSet) {
return mSearchAffordanceColor;
}
-
- TypedValue outValue = new TypedValue();
- getActivity().getTheme().resolveAttribute(R.attr.defaultSearchColor, outValue, true);
- return getResources().getColor(outValue.resourceId);
+ if (mTitleView == null) {
+ throw new IllegalStateException("Fragment views not yet created");
+ }
+ return mTitleView.getSearchAffordanceColor();
}
/**
@@ -472,6 +461,7 @@
// If headers fragment is disabled, just return null.
if (!mCanShowHeaders) return null;
+ final View searchOrbView = mTitleView.getSearchAffordanceView();
// if headers is running transition, focus stays
if (isInHeadersTransition()) return focused;
if (DEBUG) Log.v(TAG, "onFocusSearch focused " + focused + " + direction " + direction);
@@ -485,13 +475,13 @@
return focused;
}
return mRowsFragment.getVerticalGridView();
- } else if (focused == mSearchOrbView && direction == View.FOCUS_DOWN) {
+ } else if (focused == searchOrbView && direction == View.FOCUS_DOWN) {
return mShowingHeaders ? mHeadersFragment.getVerticalGridView() :
mRowsFragment.getVerticalGridView();
- } else if (focused != mSearchOrbView && mSearchOrbView.getVisibility() == View.VISIBLE
+ } else if (focused != searchOrbView && searchOrbView.getVisibility() == View.VISIBLE
&& direction == View.FOCUS_UP) {
- return mSearchOrbView;
+ return searchOrbView;
} else {
return null;
@@ -577,16 +567,14 @@
mBrowseFrame.setOnFocusSearchListener(mOnFocusSearchListener);
mBrowseFrame.setOnChildFocusListener(mOnChildFocusListener);
- mBrowseTitle = (ViewGroup) root.findViewById(R.id.browse_title_group);
- mTitleView = (TextView) mBrowseTitle.findViewById(R.id.browse_title);
- mTitleView.setText(mTitle);
- mBadgeView = (ImageView) mBrowseTitle.findViewById(R.id.browse_badge);
- setBadgeViewImage();
-
- mSearchOrbView = (SearchOrbView) mBrowseTitle.findViewById(R.id.browse_orb);
- mSearchOrbView.setOrbColor(getSearchAffordanceColor());
+ mTitleView = (TitleView) root.findViewById(R.id.browse_title_group);
+ mTitleView.setTitle(mTitle);
+ mTitleView.setBadgeDrawable(mBadgeDrawable);
+ if (mSearchAffordanceColorSet) {
+ mTitleView.setSearchAffordanceColor(mSearchAffordanceColor);
+ }
if (mExternalOnSearchClickedListener != null) {
- mSearchOrbView.setOnOrbClickedListener(mExternalOnSearchClickedListener);
+ mTitleView.setOnSearchClickedListener(mExternalOnSearchClickedListener);
}
if (mBrandColorSet) {
@@ -596,13 +584,13 @@
mSceneWithTitle = sTransitionHelper.createScene(mBrowseFrame, new Runnable() {
@Override
public void run() {
- showTitle(true);
+ TitleTransitionHelper.showTitle(mTitleView, true);
}
});
mSceneWithoutTitle = sTransitionHelper.createScene(mBrowseFrame, new Runnable() {
@Override
public void run() {
- showTitle(false);
+ TitleTransitionHelper.showTitle(mTitleView, false);
}
});
mSceneWithHeaders = sTransitionHelper.createScene(mBrowseFrame, new Runnable() {
@@ -617,10 +605,8 @@
showHeaders(false);
}
});
- mTitleUpTransition = sTransitionHelper.createChangeBounds(false);
- sTransitionHelper.setInterpolator(mTitleUpTransition, new DecelerateInterpolator(4));
- mTitleDownTransition = sTransitionHelper.createChangeBounds(false);
- sTransitionHelper.setInterpolator(mTitleDownTransition, new DecelerateInterpolator());
+ mTitleUpTransition = TitleTransitionHelper.createTransitionTitleUp(sTransitionHelper);
+ mTitleDownTransition = TitleTransitionHelper.createTransitionTitleDown(sTransitionHelper);
sTransitionHelper.excludeChildren(mTitleUpTransition, R.id.browse_headers, true);
sTransitionHelper.excludeChildren(mTitleDownTransition, R.id.browse_headers, true);
@@ -682,12 +668,6 @@
}
}
- private void showTitle(boolean show) {
- MarginLayoutParams lp = (MarginLayoutParams) mBrowseTitle.getLayoutParams();
- lp.topMargin = show ? 0 : -mBrowseTitle.getHeight();
- mBrowseTitle.setLayoutParams(lp);
- }
-
private void showHeaders(boolean show) {
if (DEBUG) Log.v(TAG, "showHeaders " + show);
mHeadersFragment.setHeadersEnabled(show);
@@ -834,21 +814,9 @@
public void setBadgeDrawable(Drawable drawable) {
if (mBadgeDrawable != drawable) {
mBadgeDrawable = drawable;
- setBadgeViewImage();
- }
- }
-
- private void setBadgeViewImage() {
- if (mBadgeView == null) {
- return;
- }
- mBadgeView.setImageDrawable(mBadgeDrawable);
- if (mBadgeDrawable != null) {
- mBadgeView.setVisibility(View.VISIBLE);
- mTitleView.setVisibility(View.GONE);
- } else {
- mBadgeView.setVisibility(View.GONE);
- mTitleView.setVisibility(View.VISIBLE);
+ if (mTitleView != null) {
+ mTitleView.setBadgeDrawable(drawable);
+ }
}
}
@@ -865,7 +833,7 @@
public void setTitle(String title) {
mTitle = title;
if (mTitleView != null) {
- mTitleView.setText(title);
+ mTitleView.setTitle(title);
}
}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/SearchFragment.java b/v17/leanback/src/android/support/v17/leanback/app/SearchFragment.java
index ce4faf3..998ca0d 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/SearchFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/SearchFragment.java
@@ -30,6 +30,8 @@
import android.widget.FrameLayout;
import android.support.v17.leanback.R;
+import java.util.List;
+
/**
* <p>A fragment to handle searches.</p>
*
@@ -293,6 +295,14 @@
return null;
}
+ /**
+ * Display the completions shown by the IME.
+ *
+ * @param completions list of completions shown in the IME, can be null or empty to clear them
+ */
+ public void displayCompletions(List<String> completions) {
+ mSearchBar.displayCompletions(completions);
+ }
private void retrieveResults(String searchQuery) {
if (DEBUG) Log.v(TAG, String.format("retrieveResults %s", searchQuery));
diff --git a/v17/leanback/src/android/support/v17/leanback/app/TitleTransitionHelper.java b/v17/leanback/src/android/support/v17/leanback/app/TitleTransitionHelper.java
new file mode 100644
index 0000000..288c9eb
--- /dev/null
+++ b/v17/leanback/src/android/support/v17/leanback/app/TitleTransitionHelper.java
@@ -0,0 +1,49 @@
+/*
+ * 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 android.support.v17.leanback.app;
+
+import android.support.v17.leanback.widget.TitleView;
+import android.view.ViewGroup.MarginLayoutParams;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
+
+class TitleTransitionHelper {
+
+ private static Interpolator createTransitionInterpolatorUp() {
+ return new DecelerateInterpolator(4);
+ }
+
+ private static Interpolator createTransitionInterpolatorDown() {
+ return new DecelerateInterpolator();
+ }
+
+ static public Object createTransitionTitleUp(TransitionHelper helper) {
+ Object transition = helper.createChangeBounds(false);
+ helper.setInterpolator(transition, createTransitionInterpolatorUp());
+ return transition;
+ }
+
+ static public Object createTransitionTitleDown(TransitionHelper helper) {
+ Object transition = helper.createChangeBounds(false);
+ helper.setInterpolator(transition, createTransitionInterpolatorDown());
+ return transition;
+ }
+
+ static public void showTitle(TitleView view, boolean show) {
+ MarginLayoutParams lp = (MarginLayoutParams) view.getLayoutParams();
+ lp.topMargin = show ? 0 : -view.getHeight();
+ view.setLayoutParams(lp);
+ }
+
+}
diff --git a/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java b/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java
index 8758381..1bee762 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java
@@ -15,6 +15,7 @@
import android.support.v17.leanback.R;
import android.support.v17.leanback.widget.Row;
+import android.support.v17.leanback.widget.TitleView;
import android.support.v17.leanback.widget.VerticalGridPresenter;
import android.support.v17.leanback.widget.ObjectAdapter;
import android.support.v17.leanback.widget.OnItemClickedListener;
@@ -55,15 +56,15 @@
private View.OnClickListener mExternalOnSearchClickedListener;
private int mSelectedPosition = -1;
- private ImageView mBadgeView;
- private TextView mTitleView;
- private ViewGroup mBrowseTitle;
- private SearchOrbView mSearchOrbView;
+ private TitleView mTitleView;
+ private int mSearchAffordanceColor;
+ private boolean mSearchAffordanceColorSet;
private boolean mShowingTitle = true;
// transition related
private static TransitionHelper sTransitionHelper = TransitionHelper.getInstance();
- private Object mTitleTransition;
+ private Object mTitleUpTransition;
+ private Object mTitleDownTransition;
private Object mSceneWithTitle;
private Object mSceneWithoutTitle;
@@ -127,7 +128,9 @@
public void setBadgeDrawable(Drawable drawable) {
if (drawable != mBadgeDrawable) {
mBadgeDrawable = drawable;
- setBadgeViewImage();
+ if (mTitleView != null) {
+ mTitleView.setBadgeDrawable(drawable);
+ }
}
}
@@ -144,7 +147,7 @@
public void setTitle(String title) {
mTitle = title;
if (mTitleView != null) {
- mTitleView.setText(mTitle);
+ mTitleView.setTitle(mTitle);
}
}
@@ -215,11 +218,11 @@
if (!mGridViewHolder.getGridView().hasPreviousViewInSameRow(position)) {
// if has no sibling in front of it, show title
if (!mShowingTitle) {
- sTransitionHelper.runTransition(mSceneWithTitle, mTitleTransition);
+ sTransitionHelper.runTransition(mSceneWithTitle, mTitleDownTransition);
mShowingTitle = true;
}
} else if (mShowingTitle) {
- sTransitionHelper.runTransition(mSceneWithoutTitle, mTitleTransition);
+ sTransitionHelper.runTransition(mSceneWithoutTitle, mTitleUpTransition);
mShowingTitle = false;
}
mSelectedPosition = position;
@@ -255,38 +258,50 @@
*/
public void setOnSearchClickedListener(View.OnClickListener listener) {
mExternalOnSearchClickedListener = listener;
- if (mSearchOrbView != null) {
- mSearchOrbView.setOnOrbClickedListener(listener);
+ if (mTitleView != null) {
+ mTitleView.setOnSearchClickedListener(listener);
}
}
- private void setBadgeViewImage() {
- if (mBadgeView == null) {
- return;
- }
- mBadgeView.setImageDrawable(mBadgeDrawable);
- if (mBadgeDrawable != null) {
- mBadgeView.setVisibility(View.VISIBLE);
- mTitleView.setVisibility(View.GONE);
- } else {
- mBadgeView.setVisibility(View.GONE);
- mTitleView.setVisibility(View.VISIBLE);
+ /**
+ * Sets the color used to draw the search affordance.
+ */
+ public void setSearchAffordanceColor(int color) {
+ mSearchAffordanceColor = color;
+ mSearchAffordanceColorSet = true;
+ if (mTitleView != null) {
+ mTitleView.setSearchAffordanceColor(mSearchAffordanceColor);
}
}
+ /**
+ * Returns the color used to draw the search affordance.
+ */
+ public int getSearchAffordanceColor() {
+ if (mSearchAffordanceColorSet) {
+ return mSearchAffordanceColor;
+ }
+ if (mTitleView == null) {
+ throw new IllegalStateException("Fragment views not yet created");
+ }
+ return mTitleView.getSearchAffordanceColor();
+ }
+
+
private final BrowseFrameLayout.OnFocusSearchListener mOnFocusSearchListener =
new BrowseFrameLayout.OnFocusSearchListener() {
@Override
public View onFocusSearch(View focused, int direction) {
if (DEBUG) Log.v(TAG, "onFocusSearch focused " + focused + " + direction " + direction);
- if (focused == mSearchOrbView && (
+ final View searchOrbView = mTitleView.getSearchAffordanceView();
+ if (focused == searchOrbView && (
direction == View.FOCUS_DOWN || direction == View.FOCUS_RIGHT)) {
return mGridViewHolder.view;
- } else if (focused != mSearchOrbView && mSearchOrbView.getVisibility() == View.VISIBLE
+ } else if (focused != searchOrbView && searchOrbView.getVisibility() == View.VISIBLE
&& direction == View.FOCUS_UP) {
- return mSearchOrbView;
+ return searchOrbView;
} else {
return null;
@@ -303,43 +318,34 @@
mBrowseFrame = (BrowseFrameLayout) root.findViewById(R.id.browse_frame);
mBrowseFrame.setOnFocusSearchListener(mOnFocusSearchListener);
- mBrowseTitle = (ViewGroup) root.findViewById(R.id.browse_title_group);
- mBadgeView = (ImageView) mBrowseTitle.findViewById(R.id.browse_badge);
- mTitleView = (TextView) mBrowseTitle.findViewById(R.id.browse_title);
- mSearchOrbView = (SearchOrbView) mBrowseTitle.findViewById(R.id.browse_orb);
- if (mExternalOnSearchClickedListener != null) {
- mSearchOrbView.setOnOrbClickedListener(mExternalOnSearchClickedListener);
+ mTitleView = (TitleView) root.findViewById(R.id.browse_title_group);
+ mTitleView.setBadgeDrawable(mBadgeDrawable);
+ mTitleView.setTitle(mTitle);
+ if (mSearchAffordanceColorSet) {
+ mTitleView.setSearchAffordanceColor(mSearchAffordanceColor);
}
-
- setBadgeViewImage();
- mTitleView.setText(mTitle);
+ if (mExternalOnSearchClickedListener != null) {
+ mTitleView.setOnSearchClickedListener(mExternalOnSearchClickedListener);
+ }
mSceneWithTitle = sTransitionHelper.createScene(root, new Runnable() {
@Override
public void run() {
- showTitle(true);
+ TitleTransitionHelper.showTitle(mTitleView, true);
}
});
mSceneWithoutTitle = sTransitionHelper.createScene(root, new Runnable() {
@Override
public void run() {
- showTitle(false);
+ TitleTransitionHelper.showTitle(mTitleView, false);
}
});
- mTitleTransition = sTransitionHelper.createTransitionSet(false);
- Object fade = sTransitionHelper.createFadeTransition(
- TransitionHelper.FADE_IN | TransitionHelper.FADE_OUT);
- Object changeBounds = sTransitionHelper.createChangeBounds(false);
- sTransitionHelper.addTransition(mTitleTransition, fade);
- sTransitionHelper.addTransition(mTitleTransition, changeBounds);
- sTransitionHelper.excludeChildren(mTitleTransition, R.id.browse_grid_dock, true);
- return root;
- }
+ mTitleUpTransition = TitleTransitionHelper.createTransitionTitleUp(sTransitionHelper);
+ mTitleDownTransition = TitleTransitionHelper.createTransitionTitleDown(sTransitionHelper);
+ sTransitionHelper.excludeChildren(mTitleUpTransition, R.id.browse_grid_dock, true);
+ sTransitionHelper.excludeChildren(mTitleDownTransition, R.id.browse_grid_dock, true);
- private void showTitle(boolean show) {
- MarginLayoutParams lp = (MarginLayoutParams) mBrowseTitle.getLayoutParams();
- lp.topMargin = show ? 0 : -mBrowseTitle.getHeight();
- mBrowseTitle.setLayoutParams(lp);
+ return root;
}
@Override
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/SearchBar.java b/v17/leanback/src/android/support/v17/leanback/widget/SearchBar.java
index 1d1728b..cf30f22 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/SearchBar.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/SearchBar.java
@@ -32,6 +32,7 @@
import android.util.Log;
import android.view.LayoutInflater;
import android.view.ViewGroup;
+import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.EditorInfo;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -43,6 +44,7 @@
import android.widget.TextView;
import java.util.ArrayList;
+import java.util.List;
/**
* <p>SearchBar is a search widget.</p>
@@ -348,6 +350,23 @@
return mBadgeDrawable;
}
+ /**
+ * Update the completion list shown by the IME
+ *
+ * @param completions list of completions shown in the IME, can be null or empty to clear them
+ */
+ public void displayCompletions(List<String> completions) {
+ List<CompletionInfo> infos = new ArrayList<CompletionInfo>();
+ if (null != completions) {
+ for (String completion : completions) {
+ infos.add(new CompletionInfo(infos.size(), infos.size(), completion));
+ }
+ }
+
+ mInputMethodManager.displayCompletions(mSearchTextEditor,
+ infos.toArray(new CompletionInfo[] {}));
+ }
+
private void hideNativeKeyboard() {
mInputMethodManager.hideSoftInputFromWindow(mSearchTextEditor.getWindowToken(),
InputMethodManager.RESULT_UNCHANGED_SHOWN);
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/SearchOrbView.java b/v17/leanback/src/android/support/v17/leanback/widget/SearchOrbView.java
index 86ad1c6..34c2026 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/SearchOrbView.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/SearchOrbView.java
@@ -150,4 +150,8 @@
enableOrbColorAnimation(true);
}
}
+
+ public int getOrbColor() {
+ return mSearchOrbColor;
+ }
}
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/TitleView.java b/v17/leanback/src/android/support/v17/leanback/widget/TitleView.java
new file mode 100644
index 0000000..d38e394
--- /dev/null
+++ b/v17/leanback/src/android/support/v17/leanback/widget/TitleView.java
@@ -0,0 +1,129 @@
+/*
+ * 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 android.support.v17.leanback.widget;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.support.v17.leanback.R;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup.MarginLayoutParams;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+/**
+ * Title view for a leanback fragment.
+ * @hide
+ */
+public class TitleView extends FrameLayout {
+
+ private ImageView mBadgeView;
+ private TextView mTextView;
+ private SearchOrbView mSearchOrbView;
+
+ public TitleView(Context context) {
+ this(context, null);
+ }
+
+ public TitleView(Context context, AttributeSet attrs) {
+ this(context, attrs, R.style.Widget_Leanback_Title);
+ }
+
+ public TitleView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ LayoutInflater inflater = LayoutInflater.from(context);
+ View rootView = inflater.inflate(R.layout.lb_title_view, this);
+
+ mBadgeView = (ImageView) rootView.findViewById(R.id.browse_badge);
+ mTextView = (TextView) rootView.findViewById(R.id.browse_title);
+ mSearchOrbView = (SearchOrbView) rootView.findViewById(R.id.browse_orb);
+
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.lbTitleView);
+ int color = a.getColor(R.styleable.lbTitleView_searchAffordanceColor, 0);
+ a.recycle();
+ mSearchOrbView.setOrbColor(color);
+
+ setClipToPadding(false);
+ setClipChildren(false);
+ }
+
+ /**
+ * Sets the title text.
+ */
+ public void setTitle(String titleText) {
+ mTextView.setText(titleText);
+ }
+
+ /**
+ * Returns the title text.
+ */
+ public CharSequence getTitle() {
+ return mTextView.getText();
+ }
+
+ /**
+ * Sets the badge drawable.
+ * If non-null, the drawable is displayed instead of the title text.
+ */
+ public void setBadgeDrawable(Drawable drawable) {
+ mBadgeView.setImageDrawable(drawable);
+ if (drawable != null) {
+ mBadgeView.setVisibility(View.VISIBLE);
+ mTextView.setVisibility(View.GONE);
+ } else {
+ mBadgeView.setVisibility(View.GONE);
+ mTextView.setVisibility(View.VISIBLE);
+ }
+ }
+
+ /**
+ * Returns the badge drawable.
+ */
+ public Drawable getBadgeDrawable() {
+ return mBadgeView.getDrawable();
+ }
+
+ /**
+ * Sets the listener to be called when the search affordance is clicked.
+ */
+ public void setOnSearchClickedListener(View.OnClickListener listener) {
+ mSearchOrbView.setOnOrbClickedListener(listener);
+ }
+
+ /**
+ * Returns the view for the search affordance.
+ */
+ public View getSearchAffordanceView() {
+ return mSearchOrbView;
+ }
+
+ /**
+ * Sets the color used to draw the search affordance.
+ */
+ public void setSearchAffordanceColor(int color) {
+ mSearchOrbView.setOrbColor(color);
+ }
+
+ /**
+ * Returns the color used to draw the search affordance.
+ */
+ public int getSearchAffordanceColor() {
+ return mSearchOrbView.getOrbColor();
+ }
+}