RecentsCreateFragment.java revision 6efba22ce510352bb84910d6efc42fecafd31ed7
1b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey/* 2b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey * Copyright (C) 2013 The Android Open Source Project 3b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey * 4b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 5b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey * you may not use this file except in compliance with the License. 6b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey * You may obtain a copy of the License at 7b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey * 8b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 9b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey * 10b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey * Unless required by applicable law or agreed to in writing, software 11b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 12b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey * See the License for the specific language governing permissions and 14b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey * limitations under the License. 15b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey */ 16b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 17b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeypackage com.android.documentsui; 18b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 190c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkeyimport static com.android.documentsui.DocumentsActivity.TAG; 200c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey 21b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport android.app.Fragment; 22b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport android.app.FragmentManager; 23b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport android.app.FragmentTransaction; 24b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport android.app.LoaderManager.LoaderCallbacks; 25b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport android.content.ContentResolver; 26b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport android.content.Context; 27b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport android.content.Loader; 28b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport android.database.Cursor; 293f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkeyimport android.graphics.drawable.Drawable; 30b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport android.net.Uri; 31b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport android.os.Bundle; 32b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport android.os.CancellationSignal; 333f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkeyimport android.text.Spannable; 343f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkeyimport android.text.SpannableStringBuilder; 35b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport android.text.TextUtils.TruncateAt; 363f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkeyimport android.text.style.ImageSpan; 370c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkeyimport android.util.Log; 38b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport android.view.LayoutInflater; 39b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport android.view.View; 40b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport android.view.ViewGroup; 41b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport android.widget.AdapterView; 42b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport android.widget.AdapterView.OnItemClickListener; 43b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport android.widget.BaseAdapter; 44b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport android.widget.ImageView; 45b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport android.widget.ListView; 46b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport android.widget.TextView; 47b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 48deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkeyimport com.android.documentsui.DocumentsActivity.State; 49d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkeyimport com.android.documentsui.RecentsProvider.RecentColumns; 50b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport com.android.documentsui.model.DocumentStack; 516a20e574116af1072782c1e87cb03eb33f05ec50Jeff Sharkeyimport com.android.documentsui.model.DurableUtils; 52deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkeyimport com.android.documentsui.model.RootInfo; 53b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport com.google.android.collect.Lists; 54b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 55b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport libcore.io.IoUtils; 56b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 57b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport java.io.ByteArrayInputStream; 58b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport java.io.DataInputStream; 59b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport java.io.IOException; 60b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport java.util.ArrayList; 61deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkeyimport java.util.Collection; 62b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport java.util.List; 63b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 64b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey/** 65b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey * Display directories where recent creates took place. 66b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey */ 67b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeypublic class RecentsCreateFragment extends Fragment { 68b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 696efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey private View mEmptyView; 70b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private ListView mListView; 71b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 72b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private DocumentStackAdapter mAdapter; 73b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private LoaderCallbacks<List<DocumentStack>> mCallbacks; 74b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 75b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private static final int LOADER_RECENTS = 3; 76b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 77b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public static void show(FragmentManager fm) { 78b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final RecentsCreateFragment fragment = new RecentsCreateFragment(); 79b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final FragmentTransaction ft = fm.beginTransaction(); 80b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey ft.replace(R.id.container_directory, fragment); 81b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey ft.commitAllowingStateLoss(); 82b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 83b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 84b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 85b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public View onCreateView( 86b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 87b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final Context context = inflater.getContext(); 88b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 89b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final View view = inflater.inflate(R.layout.fragment_directory, container, false); 90b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 916efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey mEmptyView = view.findViewById(android.R.id.empty); 926efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 93b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey mListView = (ListView) view.findViewById(R.id.list); 94b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey mListView.setOnItemClickListener(mItemListener); 95b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 96b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey mAdapter = new DocumentStackAdapter(); 97b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey mListView.setAdapter(mAdapter); 98b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 99deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey final RootsCache roots = DocumentsApplication.getRootsCache(context); 100deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey final State state = ((DocumentsActivity) getActivity()).getDisplayState(); 101deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey 102b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey mCallbacks = new LoaderCallbacks<List<DocumentStack>>() { 103b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 104b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public Loader<List<DocumentStack>> onCreateLoader(int id, Bundle args) { 105deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey return new RecentsCreateLoader(context, roots, state); 106b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 107b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 108b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 109b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public void onLoadFinished( 110b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey Loader<List<DocumentStack>> loader, List<DocumentStack> data) { 111b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey mAdapter.swapStacks(data); 112b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 113b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 114b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 115b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public void onLoaderReset(Loader<List<DocumentStack>> loader) { 116b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey mAdapter.swapStacks(null); 117b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 118b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey }; 119b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 120b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey return view; 121b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 122b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 123b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 124b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public void onStart() { 125b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey super.onStart(); 126b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey getLoaderManager().restartLoader(LOADER_RECENTS, getArguments(), mCallbacks); 127b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 128b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 129b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 130b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public void onStop() { 131b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey super.onStop(); 132b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey getLoaderManager().destroyLoader(LOADER_RECENTS); 133b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 134b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 135b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private OnItemClickListener mItemListener = new OnItemClickListener() { 136b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 137b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 138b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final DocumentStack stack = mAdapter.getItem(position); 139b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey ((DocumentsActivity) getActivity()).onStackPicked(stack); 140b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 141b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey }; 142b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 143b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey public static class RecentsCreateLoader extends UriDerivativeLoader<Uri, List<DocumentStack>> { 144deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey private final RootsCache mRoots; 145deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey private final State mState; 146deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey 147deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey public RecentsCreateLoader(Context context, RootsCache roots, State state) { 148d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey super(context, RecentsProvider.buildRecent()); 149deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey mRoots = roots; 150deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey mState = state; 151b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 152b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 153b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 154b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public List<DocumentStack> loadInBackground(Uri uri, CancellationSignal signal) { 155deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey final Collection<RootInfo> matchingRoots = mRoots.getMatchingRootsBlocking(mState); 156b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final ArrayList<DocumentStack> result = Lists.newArrayList(); 157b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 158b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final ContentResolver resolver = getContext().getContentResolver(); 159b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final Cursor cursor = resolver.query( 160d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey uri, null, null, null, RecentColumns.TIMESTAMP + " DESC", signal); 161b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey try { 162b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey while (cursor != null && cursor.moveToNext()) { 163d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey final byte[] rawStack = cursor.getBlob( 164d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey cursor.getColumnIndex(RecentColumns.STACK)); 1650c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey try { 166b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final DocumentStack stack = new DocumentStack(); 1676a20e574116af1072782c1e87cb03eb33f05ec50Jeff Sharkey DurableUtils.readFromArray(rawStack, stack); 168deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey 169deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey // Only update root here to avoid spinning up all 170deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey // providers; we update the stack during the actual 171deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey // restore. This also filters away roots that don't 172deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey // match current filter. 173deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey stack.updateRoot(matchingRoots); 1740c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey result.add(stack); 175b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } catch (IOException e) { 1760c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey Log.w(TAG, "Failed to resolve stack: " + e); 1770c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey } 178b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 179b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } finally { 180b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey IoUtils.closeQuietly(cursor); 181b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 182b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 183b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey return result; 184b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 185b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 186b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 187b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private class DocumentStackAdapter extends BaseAdapter { 188b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private List<DocumentStack> mStacks; 189b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 190b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public DocumentStackAdapter() { 191b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 192b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 193b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public void swapStacks(List<DocumentStack> stacks) { 194b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey mStacks = stacks; 1956efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 1966efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey if (isEmpty()) { 1976efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey mEmptyView.setVisibility(View.VISIBLE); 1986efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } else { 1996efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey mEmptyView.setVisibility(View.GONE); 2006efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 2016efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 202b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey notifyDataSetChanged(); 203b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 204b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 205b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 206b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public View getView(int position, View convertView, ViewGroup parent) { 207b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final Context context = parent.getContext(); 208b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 209b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey if (convertView == null) { 210b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final LayoutInflater inflater = LayoutInflater.from(context); 211b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey convertView = inflater.inflate(R.layout.item_doc_list, parent, false); 212b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 213b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 2144ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey final ImageView iconMime = (ImageView) convertView.findViewById(R.id.icon_mime); 215b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final TextView title = (TextView) convertView.findViewById(android.R.id.title); 2163f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey final View line2 = convertView.findViewById(R.id.line2); 217b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 218b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final DocumentStack stack = getItem(position); 2194ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconMime.setImageDrawable(stack.root.loadIcon(context)); 220b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 2213f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey final Drawable crumb = context.getResources() 2223f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey .getDrawable(R.drawable.ic_breadcrumb_arrow); 2233f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey crumb.setBounds(0, 0, crumb.getIntrinsicWidth(), crumb.getIntrinsicHeight()); 2243f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 2253f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey final SpannableStringBuilder builder = new SpannableStringBuilder(); 2263f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey builder.append(stack.root.title); 2273f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey for (int i = stack.size() - 2; i >= 0; i--) { 2285545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey appendDrawable(builder, crumb); 229b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey builder.append(stack.get(i).displayName); 230b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 2313f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey title.setText(builder); 232b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey title.setEllipsize(TruncateAt.MIDDLE); 233b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 234f8abf2e387681f2ed7631783418972972379d740Jeff Sharkey if (line2 != null) line2.setVisibility(View.GONE); 2353f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 236b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey return convertView; 237b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 238b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 239b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 240b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public int getCount() { 241b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey return mStacks != null ? mStacks.size() : 0; 242b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 243b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 244b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 245b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public DocumentStack getItem(int position) { 246b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey return mStacks.get(position); 247b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 248b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 249b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 250b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public long getItemId(int position) { 251b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey return getItem(position).hashCode(); 252b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 253b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 2543f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 2553f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey private static void appendDrawable(SpannableStringBuilder b, Drawable d) { 2563f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey final int length = b.length(); 2573f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey b.append("\u232a"); 2583f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey b.setSpan(new ImageSpan(d), length, b.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 2593f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 260b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey} 261