diff --git a/matisse/src/main/java/com/zhihu/matisse/SelectionCreator.java b/matisse/src/main/java/com/zhihu/matisse/SelectionCreator.java index c4c835c02..0773657f2 100644 --- a/matisse/src/main/java/com/zhihu/matisse/SelectionCreator.java +++ b/matisse/src/main/java/com/zhihu/matisse/SelectionCreator.java @@ -386,4 +386,9 @@ public void forResult(int requestCode) { } } + public SelectionCreator showOther(boolean showOther) { + mSelectionSpec.showOther = showOther; + return this; + } + } diff --git a/matisse/src/main/java/com/zhihu/matisse/internal/entity/Album.java b/matisse/src/main/java/com/zhihu/matisse/internal/entity/Album.java index 9ebafb8c5..e15f30e58 100644 --- a/matisse/src/main/java/com/zhihu/matisse/internal/entity/Album.java +++ b/matisse/src/main/java/com/zhihu/matisse/internal/entity/Album.java @@ -41,6 +41,8 @@ public Album[] newArray(int size) { }; public static final String ALBUM_ID_ALL = String.valueOf(-1); public static final String ALBUM_NAME_ALL = "All"; + public static final String ALBUM_ID_OTHER = String.valueOf(-2); + public static final String ALBUM_NAME_OTHER = "Other..."; private final String mId; private final String mCoverPath; @@ -105,6 +107,8 @@ public void addCaptureCount() { public String getDisplayName(Context context) { if (isAll()) { return context.getString(R.string.album_name_all); + } else if (isOther()) { + return ALBUM_NAME_OTHER; } return mDisplayName; } @@ -113,6 +117,8 @@ public boolean isAll() { return ALBUM_ID_ALL.equals(mId); } + public boolean isOther() { return ALBUM_ID_OTHER.equals(mId); } + public boolean isEmpty() { return mCount == 0; } diff --git a/matisse/src/main/java/com/zhihu/matisse/internal/entity/SelectionSpec.java b/matisse/src/main/java/com/zhihu/matisse/internal/entity/SelectionSpec.java index 85b77d621..e5742a3a2 100644 --- a/matisse/src/main/java/com/zhihu/matisse/internal/entity/SelectionSpec.java +++ b/matisse/src/main/java/com/zhihu/matisse/internal/entity/SelectionSpec.java @@ -57,6 +57,7 @@ public final class SelectionSpec { public int cropMaxSize; public boolean hasFilter; public OnCheckedListener onCheckedListener; + public boolean showOther; private SelectionSpec() { } @@ -94,6 +95,7 @@ private void reset() { originalMaxSize = Integer.MAX_VALUE; cropMaxSize = 4000; hasFilter = true; + showOther = false; } public boolean singleSelectionModeEnabled() { diff --git a/matisse/src/main/java/com/zhihu/matisse/internal/loader/AlbumLoader.java b/matisse/src/main/java/com/zhihu/matisse/internal/loader/AlbumLoader.java index f328296a9..5cfaf270b 100644 --- a/matisse/src/main/java/com/zhihu/matisse/internal/loader/AlbumLoader.java +++ b/matisse/src/main/java/com/zhihu/matisse/internal/loader/AlbumLoader.java @@ -24,6 +24,7 @@ import android.provider.MediaStore; import android.support.v4.content.CursorLoader; +import com.zhihu.matisse.R; import com.zhihu.matisse.internal.entity.Album; import com.zhihu.matisse.internal.entity.SelectionSpec; @@ -109,7 +110,15 @@ public Cursor loadInBackground() { allAlbum.addRow(new String[]{Album.ALBUM_ID_ALL, Album.ALBUM_ID_ALL, Album.ALBUM_NAME_ALL, allAlbumCoverPath, String.valueOf(totalCount)}); - return new MergeCursor(new Cursor[]{allAlbum, albums}); + if (SelectionSpec.getInstance().showOther) { + MatrixCursor otherAlbum = new MatrixCursor(COLUMNS); + otherAlbum.addRow(new String[]{ + Album.ALBUM_ID_OTHER, Album.ALBUM_ID_OTHER, Album.ALBUM_NAME_OTHER, null, "-1" + }); + return new MergeCursor(new Cursor[]{allAlbum, albums, otherAlbum}); + } else { + return new MergeCursor(new Cursor[]{allAlbum, albums}); + } } @Override diff --git a/matisse/src/main/java/com/zhihu/matisse/internal/ui/adapter/AlbumsAdapter.java b/matisse/src/main/java/com/zhihu/matisse/internal/ui/adapter/AlbumsAdapter.java index 711e512b8..df756b6d9 100644 --- a/matisse/src/main/java/com/zhihu/matisse/internal/ui/adapter/AlbumsAdapter.java +++ b/matisse/src/main/java/com/zhihu/matisse/internal/ui/adapter/AlbumsAdapter.java @@ -64,11 +64,16 @@ public View newView(Context context, Cursor cursor, ViewGroup parent) { public void bindView(View view, Context context, Cursor cursor) { Album album = Album.valueOf(cursor); ((TextView) view.findViewById(R.id.album_name)).setText(album.getDisplayName(context)); - ((TextView) view.findViewById(R.id.album_media_count)).setText(String.valueOf(album.getCount())); + ((TextView) view.findViewById(R.id.album_media_count)).setText( + 0 < album.getCount() ? String.valueOf(album.getCount()) : "" + ); // do not need to load animated Gif - SelectionSpec.getInstance().imageEngine.loadThumbnail(context, context.getResources().getDimensionPixelSize(R - .dimen.media_grid_size), mPlaceholder, - (ImageView) view.findViewById(R.id.album_cover), Uri.fromFile(new File(album.getCoverPath()))); + if (album.getCoverPath() != null) { + SelectionSpec.getInstance().imageEngine.loadThumbnail(context, context.getResources().getDimensionPixelSize(R + .dimen.media_grid_size), mPlaceholder, + (ImageView) view.findViewById(R.id.album_cover), Uri.fromFile(new File(album.getCoverPath()))); + } + } } diff --git a/matisse/src/main/java/com/zhihu/matisse/ui/MatisseActivity.java b/matisse/src/main/java/com/zhihu/matisse/ui/MatisseActivity.java index d571ca66a..933342b27 100644 --- a/matisse/src/main/java/com/zhihu/matisse/ui/MatisseActivity.java +++ b/matisse/src/main/java/com/zhihu/matisse/ui/MatisseActivity.java @@ -82,6 +82,7 @@ public class MatisseActivity extends AppCompatActivity implements UCropFragmentC private static final int REQUEST_CODE_PREVIEW = 23; private static final int REQUEST_CODE_CAPTURE = 24; private static final int REQUEST_CODE_FILTER = 25; + private static final int REQUEST_CODE_OPEN_DOCUMENT = 30; public static final String CHECK_STATE = "checkState"; private final AlbumCollection mAlbumCollection = new AlbumCollection(); private MediaStoreCompat mMediaStoreCompat; @@ -324,7 +325,24 @@ public void run() { }, 400); } else if (requestCode == REQUEST_CODE_FILTER) { returnResult(); + } else if (requestCode == REQUEST_CODE_OPEN_DOCUMENT) { + + if (data != null) { + Uri contentUri = data.getData(); + String path = ""; + ArrayList selected = new ArrayList<>(); + selected.add(contentUri); + ArrayList selectedPath = new ArrayList<>(); + selectedPath.add(path); + Intent result = new Intent(); + result.putParcelableArrayListExtra(EXTRA_RESULT_SELECTION, selected); + result.putStringArrayListExtra(EXTRA_RESULT_SELECTION_PATH, selectedPath); + setResult(RESULT_OK, result); + finish(); + } + } + } private void galleryAddPic(Context context) { @@ -476,6 +494,11 @@ private void onAlbumSelected(Album album) { if (album.isAll() && album.isEmpty()) { mContainer.setVisibility(View.GONE); mEmptyView.setVisibility(View.VISIBLE); + } else if (album.isOther()) { + mContainer.setVisibility(View.GONE); + mEmptyView.setVisibility(View.VISIBLE); + performFileSearch(); + } else { mContainer.setVisibility(View.VISIBLE); mEmptyView.setVisibility(View.GONE); @@ -487,6 +510,26 @@ private void onAlbumSelected(Album album) { } } + private void performFileSearch() { + + // ACTION_OPEN_DOCUMENT is the intent to choose a file via the system's file + // browser. + Intent intent = new Intent(Intent.ACTION_GET_CONTENT); + + // Filter to only show results that can be "opened", such as a + // file (as opposed to a list of contacts or timezones) + intent.addCategory(Intent.CATEGORY_OPENABLE); + + // Filter to show only images, using the image MIME data type. + // If one wanted to search for ogg vorbis files, the type would be "audio/ogg". + // To search for all documents available via installed storage providers, + // it would be "*/*". + intent.setType("image/*"); + + startActivityForResult(intent, REQUEST_CODE_OPEN_DOCUMENT); + } + + @Override public void onUpdate() { // notify bottom toolbar that check state changed. diff --git a/sample/src/main/java/com/zhihu/matisse/sample/SampleActivity.java b/sample/src/main/java/com/zhihu/matisse/sample/SampleActivity.java index eb486d981..9231a0f20 100644 --- a/sample/src/main/java/com/zhihu/matisse/sample/SampleActivity.java +++ b/sample/src/main/java/com/zhihu/matisse/sample/SampleActivity.java @@ -101,6 +101,7 @@ public void onSelected( } }) + .showOther(true) .originalEnable(true) .maxOriginalSize(10) .maxCropSize(3000)