{"id":13643908,"url":"https://github.com/yanzhenjie/album","last_synced_at":"2025-05-15T01:09:58.635Z","repository":{"id":38414520,"uuid":"72589714","full_name":"yanzhenjie/Album","owner":"yanzhenjie","description":":watermelon: Album and Gallery for Android platform.","archived":false,"fork":false,"pushed_at":"2022-08-25T21:09:56.000Z","size":69554,"stargazers_count":2504,"open_issues_count":135,"forks_count":508,"subscribers_count":58,"default_branch":"master","last_synced_at":"2025-05-15T01:09:52.530Z","etag":null,"topics":["album","camera","gallery","image","video"],"latest_commit_sha":null,"homepage":"https://github.com/yanzhenjie/Album","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yanzhenjie.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-11-02T00:49:15.000Z","updated_at":"2025-05-09T10:03:32.000Z","dependencies_parsed_at":"2022-09-26T22:02:10.078Z","dependency_job_id":null,"html_url":"https://github.com/yanzhenjie/Album","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yanzhenjie%2FAlbum","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yanzhenjie%2FAlbum/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yanzhenjie%2FAlbum/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yanzhenjie%2FAlbum/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yanzhenjie","download_url":"https://codeload.github.com/yanzhenjie/Album/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254254043,"owners_count":22039792,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["album","camera","gallery","image","video"],"created_at":"2024-08-02T01:01:54.665Z","updated_at":"2025-05-15T01:09:53.617Z","avatar_url":"https://github.com/yanzhenjie.png","language":"Java","funding_links":[],"categories":["图片"],"sub_categories":[],"readme":"# Album\n\u003cimage src=\"./image/logo.png\"/\u003e  \n\nAlbum is a Material Design style album, it provides three functions: album, camera and gallery.\n\n1. Select images, selecte videos, or select pictures and videos.\n2. Take a picture, record a video, or use camera in album list.\n3. Preview pictures and videos in the gallery or select pictures and videos in the gallery.\n\n## Screenshot\n\u003cimage src=\"./image/1.gif\" width=\"210px\"/\u003e \u003cimage src=\"./image/2.gif\" width=\"210px\"/\u003e \u003cimage src=\"./image/3.gif\" width=\"210px\"/\u003e \u003cimage src=\"./image/4.gif\" width=\"210px\"/\u003e  \n\nWhite StatusBar, the left is the effect of 5.0-(Containing 5.0), the right is the effect of 6.0+(Containing 6.0):  \n  \n\u003cimage src=\"./image/5.gif\" width=\"210px\"/\u003e \u003cimage src=\"./image/6.gif\" width=\"210px\"/\u003e  \n\nEffect on landscape screen:  \n\n\u003cimage src=\"./image/7.gif\"/\u003e\n\n## Download\n```groovy\nimplementation 'com.yanzhenjie:album:2.1.3'\n```\n\n## Usage\nDevelopers must configure `AlbumLoader` to make Album work normally, and AlbumLoader is used to load thumbnails of images and videos.\n\nThis is an example:\n```java\npublic class MediaLoader implements AlbumLoader {\n\n    @Override\n    public void load(ImageView imageView, AlbumFile albumFile) {\n        load(imageView, albumFile.getPath());\n    }\n\n    @Override\n    public void load(ImageView imageView, String url) {\n        Glide.with(imageView.getContext())\n                .load(url)\n                .error(R.drawable.placeholder)\n                .placeholder(R.drawable.placeholder)\n                .crossFade()\n                .into(imageView);\n    }\n}\n```\nThe example uses [Glide](https://github.com/bumptech/glide) to load thumbnails of pictures and videos. Please remember to configure the `AlbumLoader` you just implemented.\n```java\nAlbum.initialize(AlbumConfig.newBuilder(this)\n    .setAlbumLoader(new MediaLoader())\n    ...\n    .build());\n```\n\n### Image and video mix options\n```java\nAlbum.album(this) // Image and video mix options.\n    .multipleChoice() // Multi-Mode, Single-Mode: singleChoice().\n    .columnCount() // The number of columns in the page list.\n    .selectCount()  // Choose up to a few images.\n    .camera() // Whether the camera appears in the Item.\n    .cameraVideoQuality(1) // Video quality, [0, 1].\n    .cameraVideoLimitDuration(Long.MAX_VALUE) // The longest duration of the video is in milliseconds.\n    .cameraVideoLimitBytes()(Long.MAX_VALUE) // Maximum size of the video, in bytes.\n    .checkedList() // To reverse the list.\n    .filterSize() // Filter the file size.\n    .filterMimeType() // Filter file format.\n    .filterDuration() // Filter video duration.\n    .afterFilterVisibility() // Show the filtered files, but they are not available.\n    .onResult(new Action\u003cArrayList\u003cAlbumFile\u003e\u003e() {\n        @Override\n        public void onAction(@NonNull ArrayList\u003cAlbumFile\u003e result) {\n            // TODO accept the result.\n        }\n    })\n    .onCancel(new Action\u003cString\u003e() {\n        @Override\n        public void onAction(@NonNull String result) {\n            // The user canceled the operation.\n        }\n    })\n    .start();\n```\n\n### Image Selection\n```java\nAlbum.image(this) // Image selection.\n    .multipleChoice()\n    .camera()\n    .columnCount()\n    .selectCount()\n    .checkedList(mAlbumFiles)\n    .filterSize() // Filter the file size.\n    .filterMimeType() // Filter file format.\n    .afterFilterVisibility() // Show the filtered files, but they are not available.\n    .onResult(new Action\u003cArrayList\u003cAlbumFile\u003e\u003e() {\n        @Override\n        public void onAction(@NonNull ArrayList\u003cAlbumFile\u003e result) {\n        }\n    })\n    .onCancel(new Action\u003cString\u003e() {\n        @Override\n        public void onAction(@NonNull String result) {\n        }\n    })\n    .start();\n```\n\nIf developer want to crop the image, please use [Durban](https://github.com/yanzhenjie/Durban).\n\n### Video Selection\n```java\nAlbum.video(this) // Video selection.\n    .multipleChoice()\n    .camera(true)\n    .columnCount(2)\n    .selectCount(6)\n    .checkedList(mAlbumFiles)\n    .filterSize()\n    .filterMimeType()\n    .filterDuration()\n    .afterFilterVisibility() // Show the filtered files, but they are not available.\n    .onResult(new Action\u003cArrayList\u003cAlbumFile\u003e\u003e() {\n        @Override\n        public void onAction(@NonNull ArrayList\u003cAlbumFile\u003e result) {\n        }\n    })\n    .onCancel(new Action\u003cString\u003e() {\n        @Override\n        public void onAction(@NonNull String result) {\n        }\n    })\n    .start();\n```\n\n### Take Picture\n```java\nAlbum.camera(this) // Camera function.\n    .image() // Take Picture.\n    .filePath() // File save path, not required.\n    .onResult(new Action\u003cString\u003e() {\n        @Override\n        public void onAction(@NonNull String result) {\n        }\n    })\n    .onCancel(new Action\u003cString\u003e() {\n        @Override\n        public void onAction(@NonNull String result) {\n        }\n    })\n    .start();\n```\n\nIf developer want to crop the image, please use [Durban](https://github.com/yanzhenjie/Durban).\n\n### Record Video\n```java\nAlbum.camera(this)\n    .video() // Record Video.\n    .filePath()\n    .quality(1) // Video quality, [0, 1].\n    .limitDuration(Long.MAX_VALUE) // The longest duration of the video is in milliseconds.\n    .limitBytes(Long.MAX_VALUE) // Maximum size of the video, in bytes.\n    .onResult(new Action\u003cString\u003e() {\n        @Override\n        public void onAction(@NonNull String result) {\n        }\n    })\n    .onCancel(new Action\u003cString\u003e() {\n        @Override\n        public void onAction(@NonNull String result) {\n        }\n    })\n    .start();\n```\n\n### Gallery\n```java\n// Preview AlbumFile:\nAlbum.galleryAlbum(this)\n...\n\n// Preview path:\nAlbum.gallery(this)\n    .checkedList(imageList) // List of image to view: ArrayList\u003cString\u003e.\n    .checkable(true) // Whether there is a selection function.\n    .onResult(new Action\u003cArrayList\u003cString\u003e\u003e() { // If checkable(false), action not required.\n        @Override\n        public void onAction(@NonNull ArrayList\u003cString\u003e result) {\n        }\n    })\n    .onCancel(new Action\u003cString\u003e() {\n        @Override\n        public void onAction(@NonNull String result) {\n        }\n    })\n    .start();\n```\n\n\u003e If `checkable(false)`, listener not required, the `CheckBox` and the `FinishButton` will be not appear.\n\nThe user may click or long press on the preview image and the developer can listen to both events:\n```java\nAlbum.gallery(this)\n    ...\n    .itemClick(new ItemAction\u003cString\u003e() {\n        @Override\n        public void onAction(Context context, String item) {\n        }\n    })\n    .itemLongClick(new ItemAction\u003cString\u003e() {\n        @Override\n        public void onAction(Context context, String item) {\n        }\n    })\n    .start();\n```\n\n### Capabilities of AlbumFile\n`AlbumFile` is the result of the selection of images and videos, The properties of the image and video are different, and their different attributes are listed below.\n\n#### Image\n```java\npublic int getMediaType(); // File type, the image is AlbumFile.TYPE_IMAGE.\npublic String getPath(); // File path, must not be empty.\npublic String getBucketName(); // The name of the folder where the file is located.\npublic String getMimeType(); // File MimeType, for example: image/jpeg.\npublic long getAddDate(); // File to add date, must have.\npublic float getLatitude(); // The latitude of the file, may be zero.\npublic float getLongitude(); // The longitude of the file, may be zero.\npublic long getSize(); // File size in bytes.\npublic String getThumbPath(); // This is a small thumbnail.\n```\n\n#### Video\n```java\npublic int getMediaType(); // File type, the video is AlbumFile.TYPE_VIDEO.\npublic String getPath(); // File path, must not be empty.\npublic String getBucketName(); // The name of the folder where the file is located.\npublic String getMimeType(); // File MimeType, for example: image/jpeg.\npublic long getAddDate(); // File to add date, must have.\npublic float getLatitude(); // The latitude of the file, may be zero.\npublic float getLongitude(); // The longitude of the file, may be zero.\npublic long getSize(); // File size in bytes.\npublic long getDuration(); // Video duration, must have.\npublic String getThumbPath(); // This is a small thumbnail.\n```\n\n### Customize UI\nThrough `Widget`, developer can configure the title, color of StatusBar, color of NavigationBar and so on.\n\n```java\n// Such as image video mix:\n Album.album(this)\n    .multipleChoice()\n    .widget(...)\n    ...\n\n// Image selection:\nAlbum.image(this)\n    .multipleChoice()\n    .widget(...)\n    ...\n\n// Video selection:\nAlbum.video(this)\n    .multipleChoice()\n    .widget(...)\n    ...\n\n// Gallery, preview AlbumFile:\nAlbum.galleryAlbum(this)\n    .widget(...)\n    ...\n\n// Gallery, preview path:\nAlbum.gallery(this)\n    .widget(...)\n    ...\n```\n\nSo we only need to pass in a `Widget` parameter just fine:\n```java\n// StatusBar is a dark background when building:\nWidget.newDarkBuilder(this)\n...\n\n// StatusBar is a light background when building:\nWidget.newLightBuilder(this)\n...\n\n// Such as:\nWidget.xxxBuilder(this)\n    .title(...) // Title.\n    .statusBarColor(Color.WHITE) // StatusBar color.\n    .toolBarColor(Color.WHITE) // Toolbar color.\n    .navigationBarColor(Color.WHITE) // Virtual NavigationBar color of Android5.0+.\n    .mediaItemCheckSelector(Color.BLUE, Color.GREEN) // Image or video selection box.\n    .bucketItemCheckSelector(Color.RED, Color.YELLOW) // Select the folder selection box.\n    .buttonStyle( // Used to configure the style of button when the image/video is not found.\n        Widget.ButtonStyle.newLightBuilder(this) // With Widget's Builder model.\n            .setButtonSelector(Color.WHITE, Color.WHITE) // Button selector.\n            .build()\n    )\n    .build()\n```\n\n### Configuration language\nAlbum defaults to English and changes with the system language. Unfortunately, Album only supports English, Simplified Chinese, Traditional Chinese and Portuguese. However, developers can copy the items in Album's `string.xml` into your project for translation, the best thing is that you can [contribute](CONTRIBUTING.md) and submit pull requests to perfect Album.\n\nDevelopers can specify Album's language:\n```java\nAlbum.initialize(AlbumConfig.newBuilder(this)\n    ...\n    .setLocale(Locale.ENGLISH)\n    .build());\n```\n\n## Contributing\nBefore submitting pull requests, contributors must abide by the [agreement](CONTRIBUTING.md) .\n\n## Proguard-rules\nIf you are using ProGuard you might need to add the following options:\n```txt\n-dontwarn com.yanzhenjie.album.**\n-dontwarn com.yanzhenjie.mediascanner.**\n```\n\n## License\n```text\nCopyright 2017 Yan Zhenjie\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyanzhenjie%2Falbum","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyanzhenjie%2Falbum","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyanzhenjie%2Falbum/lists"}