RecentsCreateFragment.java revision a82c2e24bc226c123075331cdaafb171b3b07b85
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); 112a82c2e24bc226c123075331cdaafb171b3b07b85Jeff Sharkey 113a82c2e24bc226c123075331cdaafb171b3b07b85Jeff Sharkey // When launched into empty recents, show drawer 114a82c2e24bc226c123075331cdaafb171b3b07b85Jeff Sharkey if (mAdapter.isEmpty() && !state.stackTouched) { 115a82c2e24bc226c123075331cdaafb171b3b07b85Jeff Sharkey ((DocumentsActivity) context).setRootsDrawerOpen(true); 116a82c2e24bc226c123075331cdaafb171b3b07b85Jeff Sharkey } 117b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 118b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 119b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 120b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public void onLoaderReset(Loader<List<DocumentStack>> loader) { 121b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey mAdapter.swapStacks(null); 122b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 123b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey }; 124b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 125b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey return view; 126b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 127b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 128b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 129b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public void onStart() { 130b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey super.onStart(); 131b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey getLoaderManager().restartLoader(LOADER_RECENTS, getArguments(), mCallbacks); 132b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 133b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 134b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 135b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public void onStop() { 136b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey super.onStop(); 137b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey getLoaderManager().destroyLoader(LOADER_RECENTS); 138b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 139b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 140b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private OnItemClickListener mItemListener = new OnItemClickListener() { 141b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 142b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 143b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final DocumentStack stack = mAdapter.getItem(position); 144b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey ((DocumentsActivity) getActivity()).onStackPicked(stack); 145b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 146b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey }; 147b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 148b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey public static class RecentsCreateLoader extends UriDerivativeLoader<Uri, List<DocumentStack>> { 149deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey private final RootsCache mRoots; 150deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey private final State mState; 151deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey 152deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey public RecentsCreateLoader(Context context, RootsCache roots, State state) { 153d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey super(context, RecentsProvider.buildRecent()); 154deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey mRoots = roots; 155deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey mState = state; 156b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 157b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 158b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 159b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public List<DocumentStack> loadInBackground(Uri uri, CancellationSignal signal) { 160deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey final Collection<RootInfo> matchingRoots = mRoots.getMatchingRootsBlocking(mState); 161b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final ArrayList<DocumentStack> result = Lists.newArrayList(); 162b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 163b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final ContentResolver resolver = getContext().getContentResolver(); 164b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final Cursor cursor = resolver.query( 165d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey uri, null, null, null, RecentColumns.TIMESTAMP + " DESC", signal); 166b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey try { 167b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey while (cursor != null && cursor.moveToNext()) { 168d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey final byte[] rawStack = cursor.getBlob( 169d182bb641f228b2d28527a6aa86075f6358ab838Jeff Sharkey cursor.getColumnIndex(RecentColumns.STACK)); 1700c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey try { 171b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final DocumentStack stack = new DocumentStack(); 1726a20e574116af1072782c1e87cb03eb33f05ec50Jeff Sharkey DurableUtils.readFromArray(rawStack, stack); 173deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey 174deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey // Only update root here to avoid spinning up all 175deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey // providers; we update the stack during the actual 176deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey // restore. This also filters away roots that don't 177deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey // match current filter. 178deffadeb7485e8660ecce12822e259d96fa06dceJeff Sharkey stack.updateRoot(matchingRoots); 1790c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey result.add(stack); 180b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } catch (IOException e) { 1810c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey Log.w(TAG, "Failed to resolve stack: " + e); 1820c2d31bfa113c2848620ac05c916802410b71da1Jeff Sharkey } 183b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 184b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } finally { 185b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey IoUtils.closeQuietly(cursor); 186b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 187b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 188b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey return result; 189b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 190b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 191b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 192b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private class DocumentStackAdapter extends BaseAdapter { 193b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private List<DocumentStack> mStacks; 194b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 195b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public DocumentStackAdapter() { 196b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 197b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 198b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public void swapStacks(List<DocumentStack> stacks) { 199b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey mStacks = stacks; 2006efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 2016efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey if (isEmpty()) { 2026efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey mEmptyView.setVisibility(View.VISIBLE); 2036efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } else { 2046efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey mEmptyView.setVisibility(View.GONE); 2056efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey } 2066efba22ce510352bb84910d6efc42fecafd31ed7Jeff Sharkey 207b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey notifyDataSetChanged(); 208b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 209b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 210b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 211b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public View getView(int position, View convertView, ViewGroup parent) { 212b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final Context context = parent.getContext(); 213b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 214b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey if (convertView == null) { 215b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final LayoutInflater inflater = LayoutInflater.from(context); 216b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey convertView = inflater.inflate(R.layout.item_doc_list, parent, false); 217b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 218b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 2194ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey final ImageView iconMime = (ImageView) convertView.findViewById(R.id.icon_mime); 220b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final TextView title = (TextView) convertView.findViewById(android.R.id.title); 2213f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey final View line2 = convertView.findViewById(R.id.line2); 222b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 223b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final DocumentStack stack = getItem(position); 2244ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey iconMime.setImageDrawable(stack.root.loadIcon(context)); 225b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 2263f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey final Drawable crumb = context.getResources() 2273f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey .getDrawable(R.drawable.ic_breadcrumb_arrow); 2283f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey crumb.setBounds(0, 0, crumb.getIntrinsicWidth(), crumb.getIntrinsicHeight()); 2293f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 2303f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey final SpannableStringBuilder builder = new SpannableStringBuilder(); 2313f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey builder.append(stack.root.title); 2323f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey for (int i = stack.size() - 2; i >= 0; i--) { 2335545f56f7561810187545a1817b6001dd1f9931bJeff Sharkey appendDrawable(builder, crumb); 234b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey builder.append(stack.get(i).displayName); 235b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 2363f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey title.setText(builder); 237b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey title.setEllipsize(TruncateAt.MIDDLE); 238b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 239f8abf2e387681f2ed7631783418972972379d740Jeff Sharkey if (line2 != null) line2.setVisibility(View.GONE); 2403f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 241b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey return convertView; 242b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 243b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 244b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 245b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public int getCount() { 246b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey return mStacks != null ? mStacks.size() : 0; 247b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 248b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 249b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 250b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public DocumentStack getItem(int position) { 251b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey return mStacks.get(position); 252b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 253b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 254b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey @Override 255b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public long getItemId(int position) { 256b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey return getItem(position).hashCode(); 257b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 258b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 2593f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey 2603f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey private static void appendDrawable(SpannableStringBuilder b, Drawable d) { 2613f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey final int length = b.length(); 2623f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey b.append("\u232a"); 2633f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey b.setSpan(new ImageSpan(d), length, b.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 2643f4c205fd3110345241e690f2a2e7c1b477eac76Jeff Sharkey } 265b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey} 266