Loading packages/DocumentsUI/res/color/item_doc_list_background_activated.xml +0 −4 Original line number Diff line number Diff line Loading @@ -15,10 +15,6 @@ --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_focused="true" android:color="@color/platform_blue_a200" android:alpha="0.1" /> <item android:state_activated="true" android:color="?android:attr/colorAccent" Loading packages/DocumentsUI/res/layout-sw720dp-land/item_doc_list.xml +9 −3 Original line number Diff line number Diff line Loading @@ -14,10 +14,16 @@ limitations under the License. --> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <com.android.documentsui.ListItem xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/item_doc_list_background"> android:background="@drawable/item_doc_list_background" android:orientation="horizontal"> <View android:id="@+id/focus_indicator" android:layout_width="4dp" android:layout_height="match_parent" /> <LinearLayout android:layout_width="match_parent" Loading Loading @@ -121,4 +127,4 @@ </LinearLayout> </FrameLayout> </com.android.documentsui.ListItem> packages/DocumentsUI/res/layout/item_doc_list.xml +9 −3 Original line number Diff line number Diff line Loading @@ -14,10 +14,16 @@ limitations under the License. --> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <com.android.documentsui.DocListItem xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/item_doc_list_background"> android:background="@drawable/item_doc_list_background" android:orientation="horizontal"> <View android:id="@+id/focus_indicator" android:layout_width="4dp" android:layout_height="match_parent" /> <LinearLayout android:layout_width="match_parent" Loading Loading @@ -131,4 +137,4 @@ </LinearLayout> </FrameLayout> </com.android.documentsui.DocListItem> packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java +68 −9 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ import android.support.v7.widget.RecyclerView.LayoutManager; import android.support.v7.widget.RecyclerView.OnItemTouchListener; import android.support.v7.widget.RecyclerView.RecyclerListener; import android.support.v7.widget.RecyclerView.ViewHolder; import android.support.v7.widget.SimpleItemAnimator; import android.text.TextUtils; import android.text.format.DateUtils; import android.text.format.Formatter; Loading @@ -79,12 +80,12 @@ import android.util.TypedValue; import android.view.ActionMode; import android.view.DragEvent; import android.view.GestureDetector; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.View.OnLayoutChangeListener; import android.view.ViewGroup; import android.view.ViewParent; import android.widget.ImageView; Loading Loading @@ -134,6 +135,7 @@ public class DirectoryFragment extends Fragment { private Model mModel; private MultiSelectManager mSelectionManager; private Model.UpdateListener mModelUpdateListener = new ModelUpdateListener(); private ItemClickListener mItemClickListener = new ItemClickListener(); private View mEmptyView; private RecyclerView mRecView; Loading Loading @@ -238,7 +240,7 @@ public class DirectoryFragment extends Fragment { // TODO: Rather than update columns on layout changes, push this // code (or something like it) into GridLayoutManager. mRecView.addOnLayoutChangeListener( new OnLayoutChangeListener() { new View.OnLayoutChangeListener() { @Override public void onLayoutChange( Loading @@ -251,6 +253,9 @@ public class DirectoryFragment extends Fragment { } }); // TODO: Restore transition animations. See b/24802917. ((SimpleItemAnimator) mRecView.getItemAnimator()).setSupportsChangeAnimations(false); // TODO: Add a divider between views (which might use RecyclerView.ItemDecoration). if (DEBUG_ENABLE_DND) { setupDragAndDropOnDirectoryView(mRecView); Loading Loading @@ -450,7 +455,10 @@ public class DirectoryFragment extends Fragment { } private boolean onSingleTapUp(MotionEvent e) { if (Events.isTouchEvent(e) && mSelectionManager.getSelection().isEmpty()) { // Only respond to touch events. Single-click mouse events are selection events and are // handled by the selection manager. Tap events that occur while the selection manager is // active are also selection events. if (Events.isTouchEvent(e) && !mSelectionManager.hasSelection()) { int position = getEventAdapterPosition(e); if (position != RecyclerView.NO_POSITION) { return handleViewItem(position); Loading Loading @@ -825,7 +833,7 @@ public class DirectoryFragment extends Fragment { Snackbars.makeSnackbar(activity, message, Snackbar.LENGTH_LONG) .setAction( R.string.undo, new android.view.View.OnClickListener() { new View.OnClickListener() { @Override public void onClick(View view) {} }) Loading Loading @@ -889,10 +897,16 @@ public class DirectoryFragment extends Fragment { // Provide a reference to the views for each data item // Complex data items may need more than one view per item, and // you provide access to all the views for a data item in a view holder private static final class DocumentHolder extends RecyclerView.ViewHolder { private static final class DocumentHolder extends RecyclerView.ViewHolder implements View.OnKeyListener { // each data item is just a string in this case public View view; public String docId; // The stable document id. private ClickListener mClickListener; private View.OnKeyListener mKeyListener; public DocumentHolder(View view) { super(view); this.view = view; Loading @@ -900,6 +914,38 @@ public class DirectoryFragment extends Fragment { // So we set it here. Note that touch mode focus is a separate issue - see // View.setFocusableInTouchMode and View.isInTouchMode for more info. this.view.setFocusable(true); this.view.setOnKeyListener(this); } @Override public boolean onKey(View v, int keyCode, KeyEvent event) { // Intercept enter key-up events, and treat them as clicks. Forward other events. if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_ENTER) { if (mClickListener != null) { mClickListener.onClick(this); } return true; } else if (mKeyListener != null) { return mKeyListener.onKey(v, keyCode, event); } return false; } public void addClickListener(ClickListener listener) { // Just handle one for now; switch to a list if necessary. checkState(mClickListener == null); mClickListener = listener; } public void addOnKeyListener(View.OnKeyListener listener) { // Just handle one for now; switch to a list if necessary. checkState(mKeyListener == null); mKeyListener = listener; } interface ClickListener { public void onClick(DocumentHolder doc); } } Loading Loading @@ -952,10 +998,11 @@ public class DirectoryFragment extends Fragment { default: throw new IllegalStateException("Unsupported layout mode."); } // Key event bubbling doesn't work properly, so instead of setting one key listener on // the RecyclerView, we have to set it on each Item. See b/24865023. item.setOnKeyListener(mSelectionManager); return new DocumentHolder(item); DocumentHolder holder = new DocumentHolder(item); holder.addClickListener(mItemClickListener); holder.addOnKeyListener(mSelectionManager); return holder; } @Override Loading Loading @@ -1957,6 +2004,18 @@ public class DirectoryFragment extends Fragment { } } private class ItemClickListener implements DocumentHolder.ClickListener { @Override public void onClick(DocumentHolder doc) { final int position = doc.getAdapterPosition(); if (mSelectionManager.hasSelection()) { mSelectionManager.toggleSelection(position); } else { handleViewItem(position); } } } private class ModelUpdateListener extends Model.UpdateListener { @Override public void onModelUpdate(Model model) { Loading packages/DocumentsUI/src/com/android/documentsui/ListItem.java 0 → 100644 +52 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.documentsui; import android.content.Context; import android.graphics.Rect; import android.util.AttributeSet; import android.util.TypedValue; import android.view.View; import android.widget.LinearLayout; /** * Layout for a single item in List mode. This class overrides the default focus listener in order * to light up a focus indicator when it is focused. */ public class ListItem extends LinearLayout { public ListItem(Context context) { super(context); } public ListItem(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) { View indicator = findViewById(R.id.focus_indicator); if (gainFocus) { TypedValue color = new TypedValue(); getContext().getTheme().resolveAttribute(android.R.attr.colorAccent, color, true); indicator.setBackgroundColor(color.data); } else { indicator.setBackgroundColor(android.R.color.transparent); } super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); } } Loading
packages/DocumentsUI/res/color/item_doc_list_background_activated.xml +0 −4 Original line number Diff line number Diff line Loading @@ -15,10 +15,6 @@ --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_focused="true" android:color="@color/platform_blue_a200" android:alpha="0.1" /> <item android:state_activated="true" android:color="?android:attr/colorAccent" Loading
packages/DocumentsUI/res/layout-sw720dp-land/item_doc_list.xml +9 −3 Original line number Diff line number Diff line Loading @@ -14,10 +14,16 @@ limitations under the License. --> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <com.android.documentsui.ListItem xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/item_doc_list_background"> android:background="@drawable/item_doc_list_background" android:orientation="horizontal"> <View android:id="@+id/focus_indicator" android:layout_width="4dp" android:layout_height="match_parent" /> <LinearLayout android:layout_width="match_parent" Loading Loading @@ -121,4 +127,4 @@ </LinearLayout> </FrameLayout> </com.android.documentsui.ListItem>
packages/DocumentsUI/res/layout/item_doc_list.xml +9 −3 Original line number Diff line number Diff line Loading @@ -14,10 +14,16 @@ limitations under the License. --> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <com.android.documentsui.DocListItem xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/item_doc_list_background"> android:background="@drawable/item_doc_list_background" android:orientation="horizontal"> <View android:id="@+id/focus_indicator" android:layout_width="4dp" android:layout_height="match_parent" /> <LinearLayout android:layout_width="match_parent" Loading Loading @@ -131,4 +137,4 @@ </LinearLayout> </FrameLayout> </com.android.documentsui.DocListItem>
packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java +68 −9 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ import android.support.v7.widget.RecyclerView.LayoutManager; import android.support.v7.widget.RecyclerView.OnItemTouchListener; import android.support.v7.widget.RecyclerView.RecyclerListener; import android.support.v7.widget.RecyclerView.ViewHolder; import android.support.v7.widget.SimpleItemAnimator; import android.text.TextUtils; import android.text.format.DateUtils; import android.text.format.Formatter; Loading @@ -79,12 +80,12 @@ import android.util.TypedValue; import android.view.ActionMode; import android.view.DragEvent; import android.view.GestureDetector; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.View.OnLayoutChangeListener; import android.view.ViewGroup; import android.view.ViewParent; import android.widget.ImageView; Loading Loading @@ -134,6 +135,7 @@ public class DirectoryFragment extends Fragment { private Model mModel; private MultiSelectManager mSelectionManager; private Model.UpdateListener mModelUpdateListener = new ModelUpdateListener(); private ItemClickListener mItemClickListener = new ItemClickListener(); private View mEmptyView; private RecyclerView mRecView; Loading Loading @@ -238,7 +240,7 @@ public class DirectoryFragment extends Fragment { // TODO: Rather than update columns on layout changes, push this // code (or something like it) into GridLayoutManager. mRecView.addOnLayoutChangeListener( new OnLayoutChangeListener() { new View.OnLayoutChangeListener() { @Override public void onLayoutChange( Loading @@ -251,6 +253,9 @@ public class DirectoryFragment extends Fragment { } }); // TODO: Restore transition animations. See b/24802917. ((SimpleItemAnimator) mRecView.getItemAnimator()).setSupportsChangeAnimations(false); // TODO: Add a divider between views (which might use RecyclerView.ItemDecoration). if (DEBUG_ENABLE_DND) { setupDragAndDropOnDirectoryView(mRecView); Loading Loading @@ -450,7 +455,10 @@ public class DirectoryFragment extends Fragment { } private boolean onSingleTapUp(MotionEvent e) { if (Events.isTouchEvent(e) && mSelectionManager.getSelection().isEmpty()) { // Only respond to touch events. Single-click mouse events are selection events and are // handled by the selection manager. Tap events that occur while the selection manager is // active are also selection events. if (Events.isTouchEvent(e) && !mSelectionManager.hasSelection()) { int position = getEventAdapterPosition(e); if (position != RecyclerView.NO_POSITION) { return handleViewItem(position); Loading Loading @@ -825,7 +833,7 @@ public class DirectoryFragment extends Fragment { Snackbars.makeSnackbar(activity, message, Snackbar.LENGTH_LONG) .setAction( R.string.undo, new android.view.View.OnClickListener() { new View.OnClickListener() { @Override public void onClick(View view) {} }) Loading Loading @@ -889,10 +897,16 @@ public class DirectoryFragment extends Fragment { // Provide a reference to the views for each data item // Complex data items may need more than one view per item, and // you provide access to all the views for a data item in a view holder private static final class DocumentHolder extends RecyclerView.ViewHolder { private static final class DocumentHolder extends RecyclerView.ViewHolder implements View.OnKeyListener { // each data item is just a string in this case public View view; public String docId; // The stable document id. private ClickListener mClickListener; private View.OnKeyListener mKeyListener; public DocumentHolder(View view) { super(view); this.view = view; Loading @@ -900,6 +914,38 @@ public class DirectoryFragment extends Fragment { // So we set it here. Note that touch mode focus is a separate issue - see // View.setFocusableInTouchMode and View.isInTouchMode for more info. this.view.setFocusable(true); this.view.setOnKeyListener(this); } @Override public boolean onKey(View v, int keyCode, KeyEvent event) { // Intercept enter key-up events, and treat them as clicks. Forward other events. if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_ENTER) { if (mClickListener != null) { mClickListener.onClick(this); } return true; } else if (mKeyListener != null) { return mKeyListener.onKey(v, keyCode, event); } return false; } public void addClickListener(ClickListener listener) { // Just handle one for now; switch to a list if necessary. checkState(mClickListener == null); mClickListener = listener; } public void addOnKeyListener(View.OnKeyListener listener) { // Just handle one for now; switch to a list if necessary. checkState(mKeyListener == null); mKeyListener = listener; } interface ClickListener { public void onClick(DocumentHolder doc); } } Loading Loading @@ -952,10 +998,11 @@ public class DirectoryFragment extends Fragment { default: throw new IllegalStateException("Unsupported layout mode."); } // Key event bubbling doesn't work properly, so instead of setting one key listener on // the RecyclerView, we have to set it on each Item. See b/24865023. item.setOnKeyListener(mSelectionManager); return new DocumentHolder(item); DocumentHolder holder = new DocumentHolder(item); holder.addClickListener(mItemClickListener); holder.addOnKeyListener(mSelectionManager); return holder; } @Override Loading Loading @@ -1957,6 +2004,18 @@ public class DirectoryFragment extends Fragment { } } private class ItemClickListener implements DocumentHolder.ClickListener { @Override public void onClick(DocumentHolder doc) { final int position = doc.getAdapterPosition(); if (mSelectionManager.hasSelection()) { mSelectionManager.toggleSelection(position); } else { handleViewItem(position); } } } private class ModelUpdateListener extends Model.UpdateListener { @Override public void onModelUpdate(Model model) { Loading
packages/DocumentsUI/src/com/android/documentsui/ListItem.java 0 → 100644 +52 −0 Original line number Diff line number Diff line /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.documentsui; import android.content.Context; import android.graphics.Rect; import android.util.AttributeSet; import android.util.TypedValue; import android.view.View; import android.widget.LinearLayout; /** * Layout for a single item in List mode. This class overrides the default focus listener in order * to light up a focus indicator when it is focused. */ public class ListItem extends LinearLayout { public ListItem(Context context) { super(context); } public ListItem(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) { View indicator = findViewById(R.id.focus_indicator); if (gainFocus) { TypedValue color = new TypedValue(); getContext().getTheme().resolveAttribute(android.R.attr.colorAccent, color, true); indicator.setBackgroundColor(color.data); } else { indicator.setBackgroundColor(android.R.color.transparent); } super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); } }