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 static com.android.documentsui.base.DocumentInfo.getCursorString; 20 21 import android.content.Context; 22 import android.database.Cursor; 23 import android.graphics.Rect; 24 import android.text.format.Formatter; 25 import android.view.View; 26 import android.view.ViewGroup; 27 import android.widget.ImageView; 28 import android.widget.LinearLayout; 29 import android.widget.TextView; 30 31 import com.android.documentsui.R; 32 import com.android.documentsui.base.DocumentInfo; 33 import com.android.documentsui.base.Events.InputEvent; 34 import com.android.documentsui.base.Shared; 35 import com.android.documentsui.roots.RootCursorWrapper; 36 37 final class ListDocumentHolder extends DocumentHolder { 38 39 private final TextView mTitle; 40 private final LinearLayout mDetails; // Container of date/size/summary 41 private final TextView mDate; 42 private final TextView mSize; 43 private final TextView mSummary; 44 private final ImageView mIconMime; 45 private final ImageView mIconThumb; 46 private final ImageView mIconCheck; 47 private final IconHelper mIconHelper; 48 private final View mIconLayout; 49 // This is used in as a convenience in our bind method. 50 private final DocumentInfo mDoc; 51 ListDocumentHolder(Context context, ViewGroup parent, IconHelper iconHelper)52 public ListDocumentHolder(Context context, ViewGroup parent, IconHelper iconHelper) { 53 super(context, parent, R.layout.item_doc_list); 54 55 mIconLayout = itemView.findViewById(android.R.id.icon); 56 mIconMime = (ImageView) itemView.findViewById(R.id.icon_mime); 57 mIconThumb = (ImageView) itemView.findViewById(R.id.icon_thumb); 58 mIconCheck = (ImageView) itemView.findViewById(R.id.icon_check); 59 mTitle = (TextView) itemView.findViewById(android.R.id.title); 60 mSummary = (TextView) itemView.findViewById(android.R.id.summary); 61 mSize = (TextView) itemView.findViewById(R.id.size); 62 mDate = (TextView) itemView.findViewById(R.id.date); 63 // Warning: mDetails view doesn't exists in layout-sw720dp-land layout 64 mDetails = (LinearLayout) itemView.findViewById(R.id.line2); 65 66 mIconHelper = iconHelper; 67 mDoc = new DocumentInfo(); 68 } 69 70 @Override setSelected(boolean selected, boolean animate)71 public void setSelected(boolean selected, boolean animate) { 72 // We always want to make sure our check box disappears if we're not selected, 73 // even if the item is disabled. But it should be an error (see assert below) 74 // to be set to selected && be disabled. 75 float checkAlpha = selected ? 1f : 0f; 76 if (animate) { 77 fade(mIconCheck, checkAlpha).start(); 78 } else { 79 mIconCheck.setAlpha(checkAlpha); 80 } 81 82 if (!itemView.isEnabled()) { 83 assert(!selected); 84 return; 85 } 86 87 super.setSelected(selected, animate); 88 89 if (animate) { 90 fade(mIconMime, 1f - checkAlpha).start(); 91 fade(mIconThumb, 1f - checkAlpha).start(); 92 } else { 93 mIconMime.setAlpha(1f - checkAlpha); 94 mIconThumb.setAlpha(1f - checkAlpha); 95 } 96 } 97 98 @Override setEnabled(boolean enabled)99 public void setEnabled(boolean enabled) { 100 super.setEnabled(enabled); 101 102 // Text colors enabled/disabled is handle via a color set. 103 final float imgAlpha = enabled ? 1f : DISABLED_ALPHA; 104 mIconMime.setAlpha(imgAlpha); 105 mIconThumb.setAlpha(imgAlpha); 106 } 107 108 @Override isInDragHotspot(InputEvent event)109 public boolean isInDragHotspot(InputEvent event) { 110 // If itemView is activated = selected, then whole region is interactive 111 if (itemView.isActivated()) { 112 return true; 113 } 114 115 // Do everything in global coordinates - it makes things simpler. 116 int[] coords = new int[2]; 117 mIconLayout.getLocationOnScreen(coords); 118 119 Rect textBounds = new Rect(); 120 mTitle.getPaint().getTextBounds( 121 mTitle.getText().toString(), 0, mTitle.getText().length(), textBounds); 122 123 Rect rect = new Rect( 124 coords[0], 125 coords[1], 126 coords[0] + mIconLayout.getWidth() + textBounds.width(), 127 coords[1] + Math.max(mIconLayout.getHeight(), textBounds.height())); 128 129 // If the tap occurred inside icon or the text, these are interactive spots. 130 return rect.contains((int) event.getRawX(), (int) event.getRawY()); 131 } 132 133 /** 134 * Bind this view to the given document for display. 135 * @param cursor Pointing to the item to be bound. 136 * @param modelId The model ID of the item. 137 * @param state Current display state. 138 */ 139 @Override bind(Cursor cursor, String modelId)140 public void bind(Cursor cursor, String modelId) { 141 assert(cursor != null); 142 143 mModelId = modelId; 144 145 mDoc.updateFromCursor(cursor, getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY)); 146 147 mIconHelper.stopLoading(mIconThumb); 148 149 mIconMime.animate().cancel(); 150 mIconMime.setAlpha(1f); 151 mIconThumb.animate().cancel(); 152 mIconThumb.setAlpha(0f); 153 154 mIconHelper.load(mDoc, mIconThumb, mIconMime, null); 155 156 mTitle.setText(mDoc.displayName, TextView.BufferType.SPANNABLE); 157 mTitle.setVisibility(View.VISIBLE); 158 159 160 boolean hasDetails = false; 161 if (mDoc.isDirectory()) { 162 // Note, we don't show any details for any directory...ever. 163 hasDetails = false; 164 } else { 165 if (mDoc.summary != null) { 166 hasDetails = true; 167 mSummary.setText(mDoc.summary); 168 mSummary.setVisibility(View.VISIBLE); 169 } else { 170 mSummary.setVisibility(View.INVISIBLE); 171 } 172 173 if (mDoc.lastModified > 0) { 174 hasDetails = true; 175 mDate.setText(Shared.formatTime(mContext, mDoc.lastModified)); 176 } else { 177 mDate.setText(null); 178 } 179 180 if (mDoc.size > -1) { 181 hasDetails = true; 182 mSize.setVisibility(View.VISIBLE); 183 mSize.setText(Formatter.formatFileSize(mContext, mDoc.size)); 184 } else { 185 mSize.setVisibility(View.GONE); 186 } 187 } 188 189 // mDetails view doesn't exists in layout-sw720dp-land layout 190 if (mDetails != null) { 191 mDetails.setVisibility(hasDetails ? View.VISIBLE : View.GONE); 192 } 193 194 // TODO: Add document debug info 195 // Call includeDebugInfo 196 } 197 } 198