RecentsCreateFragment.java revision 58efce36cd1b26006e08ddd696292bf06fc34c81
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 1958efce36cd1b26006e08ddd696292bf06fc34c81Steve McKayimport static com.android.documentsui.Shared.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 48e934ce6f8430f50d1d22bccd3b341b982f5541eeSteve McKayimport com.android.documentsui.BaseActivity.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 Sharkey 54b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport libcore.io.IoUtils; 55b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 56b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport java.io.IOException; 57b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport java.util.ArrayList; 58deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkeyimport java.util.Collection; 59b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport java.util.List; 60b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 61b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey/** 62b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey * Display directories where recent creates took place. 63b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey */ 64b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeypublic class RecentsCreateFragment extends Fragment { 65b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 666efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey private View mEmptyView; 67b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private ListView mListView; 68b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 69b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private DocumentStackAdapter mAdapter; 70b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private LoaderCallbacks<List<DocumentStack>> mCallbacks; 71b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 72b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private static final int LOADER_RECENTS = 3; 73b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 74b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public static void show(FragmentManager fm) { 75b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final RecentsCreateFragment fragment = new RecentsCreateFragment(); 76b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final FragmentTransaction ft = fm.beginTransaction(); 77b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey ft.replace(R.id.container_directory, fragment); 78b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey ft.commitAllowingStateLoss(); 79b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 80b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 81b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 82b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public View onCreateView( 83b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 84b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final Context context = inflater.getContext(); 85b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 86b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final View view = inflater.inflate(R.layout.fragment_directory, container, false); 87b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 886efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey mEmptyView = view.findViewById(android.R.id.empty); 896efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 90b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey mListView = (ListView) view.findViewById(R.id.list); 91b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey mListView.setOnItemClickListener(mItemListener); 92b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 93b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey mAdapter = new DocumentStackAdapter(); 94b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey mListView.setAdapter(mAdapter); 95b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 96deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey final RootsCache roots = DocumentsApplication.getRootsCache(context); 97e934ce6f8430f50d1d22bccd3b341b982f5541eeSteve McKay final State state = ((BaseActivity) getActivity()).getDisplayState(); 98deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey 99b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey mCallbacks = new LoaderCallbacks<List<DocumentStack>>() { 100b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 101b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public Loader<List<DocumentStack>> onCreateLoader(int id, Bundle args) { 102deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey return new RecentsCreateLoader(context, roots, state); 103b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 104b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 105b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 106b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public void onLoadFinished( 107b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey Loader<List<DocumentStack>> loader, List<DocumentStack> data) { 108b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey mAdapter.swapStacks(data); 109a82c2e24bc226c123075331cdaafb171b3b07b85Jeff Sharkey 110a82c2e24bc226c123075331cdaafb171b3b07b85Jeff Sharkey // When launched into empty recents, show drawer 111ef3e2cf35fbede340d5ff830b410baea8e461a94Steve McKay if (mAdapter.isEmpty() && !state.stackTouched && 112ef3e2cf35fbede340d5ff830b410baea8e461a94Steve McKay context instanceof DocumentsActivity) { 113ef3e2cf35fbede340d5ff830b410baea8e461a94Steve McKay ((DocumentsActivity) context).setRootsDrawerOpen(true); 114a82c2e24bc226c123075331cdaafb171b3b07b85Jeff Sharkey } 115b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 116b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 117b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 118b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public void onLoaderReset(Loader<List<DocumentStack>> loader) { 119b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey mAdapter.swapStacks(null); 120b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 121b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey }; 122b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 123b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey return view; 124b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 125b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 126b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 127b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public void onStart() { 128b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey super.onStart(); 129b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey getLoaderManager().restartLoader(LOADER_RECENTS, getArguments(), mCallbacks); 130b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 131b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 132b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 133b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public void onStop() { 134b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey super.onStop(); 135b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey getLoaderManager().destroyLoader(LOADER_RECENTS); 136b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 137b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 138b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private OnItemClickListener mItemListener = new OnItemClickListener() { 139b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 140b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 141b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final DocumentStack stack = mAdapter.getItem(position); 142e934ce6f8430f50d1d22bccd3b341b982f5541eeSteve McKay ((BaseActivity) getActivity()).onStackPicked(stack); 143b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 144b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey }; 145b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 146b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey public static class RecentsCreateLoader extends UriDerivativeLoader<Uri, List<DocumentStack>> { 147deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey private final RootsCache mRoots; 148deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey private final State mState; 149deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey 150deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey public RecentsCreateLoader(Context context, RootsCache roots, State state) { 151d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey super(context, RecentsProvider.buildRecent()); 152deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey mRoots = roots; 153deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey mState = state; 154b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 155b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 156b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 157b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public List<DocumentStack> loadInBackground(Uri uri, CancellationSignal signal) { 158deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey final Collection<RootInfo> matchingRoots = mRoots.getMatchingRootsBlocking(mState); 15958efce36cd1b26006e08ddd696292bf06fc34c81Steve McKay final ArrayList<DocumentStack> result = new ArrayList<>(); 160b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 161b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final ContentResolver resolver = getContext().getContentResolver(); 162b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final Cursor cursor = resolver.query( 163d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey uri, null, null, null, RecentColumns.TIMESTAMP + " DESC", signal); 164b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey try { 165b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey while (cursor != null && cursor.moveToNext()) { 166d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey final byte[] rawStack = cursor.getBlob( 167d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey cursor.getColumnIndex(RecentColumns.STACK)); 1680c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey try { 169b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final DocumentStack stack = new DocumentStack(); 1706a20e574116af1072782c1e87cb03eb33f05ec50Jeff Sharkey DurableUtils.readFromArray(rawStack, stack); 171deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey 172deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey // Only update root here to avoid spinning up all 173deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey // providers; we update the stack during the actual 174deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey // restore. This also filters away roots that don't 175deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey // match current filter. 176deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey stack.updateRoot(matchingRoots); 1770c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey result.add(stack); 178b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } catch (IOException e) { 1790c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey Log.w(TAG, "Failed to resolve stack: " + e); 1800c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey } 181b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 182b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } finally { 183b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey IoUtils.closeQuietly(cursor); 184b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 185b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 186b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey return result; 187b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 188b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 189b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 190b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private class DocumentStackAdapter extends BaseAdapter { 191b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private List<DocumentStack> mStacks; 192b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 193b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public DocumentStackAdapter() { 194b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 195b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 196b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public void swapStacks(List<DocumentStack> stacks) { 197b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey mStacks = stacks; 1986efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 1996efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey if (isEmpty()) { 2006efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey mEmptyView.setVisibility(View.VISIBLE); 2016efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } else { 2026efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey mEmptyView.setVisibility(View.GONE); 2036efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 2046efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 205b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey notifyDataSetChanged(); 206b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 207b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 208b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 209b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public View getView(int position, View convertView, ViewGroup parent) { 210b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final Context context = parent.getContext(); 211b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 212b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey if (convertView == null) { 213b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final LayoutInflater inflater = LayoutInflater.from(context); 214b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey convertView = inflater.inflate(R.layout.item_doc_list, parent, false); 215b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 216b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 2174ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey final ImageView iconMime = (ImageView) convertView.findViewById(R.id.icon_mime); 218b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final TextView title = (TextView) convertView.findViewById(android.R.id.title); 2193f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey final View line2 = convertView.findViewById(R.id.line2); 220b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 221b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final DocumentStack stack = getItem(position); 2224ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconMime.setImageDrawable(stack.root.loadIcon(context)); 223b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 22403d30a573b8bc8e169e153a0fffa053ffedcd5eeAlan Viverette final Drawable crumb = context.getDrawable(R.drawable.ic_breadcrumb_arrow); 2253f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey crumb.setBounds(0, 0, crumb.getIntrinsicWidth(), crumb.getIntrinsicHeight()); 2263f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 2273f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey final SpannableStringBuilder builder = new SpannableStringBuilder(); 2283f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey builder.append(stack.root.title); 2293f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey for (int i = stack.size() - 2; i >= 0; i--) { 2305545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey appendDrawable(builder, crumb); 231b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey builder.append(stack.get(i).displayName); 232b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 2333f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey title.setText(builder); 234b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey title.setEllipsize(TruncateAt.MIDDLE); 235b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 236f8abf2e387681f2ed7631783418972972379d740Jeff Sharkey if (line2 != null) line2.setVisibility(View.GONE); 2373f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 238b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey return convertView; 239b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 240b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 241b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 242b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public int getCount() { 243b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey return mStacks != null ? mStacks.size() : 0; 244b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 245b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 246b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 247b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public DocumentStack getItem(int position) { 248b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey return mStacks.get(position); 249b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 250b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 251b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 252b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public long getItemId(int position) { 253b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey return getItem(position).hashCode(); 254b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 255b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 2563f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 2573f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey private static void appendDrawable(SpannableStringBuilder b, Drawable d) { 2583f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey final int length = b.length(); 2593f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey b.append("\u232a"); 2603f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey b.setSpan(new ImageSpan(d), length, b.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 2613f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 262b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey} 263