• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.documentsui.dirlist;
18 
19 import android.content.Context;
20 import android.database.Cursor;
21 import android.support.v7.widget.RecyclerView;
22 import android.view.KeyEvent;
23 import android.view.LayoutInflater;
24 import android.view.MotionEvent;
25 import android.view.View;
26 import android.view.ViewGroup;
27 import android.view.ViewPropertyAnimator;
28 import android.widget.ImageView;
29 
30 import com.android.documentsui.base.Shared;
31 import com.android.documentsui.selection.ItemDetailsLookup.ItemDetails;
32 
33 import javax.annotation.Nullable;
34 
35 public abstract class DocumentHolder
36         extends RecyclerView.ViewHolder implements View.OnKeyListener {
37 
38     static final float DISABLED_ALPHA = 0.3f;
39 
40     protected final Context mContext;
41 
42     protected @Nullable String mModelId;
43 
44     // See #addKeyEventListener for details on the need for this field.
45     private KeyboardEventListener mKeyEventListener;
46 
47     private final DocumentItemDetails mDetails;
48 
DocumentHolder(Context context, ViewGroup parent, int layout)49     public DocumentHolder(Context context, ViewGroup parent, int layout) {
50         this(context, inflateLayout(context, parent, layout));
51     }
52 
DocumentHolder(Context context, View item)53     public DocumentHolder(Context context, View item) {
54         super(item);
55 
56         itemView.setOnKeyListener(this);
57 
58         mContext = context;
59         mDetails = new DocumentItemDetails();
60     }
61 
62     /**
63      * Binds the view to the given item data.
64      * @param cursor
65      * @param modelId
66      * @param state
67      */
bind(Cursor cursor, String modelId)68     public abstract void bind(Cursor cursor, String modelId);
69 
getModelId()70     public String getModelId() {
71         return mModelId;
72     }
73 
74     /**
75      * Makes the associated item view appear selected. Note that this merely affects the appearance
76      * of the view, it doesn't actually select the item.
77      * TODO: Use the DirectoryItemAnimator instead of manually controlling animation using a boolean
78      * flag.
79      *
80      * @param selected
81      * @param animate Whether or not to animate the change. Only selection changes initiated by the
82      *            selection manager should be animated. See
83      *            {@link ModelBackedDocumentsAdapter#onBindViewHolder(DocumentHolder, int, java.util.List)}
84      */
setSelected(boolean selected, boolean animate)85     public void setSelected(boolean selected, boolean animate) {
86         itemView.setActivated(selected);
87         itemView.setSelected(selected);
88     }
89 
setEnabled(boolean enabled)90     public void setEnabled(boolean enabled) {
91         setEnabledRecursive(itemView, enabled);
92     }
93 
94     @Override
onKey(View v, int keyCode, KeyEvent event)95     public boolean onKey(View v, int keyCode, KeyEvent event) {
96         assert(mKeyEventListener != null);
97         ItemDetails details = getItemDetails();
98         return (details == null)
99             ? false
100             : mKeyEventListener.onKey(getItemDetails(),  keyCode,  event);
101     }
102 
103     /**
104      * Installs a delegate to receive keyboard input events. This arrangement is necessitated
105      * by the fact that a single listener cannot listen to all keyboard events
106      * on RecyclerView (our parent view). Not sure why this is, but have been
107      * assured it is the case.
108      *
109      * <p>Ideally we'd not involve DocumentHolder in propagation of events like this.
110      */
addKeyEventListener(KeyboardEventListener listener)111     public void addKeyEventListener(KeyboardEventListener listener) {
112         assert(mKeyEventListener == null);
113         mKeyEventListener = listener;
114     }
115 
inDragRegion(MotionEvent event)116     public boolean inDragRegion(MotionEvent event) {
117         return false;
118     }
119 
inSelectRegion(MotionEvent event)120     public boolean inSelectRegion(MotionEvent event) {
121         return false;
122     }
123 
getItemDetails()124     public ItemDetails getItemDetails() {
125         return mDetails;
126     }
127 
setEnabledRecursive(View itemView, boolean enabled)128     static void setEnabledRecursive(View itemView, boolean enabled) {
129         if (itemView == null || itemView.isEnabled() == enabled) {
130             return;
131         }
132         itemView.setEnabled(enabled);
133 
134         if (itemView instanceof ViewGroup) {
135             final ViewGroup vg = (ViewGroup) itemView;
136             for (int i = vg.getChildCount() - 1; i >= 0; i--) {
137                 setEnabledRecursive(vg.getChildAt(i), enabled);
138             }
139         }
140     }
141 
142     @SuppressWarnings("TypeParameterUnusedInFormals")
inflateLayout(Context context, ViewGroup parent, int layout)143     private static <V extends View> V inflateLayout(Context context, ViewGroup parent, int layout) {
144         final LayoutInflater inflater = LayoutInflater.from(context);
145         return (V) inflater.inflate(layout, parent, false);
146     }
147 
fade(ImageView view, float alpha)148     static ViewPropertyAnimator fade(ImageView view, float alpha) {
149         return view.animate().setDuration(Shared.CHECK_ANIMATION_DURATION).alpha(alpha);
150     }
151 
152     private final class DocumentItemDetails extends ItemDetails {
153 
154         @Override
getPosition()155         public int getPosition() {
156             return DocumentHolder.this.getAdapterPosition();
157         }
158 
159         @Override
getStableId()160         public String getStableId() {
161             return DocumentHolder.this.getModelId();
162         }
163 
164         @Override
getItemViewType()165         public int getItemViewType() {
166             return DocumentHolder.this.getItemViewType();
167         }
168 
169         @Override
inDragRegion(MotionEvent e)170         public boolean inDragRegion(MotionEvent e) {
171             return DocumentHolder.this.inDragRegion(e);
172         }
173 
174         @Override
inSelectionHotspot(MotionEvent e)175         public boolean inSelectionHotspot(MotionEvent e) {
176             return DocumentHolder.this.inSelectRegion(e);
177         }
178     }
179 }
180