summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3/AppsContainerView.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/launcher3/AppsContainerView.java')
-rw-r--r--src/com/android/launcher3/AppsContainerView.java117
1 files changed, 103 insertions, 14 deletions
diff --git a/src/com/android/launcher3/AppsContainerView.java b/src/com/android/launcher3/AppsContainerView.java
index 5dac9f1e8..21dd7cbc4 100644
--- a/src/com/android/launcher3/AppsContainerView.java
+++ b/src/com/android/launcher3/AppsContainerView.java
@@ -26,12 +26,14 @@ import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.KeyEvent;
+import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
+import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
-import android.widget.EditText;
+import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.launcher3.util.Thunk;
@@ -44,11 +46,11 @@ import java.util.regex.Pattern;
* The all apps view container.
*/
public class AppsContainerView extends BaseContainerView implements DragSource, Insettable,
- TextWatcher, TextView.OnEditorActionListener, LauncherTransitionable, View.OnTouchListener,
- View.OnClickListener, View.OnLongClickListener {
+ TextWatcher, TextView.OnEditorActionListener, LauncherTransitionable,
+ AlphabeticalAppsList.FilterChangedCallback, AppsGridAdapter.PredictionBarSpacerCallbacks,
+ View.OnTouchListener, View.OnClickListener, View.OnLongClickListener {
public static final boolean GRID_MERGE_SECTIONS = true;
- public static final boolean GRID_HIDE_SECTION_HEADERS = false;
private static final boolean ALLOW_SINGLE_APP_LAUNCH = true;
private static final boolean DYNAMIC_HEADER_ELEVATION = true;
@@ -64,12 +66,14 @@ public class AppsContainerView extends BaseContainerView implements DragSource,
@Thunk Launcher mLauncher;
@Thunk AlphabeticalAppsList mApps;
+ private LayoutInflater mLayoutInflater;
private AppsGridAdapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
private RecyclerView.ItemDecoration mItemDecoration;
- private LinearLayout mContentView;
+ private FrameLayout mContentView;
@Thunk AppsContainerRecyclerView mAppsRecyclerView;
+ private ViewGroup mPredictionBarView;
private View mHeaderView;
private View mSearchBarContainerView;
private View mSearchButtonView;
@@ -77,11 +81,13 @@ public class AppsContainerView extends BaseContainerView implements DragSource,
private AppsContainerSearchEditTextView mSearchBarEditView;
private int mNumAppsPerRow;
+ private int mNumPredictedAppsPerRow;
private Point mLastTouchDownPos = new Point(-1, -1);
private Point mLastTouchPos = new Point();
private int mContentMarginStart;
// Normal container insets
private int mContainerInset;
+ private int mPredictionBarHeight;
// RecyclerView scroll position
@Thunk int mRecyclerViewScrollY;
@@ -101,12 +107,17 @@ public class AppsContainerView extends BaseContainerView implements DragSource,
mContainerInset = context.getResources().getDimensionPixelSize(
R.dimen.apps_container_inset);
+ mPredictionBarHeight = grid.allAppsCellHeightPx +
+ 2 * res.getDimensionPixelSize(R.dimen.apps_prediction_icon_top_bottom_padding);
mLauncher = (Launcher) context;
+ mLayoutInflater = LayoutInflater.from(context);
mNumAppsPerRow = grid.appsViewNumCols;
- mApps = new AlphabeticalAppsList(context, mNumAppsPerRow);
- mAdapter = new AppsGridAdapter(context, mApps, mNumAppsPerRow, this, mLauncher, this);
+ mNumPredictedAppsPerRow = grid.appsViewNumPredictiveCols;
+ mApps = new AlphabeticalAppsList(context, this, mNumAppsPerRow, mNumPredictedAppsPerRow);
+ mAdapter = new AppsGridAdapter(context, mApps, mNumAppsPerRow, this, this, mLauncher, this);
mAdapter.setEmptySearchText(res.getString(R.string.loading_apps_message));
mAdapter.setNumAppsPerRow(mNumAppsPerRow);
+ mAdapter.setPredictionRowHeight(mPredictionBarHeight);
mLayoutManager = mAdapter.getLayoutManager();
mItemDecoration = mAdapter.getItemDecoration();
mContentMarginStart = mAdapter.getContentMarginStart();
@@ -186,7 +197,7 @@ public class AppsContainerView extends BaseContainerView implements DragSource,
// Work around the search box getting first focus and showing the cursor by
// proxying the focus from the content view to the recycler view directly
- mContentView = (LinearLayout) findViewById(R.id.apps_list);
+ mContentView = (FrameLayout) findViewById(R.id.apps_list);
mContentView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
@@ -195,12 +206,20 @@ public class AppsContainerView extends BaseContainerView implements DragSource,
}
}
});
+
+ // Fix the header view elevation if not dynamically calculating it
mHeaderView = findViewById(R.id.header);
mHeaderView.setOnClickListener(this);
if (Utilities.isLmpOrAbove() && !DYNAMIC_HEADER_ELEVATION) {
mHeaderView.setElevation(DynamicGrid.pxFromDp(HEADER_ELEVATION_DP,
getContext().getResources().getDisplayMetrics()));
}
+
+ // Fix the prediction bar size
+ mPredictionBarView = (ViewGroup) findViewById(R.id.prediction_bar);
+ FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mPredictionBarView.getLayoutParams();
+ lp.height = mPredictionBarHeight;
+
mSearchButtonView = mHeaderView.findViewById(R.id.search_button);
mSearchBarContainerView = findViewById(R.id.app_search_container);
mDismissSearchButtonView = mSearchBarContainerView.findViewById(R.id.dismiss_search_button);
@@ -227,7 +246,8 @@ public class AppsContainerView extends BaseContainerView implements DragSource,
}
mAppsRecyclerView = (AppsContainerRecyclerView) findViewById(R.id.apps_list_view);
mAppsRecyclerView.setApps(mApps);
- mAppsRecyclerView.setNumAppsPerRow(mNumAppsPerRow);
+ mAppsRecyclerView.setNumAppsPerRow(mNumAppsPerRow, mNumPredictedAppsPerRow);
+ mAppsRecyclerView.setPredictionBarHeight(mPredictionBarHeight);
mAppsRecyclerView.setLayoutManager(mLayoutManager);
mAppsRecyclerView.setAdapter(mAdapter);
mAppsRecyclerView.setHasFixedSize(true);
@@ -247,15 +267,52 @@ public class AppsContainerView extends BaseContainerView implements DragSource,
}
@Override
+ public void onBindPredictionBar() {
+ if (!updatePredictionBarVisibility()) {
+ return;
+ }
+
+ List<AppInfo> predictedApps = mApps.getPredictedApps();
+ int childCount = mPredictionBarView.getChildCount();
+ for (int i = 0; i < mNumPredictedAppsPerRow; i++) {
+ BubbleTextView icon;
+ if (i < childCount) {
+ // If a child at that index exists, then get that child
+ icon = (BubbleTextView) mPredictionBarView.getChildAt(i);
+ } else {
+ // Otherwise, inflate a new icon
+ icon = (BubbleTextView) mLayoutInflater.inflate(
+ R.layout.apps_prediction_bar_icon_view, mPredictionBarView, false);
+ icon.setOnTouchListener(this);
+ icon.setOnClickListener(mLauncher);
+ icon.setOnLongClickListener(this);
+ icon.setFocusable(true);
+ mPredictionBarView.addView(icon);
+ }
+
+ // Either apply the app info to the child, or hide the view
+ if (i < predictedApps.size()) {
+ if (icon.getVisibility() != View.VISIBLE) {
+ icon.setVisibility(View.VISIBLE);
+ }
+ icon.applyFromApplicationInfo(predictedApps.get(i));
+ } else {
+ icon.setVisibility(View.INVISIBLE);
+ }
+ }
+ }
+
+ @Override
protected void onFixedBoundsUpdated() {
// Update the number of items in the grid
LauncherAppState app = LauncherAppState.getInstance();
DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
if (grid.updateAppsViewNumCols(getContext().getResources(), mFixedBounds.width())) {
mNumAppsPerRow = grid.appsViewNumCols;
- mAppsRecyclerView.setNumAppsPerRow(mNumAppsPerRow);
+ mNumPredictedAppsPerRow = grid.appsViewNumPredictiveCols;
+ mAppsRecyclerView.setNumAppsPerRow(mNumAppsPerRow, mNumPredictedAppsPerRow);
mAdapter.setNumAppsPerRow(mNumAppsPerRow);
- mApps.setNumAppsPerRow(mNumAppsPerRow);
+ mApps.setNumAppsPerRow(mNumAppsPerRow, mNumPredictedAppsPerRow);
}
}
@@ -297,10 +354,16 @@ public class AppsContainerView extends BaseContainerView implements DragSource,
// Update the header bar
if (hasSearchBar) {
- LinearLayout.LayoutParams lp =
- (LinearLayout.LayoutParams) mHeaderView.getLayoutParams();
+ FrameLayout.LayoutParams lp =
+ (FrameLayout.LayoutParams) mHeaderView.getLayoutParams();
lp.leftMargin = lp.rightMargin = inset;
+ mHeaderView.requestLayout();
}
+
+ FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mPredictionBarView.getLayoutParams();
+ lp.leftMargin = inset + mAppsRecyclerView.getScrollbarWidth();
+ lp.rightMargin = inset + mAppsRecyclerView.getScrollbarWidth();
+ mPredictionBarView.requestLayout();
}
/**
@@ -499,7 +562,7 @@ public class AppsContainerView extends BaseContainerView implements DragSource,
List<AlphabeticalAppsList.AdapterItem> items = mApps.getAdapterItems();
for (int i = 0; i < items.size(); i++) {
AlphabeticalAppsList.AdapterItem item = items.get(i);
- if (!item.isSectionHeader) {
+ if (item.viewType == AppsGridAdapter.ICON_VIEW_TYPE) {
mAppsRecyclerView.getChildAt(i).performClick();
getInputMethodManager().hideSoftInputFromWindow(getWindowToken(), 0);
return true;
@@ -510,6 +573,11 @@ public class AppsContainerView extends BaseContainerView implements DragSource,
}
@Override
+ public void onFilterChanged() {
+ updatePredictionBarVisibility();
+ }
+
+ @Override
public View getContent() {
return null;
}
@@ -554,6 +622,12 @@ public class AppsContainerView extends BaseContainerView implements DragSource,
mHeaderView.setElevation(newElevation);
}
}
+
+ // XXX: Optimize this, stop once we are out of bounds
+ if (mRecyclerViewScrollY < 0) {
+ new Throwable().printStackTrace();
+ }
+ mPredictionBarView.setTranslationY(-mRecyclerViewScrollY + mAppsRecyclerView.getPaddingTop());
}
/**
@@ -683,6 +757,21 @@ public class AppsContainerView extends BaseContainerView implements DragSource,
}
/**
+ * Updates the visibility of the prediction bar.
+ * @return whether the prediction bar is visible
+ */
+ private boolean updatePredictionBarVisibility() {
+ boolean showPredictionBar = !mApps.getPredictedApps().isEmpty() && (!mApps.hasFilter() ||
+ mSearchBarEditView.getEditableText().toString().isEmpty());
+ if (showPredictionBar) {
+ mPredictionBarView.setVisibility(View.VISIBLE);
+ } else if (!showPredictionBar) {
+ mPredictionBarView.setVisibility(View.INVISIBLE);
+ }
+ return showPredictionBar;
+ }
+
+ /**
* Returns an input method manager.
*/
private InputMethodManager getInputMethodManager() {