init
|
|
@ -0,0 +1,6 @@
|
|||
.gradle
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
/.idea/libraries
|
||||
.DS_Store
|
||||
/build
|
||||
|
|
@ -0,0 +1 @@
|
|||
MultiImageSelector
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<option name="DEFAULT_COMPILER" value="Javac" />
|
||||
<resourceExtensions />
|
||||
<wildcardResourcePatterns>
|
||||
<entry name="!?*.java" />
|
||||
<entry name="!?*.form" />
|
||||
<entry name="!?*.class" />
|
||||
<entry name="!?*.groovy" />
|
||||
<entry name="!?*.scala" />
|
||||
<entry name="!?*.flex" />
|
||||
<entry name="!?*.kt" />
|
||||
<entry name="!?*.clj" />
|
||||
</wildcardResourcePatterns>
|
||||
<annotationProcessing>
|
||||
<profile default="true" name="Default" enabled="false">
|
||||
<processorPath useClasspath="true" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
</component>
|
||||
</project>
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<component name="CopyrightManager">
|
||||
<settings default="" />
|
||||
</component>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
|
||||
</project>
|
||||
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
<option value="$PROJECT_DIR$/multi-image-selector" />
|
||||
</set>
|
||||
</option>
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="EntryPointsManager">
|
||||
<entry_points version="2.0" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
</project>
|
||||
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/MultiImageSelector.iml" filepath="$PROJECT_DIR$/MultiImageSelector.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/multi-image-selector/multi-image-selector.iml" filepath="$PROJECT_DIR$/multi-image-selector/multi-image-selector.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<component name="DependencyValidationManager">
|
||||
<state>
|
||||
<option name="SKIP_IMPORT_STATEMENTS" value="false" />
|
||||
</state>
|
||||
</component>
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="" />
|
||||
</component>
|
||||
</project>
|
||||
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="java-gradle" name="Java-Gradle">
|
||||
<configuration>
|
||||
<option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
/build
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="MultiImageSelector" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="android-gradle" name="Android-Gradle">
|
||||
<configuration>
|
||||
<option name="GRADLE_PROJECT_PATH" value=":app" />
|
||||
</configuration>
|
||||
</facet>
|
||||
<facet type="android" name="Android">
|
||||
<configuration>
|
||||
<option name="SELECTED_BUILD_VARIANT" value="debug" />
|
||||
<option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
|
||||
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
|
||||
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
|
||||
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugAndroidTest" />
|
||||
<option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
|
||||
<option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugAndroidTestSources" />
|
||||
<option name="ALLOW_USER_CONFIGURATION" value="false" />
|
||||
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
|
||||
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
|
||||
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
|
||||
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="false">
|
||||
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
|
||||
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/androidTest/debug" />
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/androidTest/debug" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Android API 22 Platform" jdkType="Android SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" exported="" name="appcompat-v7-22.0.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="picasso-2.5.2" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-v4-22.0.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-annotations-22.0.0" level="project" />
|
||||
<orderEntry type="module" module-name="multi-image-selector" exported="" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 22
|
||||
buildToolsVersion "22.0.1"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "me.nereo.multiimageselector"
|
||||
minSdkVersion 12
|
||||
targetSdkVersion 22
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(include: ['*.jar'], dir: 'libs')
|
||||
compile 'com.android.support:appcompat-v7:22.0.0'
|
||||
compile project(':multi-image-selector')
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in F:\Nereo\Program\Android\sdk/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package me.nereo.multiimageselector;
|
||||
|
||||
import android.app.Application;
|
||||
import android.test.ApplicationTestCase;
|
||||
|
||||
/**
|
||||
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
|
||||
*/
|
||||
public class ApplicationTest extends ApplicationTestCase<Application> {
|
||||
public ApplicationTest() {
|
||||
super(Application.class);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="me.nereo.multiimageselector" >
|
||||
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme" >
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:label="@string/app_name" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name="me.nereo.multi_image_selector.MultiImageSelectorActivity" />
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
package me.nereo.multiimageselector;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.RadioGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import me.nereo.multi_image_selector.MultiImageSelectorActivity;
|
||||
|
||||
|
||||
public class MainActivity extends ActionBarActivity {
|
||||
|
||||
private static final int REQUEST_IMAGE = 2;
|
||||
|
||||
private TextView mResultText;
|
||||
private RadioGroup mChoiceMode, mShowCamera;
|
||||
private EditText mRequestNum;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
mResultText = (TextView) findViewById(R.id.result);
|
||||
mChoiceMode = (RadioGroup) findViewById(R.id.choice_mode);
|
||||
mShowCamera = (RadioGroup) findViewById(R.id.show_camera);
|
||||
mRequestNum = (EditText) findViewById(R.id.request_num);
|
||||
|
||||
mChoiceMode.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(RadioGroup radioGroup, int checkedId) {
|
||||
if(checkedId == R.id.multi){
|
||||
mRequestNum.setEnabled(true);
|
||||
}else{
|
||||
mRequestNum.setEnabled(false);
|
||||
mRequestNum.setText("");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
|
||||
int selectedMode = MultiImageSelectorActivity.MODE_MULTI;
|
||||
|
||||
if(mChoiceMode.getCheckedRadioButtonId() == R.id.single){
|
||||
selectedMode = MultiImageSelectorActivity.MODE_SINGLE;
|
||||
}else{
|
||||
selectedMode = MultiImageSelectorActivity.MODE_MULTI;
|
||||
}
|
||||
|
||||
boolean showCamera = mShowCamera.getCheckedRadioButtonId() == R.id.show;
|
||||
|
||||
int maxNum = 9;
|
||||
if(!TextUtils.isEmpty(mRequestNum.getText())){
|
||||
maxNum = Integer.valueOf(mRequestNum.getText().toString());
|
||||
}
|
||||
|
||||
Intent intent = new Intent(MainActivity.this, MultiImageSelectorActivity.class);
|
||||
// 是否显示拍摄图片
|
||||
intent.putExtra(MultiImageSelectorActivity.EXTRA_SHOW_CAMERA, showCamera);
|
||||
// 最大可选择图片数量
|
||||
intent.putExtra(MultiImageSelectorActivity.EXTRA_SELECT_COUNT, maxNum);
|
||||
// 选择模式
|
||||
intent.putExtra(MultiImageSelectorActivity.EXTRA_SELECT_MODE, selectedMode);
|
||||
startActivityForResult(intent, REQUEST_IMAGE);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if(requestCode == REQUEST_IMAGE){
|
||||
if(resultCode == RESULT_OK){
|
||||
List<String> path = data.getStringArrayListExtra(MultiImageSelectorActivity.EXTRA_RESULT);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for(String p: path){
|
||||
sb.append(p);
|
||||
sb.append("\n");
|
||||
}
|
||||
mResultText.setText(sb.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
// Inflate the menu; this adds items to the action bar if it is present.
|
||||
getMenuInflater().inflate(R.menu.menu_main, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
// Handle action bar item clicks here. The action bar will
|
||||
// automatically handle clicks on the Home/Up button, so long
|
||||
// as you specify a parent activity in AndroidManifest.xml.
|
||||
int id = item.getItemId();
|
||||
|
||||
//noinspection SimplifiableIfStatement
|
||||
if (id == R.id.action_settings) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
|
||||
|
||||
<TextView
|
||||
android:focusableInTouchMode="true"
|
||||
android:focusable="true"
|
||||
android:text="选择模式:"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="@android:color/black"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<RadioGroup
|
||||
android:id="@+id/choice_mode"
|
||||
android:checkedButton="@+id/multi"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/single"
|
||||
android:text="单选"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
<RadioButton
|
||||
android:id="@+id/multi"
|
||||
android:text="多选"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</RadioGroup>
|
||||
|
||||
<TextView
|
||||
android:text="最大选择数量:"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="@android:color/black"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/request_num"
|
||||
android:hint="默认数量为9"
|
||||
android:enabled="false"
|
||||
android:inputType="number"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:text="是否显示Camera:"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="@android:color/black"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<RadioGroup
|
||||
android:id="@+id/show_camera"
|
||||
android:checkedButton="@+id/show"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/show"
|
||||
android:text="是"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
<RadioButton
|
||||
android:id="@+id/no_show"
|
||||
android:text="否"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</RadioGroup>
|
||||
|
||||
<Button
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="图片选择"
|
||||
android:id="@+id/button"/>
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/result"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</ScrollView>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity">
|
||||
<item android:id="@+id/action_settings" android:title="@string/action_settings"
|
||||
android:orderInCategory="100" app:showAsAction="never" />
|
||||
</menu>
|
||||
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
|
|
@ -0,0 +1,6 @@
|
|||
<resources>
|
||||
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
|
||||
(such as screen margins) for screens with more than 820dp of available width. This
|
||||
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
|
||||
<dimen name="activity_horizontal_margin">64dp</dimen>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<resources>
|
||||
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<resources>
|
||||
<string name="app_name">MultiImageSelector</string>
|
||||
|
||||
<string name="hello_world">Hello world!</string>
|
||||
<string name="action_settings">Settings</string>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:1.1.0'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# Project-wide Gradle settings.
|
||||
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Gradle settings configured through the IDE *will override*
|
||||
# any settings specified in this file.
|
||||
|
||||
# For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
# Default value: -Xmx10248m -XX:MaxPermSize=256m
|
||||
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
#Wed Apr 10 15:27:10 PDT 2013
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||
if $cygwin ; then
|
||||
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
fi
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >&-
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >&-
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
|
|
@ -0,0 +1 @@
|
|||
/build
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion 22
|
||||
buildToolsVersion "22.0.1"
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 12
|
||||
targetSdkVersion 22
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
compile 'com.android.support:appcompat-v7:22.0.0'
|
||||
compile 'com.squareup.picasso:picasso:2.5.2'
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="MultiImageSelector" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="android-gradle" name="Android-Gradle">
|
||||
<configuration>
|
||||
<option name="GRADLE_PROJECT_PATH" value=":multi-image-selector" />
|
||||
</configuration>
|
||||
</facet>
|
||||
<facet type="android" name="Android">
|
||||
<configuration>
|
||||
<option name="SELECTED_BUILD_VARIANT" value="debug" />
|
||||
<option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
|
||||
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
|
||||
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
|
||||
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugAndroidTest" />
|
||||
<option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
|
||||
<option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugAndroidTestSources" />
|
||||
<option name="ALLOW_USER_CONFIGURATION" value="false" />
|
||||
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
|
||||
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
|
||||
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
|
||||
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
|
||||
<option name="LIBRARY_PROJECT" value="true" />
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="false">
|
||||
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
|
||||
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/androidTest/debug" />
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/androidTest/debug" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Android API 22 Platform" jdkType="Android SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" exported="" name="appcompat-v7-22.0.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="picasso-2.5.2" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-v4-22.0.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-annotations-22.0.0" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in F:/Nereo/Program/Android/sdk/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package me.nereo.multi_image_selector;
|
||||
|
||||
import android.app.Application;
|
||||
import android.test.ApplicationTestCase;
|
||||
|
||||
/**
|
||||
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
|
||||
*/
|
||||
public class ApplicationTest extends ApplicationTestCase<Application> {
|
||||
public ApplicationTest() {
|
||||
super(Application.class);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="me.nereo.multi_image_selector">
|
||||
|
||||
<application android:allowBackup="true">
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
package me.nereo.multi_image_selector;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* 多图选择
|
||||
* Created by Nereo on 2015/4/7.
|
||||
*/
|
||||
public class MultiImageSelectorActivity extends FragmentActivity implements MultiImageSelectorFragment.Callback{
|
||||
|
||||
/** 最大图片选择次数,int类型,默认9 */
|
||||
public static final String EXTRA_SELECT_COUNT = "max_select_count";
|
||||
/** 图片选择模式,默认多选 */
|
||||
public static final String EXTRA_SELECT_MODE = "select_count_mode";
|
||||
/** 是否显示相机,默认显示 */
|
||||
public static final String EXTRA_SHOW_CAMERA = "show_camera";
|
||||
/** 选择结果,返回为 ArrayList<String> 图片路径集合 */
|
||||
public static final String EXTRA_RESULT = "select_result";
|
||||
|
||||
/** 单选 */
|
||||
public static final int MODE_SINGLE = 0;
|
||||
/** 多选 */
|
||||
public static final int MODE_MULTI = 1;
|
||||
|
||||
private ArrayList<String> resultList = new ArrayList<>();
|
||||
private Button mSubmitButton;
|
||||
private int mDefaultCount;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_default);
|
||||
|
||||
Intent intent = getIntent();
|
||||
mDefaultCount = intent.getIntExtra(EXTRA_SELECT_COUNT, 9);
|
||||
int mode = intent.getIntExtra(EXTRA_SELECT_MODE, MODE_MULTI);
|
||||
boolean isShow = intent.getBooleanExtra(EXTRA_SHOW_CAMERA, true);
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt(MultiImageSelectorFragment.EXTRA_SELECT_COUNT, mDefaultCount);
|
||||
bundle.putInt(MultiImageSelectorFragment.EXTRA_SELECT_MODE, mode);
|
||||
bundle.putBoolean(MultiImageSelectorFragment.EXTRA_SHOW_CAMERA, isShow);
|
||||
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.add(R.id.image_grid, Fragment.instantiate(this, MultiImageSelectorFragment.class.getName(), bundle))
|
||||
.commit();
|
||||
|
||||
// 返回按钮
|
||||
findViewById(R.id.btn_back).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
setResult(RESULT_CANCELED);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
// 完成按钮
|
||||
mSubmitButton = (Button) findViewById(R.id.commit);
|
||||
if(resultList == null || resultList.size()<=0){
|
||||
mSubmitButton.setText("完成");
|
||||
mSubmitButton.setEnabled(false);
|
||||
}
|
||||
mSubmitButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if(resultList != null && resultList.size() >0){
|
||||
// 返回已选择的图片数据
|
||||
Intent data = new Intent();
|
||||
data.putStringArrayListExtra(EXTRA_RESULT, resultList);
|
||||
setResult(RESULT_OK, data);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSingleImageSelected(String path) {
|
||||
Intent data = new Intent();
|
||||
resultList.add(path);
|
||||
data.putStringArrayListExtra(EXTRA_RESULT, resultList);
|
||||
setResult(RESULT_OK, data);
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImageSelected(String path) {
|
||||
if(!resultList.contains(path)) {
|
||||
resultList.add(path);
|
||||
}
|
||||
// 有图片之后,改变按钮状态
|
||||
if(resultList.size() > 0){
|
||||
mSubmitButton.setText("完成("+resultList.size()+"/"+mDefaultCount+")");
|
||||
if(!mSubmitButton.isEnabled()){
|
||||
mSubmitButton.setEnabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onImageUnselected(String path) {
|
||||
if(resultList.contains(path)){
|
||||
resultList.remove(path);
|
||||
mSubmitButton.setText("完成("+resultList.size()+"/"+mDefaultCount+")");
|
||||
}
|
||||
// 当为选择图片时候的状态
|
||||
if(resultList.size() == 0){
|
||||
mSubmitButton.setText("完成");
|
||||
mSubmitButton.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCameraShot(File imageFile) {
|
||||
if(imageFile != null) {
|
||||
Intent data = new Intent();
|
||||
resultList.add(imageFile.getAbsolutePath());
|
||||
data.putStringArrayListExtra(EXTRA_RESULT, resultList);
|
||||
setResult(RESULT_OK, data);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,440 @@
|
|||
package me.nereo.multi_image_selector;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.MediaStore;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.CursorLoader;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v7.widget.ListPopupWindow;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.widget.AbsListView;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.Button;
|
||||
import android.widget.GridView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.squareup.picasso.Picasso;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import me.nereo.multi_image_selector.adapter.FolderAdapter;
|
||||
import me.nereo.multi_image_selector.adapter.ImageGridAdapter;
|
||||
import me.nereo.multi_image_selector.bean.Folder;
|
||||
import me.nereo.multi_image_selector.bean.Image;
|
||||
import me.nereo.multi_image_selector.utils.FileUtils;
|
||||
import me.nereo.multi_image_selector.utils.TimeUtils;
|
||||
|
||||
/**
|
||||
* 图片选择Fragment
|
||||
* Created by Nereo on 2015/4/7.
|
||||
*/
|
||||
public class MultiImageSelectorFragment extends Fragment {
|
||||
|
||||
/** 最大图片选择次数,int类型 */
|
||||
public static final String EXTRA_SELECT_COUNT = "max_select_count";
|
||||
/** 图片选择模式,int类型 */
|
||||
public static final String EXTRA_SELECT_MODE = "select_count_mode";
|
||||
/** 是否显示相机,boolean类型 */
|
||||
public static final String EXTRA_SHOW_CAMERA = "show_camera";
|
||||
/** 单选 */
|
||||
public static final int MODE_SINGLE = 0;
|
||||
/** 多选 */
|
||||
public static final int MODE_MULTI = 1;
|
||||
// 不同loader定义
|
||||
private static final int LOADER_ALL = 0;
|
||||
private static final int LOADER_CATEGORY = 1;
|
||||
// 请求加载系统照相机
|
||||
private static final int REQUEST_CAMERA = 100;
|
||||
|
||||
// 结果数据
|
||||
private ArrayList<String> resultList = new ArrayList<>();
|
||||
// 文件夹数据
|
||||
private ArrayList<Folder> mResultFolder = new ArrayList<>();
|
||||
|
||||
// 图片Grid
|
||||
private GridView mGridView;
|
||||
private Callback mCallback;
|
||||
|
||||
private ImageGridAdapter mImageAdapter;
|
||||
private FolderAdapter mFolderAdapter;
|
||||
|
||||
private ListPopupWindow mFolderPopupWindow;
|
||||
|
||||
// 时间线
|
||||
private TextView mTimeLineText;
|
||||
// 类别
|
||||
private TextView mCategoryText;
|
||||
// 预览按钮
|
||||
private Button mPreviewBtn;
|
||||
// 底部View
|
||||
private View mPopupAnchorView;
|
||||
|
||||
private int mDesireImageCount;
|
||||
|
||||
private boolean hasFolderGened = false;
|
||||
|
||||
private File mTmpFile;
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
try {
|
||||
mCallback = (Callback) activity;
|
||||
}catch (ClassCastException e){
|
||||
throw new ClassCastException("The Activity must implement MultiImageSelectorFragment.Callback interface...");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.fragment_multi_image, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
// 选择图片数量
|
||||
mDesireImageCount = getArguments().getInt(EXTRA_SELECT_COUNT);
|
||||
|
||||
// 图片选择模式
|
||||
final int mode = getArguments().getInt(EXTRA_SELECT_MODE);
|
||||
|
||||
// 是否显示照相机
|
||||
final boolean showCamera = getArguments().getBoolean(EXTRA_SHOW_CAMERA, true);
|
||||
mImageAdapter = new ImageGridAdapter(getActivity(), showCamera);
|
||||
// 是否显示选择指示器
|
||||
mImageAdapter.showSelectIndicator(mode == MODE_MULTI);
|
||||
|
||||
// 如果显示了照相机,则创建临时文件
|
||||
if(showCamera){
|
||||
mTmpFile = FileUtils.createTmpFile(getActivity());
|
||||
}
|
||||
|
||||
mPopupAnchorView = view.findViewById(R.id.footer);
|
||||
|
||||
mTimeLineText = (TextView) view.findViewById(R.id.timeline_area);
|
||||
// 初始化,先隐藏当前timeline
|
||||
mTimeLineText.setVisibility(View.GONE);
|
||||
|
||||
mCategoryText = (TextView) view.findViewById(R.id.category_btn);
|
||||
// 初始化,加载所有图片
|
||||
mCategoryText.setText("所有图片");
|
||||
mCategoryText.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if(mFolderPopupWindow.isShowing()){
|
||||
mFolderPopupWindow.dismiss();
|
||||
}else {
|
||||
mFolderPopupWindow.show();
|
||||
int index = mFolderAdapter.getSelectIndex();
|
||||
index = index == 0 ? index : index - 1;
|
||||
mFolderPopupWindow.getListView().setSelection(index);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mPreviewBtn = (Button) view.findViewById(R.id.preview);
|
||||
// 初始化,按钮状态初始化
|
||||
if(resultList == null || resultList.size()<=0){
|
||||
mPreviewBtn.setText("预览");
|
||||
mPreviewBtn.setEnabled(false);
|
||||
}
|
||||
mPreviewBtn.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
// TODO 预览
|
||||
}
|
||||
});
|
||||
|
||||
mGridView = (GridView) view.findViewById(R.id.grid);
|
||||
mGridView.setOnScrollListener(new AbsListView.OnScrollListener() {
|
||||
@Override
|
||||
public void onScrollStateChanged(AbsListView absListView, int state) {
|
||||
|
||||
final Picasso picasso = Picasso.with(getActivity());
|
||||
if(state == SCROLL_STATE_IDLE || state == SCROLL_STATE_TOUCH_SCROLL){
|
||||
picasso.resumeTag(getActivity());
|
||||
}else{
|
||||
picasso.pauseTag(getActivity());
|
||||
}
|
||||
|
||||
if(state == SCROLL_STATE_IDLE){
|
||||
// 停止滑动,日期指示器消失
|
||||
mTimeLineText.setVisibility(View.GONE);
|
||||
}else if(state == SCROLL_STATE_FLING){
|
||||
mTimeLineText.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
|
||||
if(mTimeLineText.getVisibility() == View.VISIBLE) {
|
||||
int index = firstVisibleItem + 1 == view.getAdapter().getCount() ? view.getAdapter().getCount() - 1 : firstVisibleItem + 1;
|
||||
Image image = (Image) view.getAdapter().getItem(index);
|
||||
if (image != null) {
|
||||
mTimeLineText.setText(TimeUtils.formatPhotoDate(image.path));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
mGridView.setAdapter(mImageAdapter);
|
||||
mGridView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
@Override @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
|
||||
public void onGlobalLayout() {
|
||||
final int numCount = mGridView.getNumColumns();
|
||||
final int columnSpace = getResources().getDimensionPixelOffset(R.dimen.space_size);
|
||||
int columnWidth = (mGridView.getWidth() - columnSpace*(numCount-1)) / numCount;
|
||||
mImageAdapter.setItemSize(columnWidth);
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN){
|
||||
mGridView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||
}else{
|
||||
mGridView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
|
||||
}
|
||||
}
|
||||
});
|
||||
mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
|
||||
if(showCamera){
|
||||
// 如果显示照相机,则第一个Grid显示为照相机,处理特殊逻辑
|
||||
if(i == 0){
|
||||
showCameraAction();
|
||||
}else{
|
||||
// 正常操作
|
||||
Image image = (Image) adapterView.getAdapter().getItem(i);
|
||||
selectImageFromGrid(image, mode);
|
||||
}
|
||||
}else{
|
||||
// 正常操作
|
||||
Image image = (Image) adapterView.getAdapter().getItem(i);
|
||||
selectImageFromGrid(image, mode);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mFolderAdapter = new FolderAdapter(getActivity());
|
||||
createPopupFolderList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建弹出的ListView
|
||||
*/
|
||||
private void createPopupFolderList() {
|
||||
mFolderPopupWindow = new ListPopupWindow(getActivity());
|
||||
// mFolderPopupWindow.getListView().setDividerHeight(1);
|
||||
// mFolderPopupWindow.getListView().setDivider(new ColorDrawable(Color.parseColor("#CCCCCC")));
|
||||
mFolderPopupWindow.setAdapter(mFolderAdapter);
|
||||
int sWidthPix = getResources().getDisplayMetrics().widthPixels;
|
||||
mFolderPopupWindow.setContentWidth(sWidthPix);
|
||||
mFolderPopupWindow.setHeight(sWidthPix);
|
||||
mFolderPopupWindow.setAnchorView(mPopupAnchorView);
|
||||
mFolderPopupWindow.setModal(true);
|
||||
mFolderPopupWindow.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
|
||||
if(i == 0){
|
||||
getActivity().getSupportLoaderManager().restartLoader(LOADER_ALL, null, mLoaderCallback);
|
||||
mCategoryText.setText("所有照片");
|
||||
mImageAdapter.setShowCamera(true);
|
||||
}else {
|
||||
Folder folder = (Folder) adapterView.getAdapter().getItem(i);
|
||||
if (null != folder) {
|
||||
Bundle args = new Bundle();
|
||||
args.putString("path", folder.path);
|
||||
getActivity().getSupportLoaderManager().restartLoader(LOADER_CATEGORY, args, mLoaderCallback);
|
||||
mCategoryText.setText(folder.name);
|
||||
}
|
||||
mImageAdapter.setShowCamera(false);
|
||||
}
|
||||
mFolderAdapter.setSelectIndex(i);
|
||||
mFolderPopupWindow.dismiss();
|
||||
|
||||
// 滑动到最初始位置
|
||||
mGridView.smoothScrollToPosition(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
// 首次加载所有图片
|
||||
//new LoadImageTask().execute();
|
||||
getActivity().getSupportLoaderManager().initLoader(LOADER_ALL, null, mLoaderCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
// 相机拍照完成后,返回图片路径
|
||||
if(resultCode == Activity.RESULT_OK) {
|
||||
if(requestCode == REQUEST_CAMERA){
|
||||
if (mTmpFile != null) {
|
||||
if (mCallback != null) {
|
||||
mCallback.onCameraShot(mTmpFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 选择相机
|
||||
*/
|
||||
private void showCameraAction() {
|
||||
// 跳转到系统照相机
|
||||
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
|
||||
if(cameraIntent.resolveActivity(getActivity().getPackageManager()) != null){
|
||||
// 设置系统相机拍照后的输出路径
|
||||
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTmpFile));
|
||||
startActivityForResult(cameraIntent, REQUEST_CAMERA);
|
||||
}else{
|
||||
Toast.makeText(getActivity(), "没有系统相机", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 选择图片操作
|
||||
* @param image
|
||||
*/
|
||||
private void selectImageFromGrid(Image image, int mode) {
|
||||
if(image != null) {
|
||||
// 多选模式
|
||||
if(mode == MODE_MULTI) {
|
||||
if (resultList.contains(image.path)) {
|
||||
resultList.remove(image.path);
|
||||
if(resultList.size() != 0) {
|
||||
mPreviewBtn.setEnabled(true);
|
||||
mPreviewBtn.setText("预览(" + resultList.size() + ")");
|
||||
}else{
|
||||
mPreviewBtn.setEnabled(false);
|
||||
mPreviewBtn.setText("预览");
|
||||
}
|
||||
if (mCallback != null) {
|
||||
mCallback.onImageUnselected(image.path);
|
||||
}
|
||||
} else {
|
||||
// 判断选择数量问题
|
||||
if(mDesireImageCount == resultList.size()){
|
||||
Toast.makeText(getActivity(), "已经达到最高选择数量了…", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
resultList.add(image.path);
|
||||
mPreviewBtn.setEnabled(true);
|
||||
mPreviewBtn.setText("预览(" + resultList.size() + ")");
|
||||
if (mCallback != null) {
|
||||
mCallback.onImageSelected(image.path);
|
||||
}
|
||||
}
|
||||
mImageAdapter.select(image);
|
||||
}else if(mode == MODE_SINGLE){
|
||||
// 单选模式
|
||||
if(mCallback != null){
|
||||
mCallback.onSingleImageSelected(image.path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private LoaderManager.LoaderCallbacks<Cursor> mLoaderCallback = new LoaderManager.LoaderCallbacks<Cursor>() {
|
||||
|
||||
private final String[] IMAGE_PROJECTION = {
|
||||
MediaStore.Images.Media.DATA,
|
||||
MediaStore.Images.Media.DISPLAY_NAME,
|
||||
MediaStore.Images.Media.DATE_ADDED,
|
||||
MediaStore.Images.Media._ID };
|
||||
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||
if(id == LOADER_ALL) {
|
||||
CursorLoader cursorLoader = new CursorLoader(getActivity(),
|
||||
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_PROJECTION,
|
||||
null, null, IMAGE_PROJECTION[2] + " DESC");
|
||||
return cursorLoader;
|
||||
}else if(id == LOADER_CATEGORY){
|
||||
CursorLoader cursorLoader = new CursorLoader(getActivity(),
|
||||
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_PROJECTION,
|
||||
IMAGE_PROJECTION[0]+" like '%"+args.getString("path")+"%'", null, IMAGE_PROJECTION[2] + " DESC");
|
||||
return cursorLoader;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
|
||||
if (data != null) {
|
||||
List<Image> images = new ArrayList<>();
|
||||
int count = data.getCount();
|
||||
if (count > 0) {
|
||||
data.moveToFirst();
|
||||
do{
|
||||
String path = data.getString(data.getColumnIndexOrThrow(IMAGE_PROJECTION[0]));
|
||||
String name = data.getString(data.getColumnIndexOrThrow(IMAGE_PROJECTION[1]));
|
||||
long dateTime = data.getLong(data.getColumnIndexOrThrow(IMAGE_PROJECTION[2]));
|
||||
Image image = new Image(path, name, dateTime);
|
||||
images.add(image);
|
||||
if( !hasFolderGened ) {
|
||||
// 获取文件夹名称
|
||||
File imageFile = new File(path);
|
||||
File folderFile = imageFile.getParentFile();
|
||||
Folder folder = new Folder();
|
||||
folder.name = folderFile.getName();
|
||||
folder.path = folderFile.getAbsolutePath();
|
||||
folder.cover = image;
|
||||
if (!mResultFolder.contains(folder)) {
|
||||
List<Image> imageList = new ArrayList<>();
|
||||
imageList.add(image);
|
||||
folder.images = imageList;
|
||||
mResultFolder.add(folder);
|
||||
} else {
|
||||
// 更新
|
||||
Folder f = mResultFolder.get(mResultFolder.indexOf(folder));
|
||||
f.images.add(image);
|
||||
}
|
||||
}
|
||||
|
||||
}while(data.moveToNext());
|
||||
|
||||
mImageAdapter.setData(images);
|
||||
mFolderAdapter.setData(mResultFolder);
|
||||
hasFolderGened = true;
|
||||
|
||||
} else {
|
||||
System.out.println("no image found");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<Cursor> loader) {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 回调接口
|
||||
*/
|
||||
public interface Callback{
|
||||
public void onSingleImageSelected(String path);
|
||||
public void onImageSelected(String path);
|
||||
public void onImageUnselected(String path);
|
||||
public void onCameraShot(File imageFile);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
package me.nereo.multi_image_selector.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.squareup.picasso.Picasso;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import me.nereo.multi_image_selector.R;
|
||||
import me.nereo.multi_image_selector.bean.Folder;
|
||||
|
||||
/**
|
||||
* 文件夹Adapter
|
||||
* Created by Nereo on 2015/4/7.
|
||||
*/
|
||||
public class FolderAdapter extends BaseAdapter {
|
||||
|
||||
private Context mContext;
|
||||
private LayoutInflater mInflater;
|
||||
|
||||
private List<Folder> mFolders = new ArrayList<>();
|
||||
|
||||
int mImageSize;
|
||||
|
||||
int lastSelected = 0;
|
||||
|
||||
public FolderAdapter(Context context){
|
||||
mContext = context;
|
||||
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
mImageSize = mContext.getResources().getDimensionPixelOffset(R.dimen.folder_cover_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置数据集
|
||||
* @param folders
|
||||
*/
|
||||
public void setData(List<Folder> folders) {
|
||||
if(folders != null && folders.size()>0){
|
||||
mFolders = folders;
|
||||
}else{
|
||||
mFolders.clear();
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mFolders.size()+1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Folder getItem(int i) {
|
||||
if(i == 0) return null;
|
||||
return mFolders.get(i-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int i) {
|
||||
return i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int i, View view, ViewGroup viewGroup) {
|
||||
ViewHolder holder;
|
||||
if(view == null){
|
||||
view = mInflater.inflate(R.layout.list_item_folder, viewGroup, false);
|
||||
holder = new ViewHolder(view);
|
||||
}else{
|
||||
holder = (ViewHolder) view.getTag();
|
||||
}
|
||||
if (holder != null) {
|
||||
if(i == 0){
|
||||
holder.name.setText("所有图片");
|
||||
holder.size.setText(getTotalImageSize()+"张");
|
||||
if(mFolders.size()>0){
|
||||
Folder f = mFolders.get(0);
|
||||
Picasso.with(mContext)
|
||||
.load(new File(f.cover.path))
|
||||
.error(R.drawable.default_error)
|
||||
.resize(mImageSize, mImageSize)
|
||||
.centerCrop()
|
||||
.into(holder.cover);
|
||||
}
|
||||
}else {
|
||||
holder.bindData(getItem(i));
|
||||
}
|
||||
if(lastSelected == i){
|
||||
holder.indicator.setVisibility(View.VISIBLE);
|
||||
}else{
|
||||
holder.indicator.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
private int getTotalImageSize(){
|
||||
int result = 0;
|
||||
if(mFolders != null && mFolders.size()>0){
|
||||
for (Folder f: mFolders){
|
||||
result += f.images.size();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setSelectIndex(int i) {
|
||||
if(lastSelected == i) return;
|
||||
|
||||
lastSelected = i;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public int getSelectIndex(){
|
||||
return lastSelected;
|
||||
}
|
||||
|
||||
class ViewHolder{
|
||||
ImageView cover;
|
||||
TextView name;
|
||||
TextView size;
|
||||
ImageView indicator;
|
||||
ViewHolder(View view){
|
||||
cover = (ImageView)view.findViewById(R.id.cover);
|
||||
name = (TextView) view.findViewById(R.id.name);
|
||||
size = (TextView) view.findViewById(R.id.size);
|
||||
indicator = (ImageView) view.findViewById(R.id.indicator);
|
||||
view.setTag(this);
|
||||
}
|
||||
|
||||
void bindData(Folder data) {
|
||||
name.setText(data.name);
|
||||
size.setText(data.images.size()+"张");
|
||||
// 显示图片
|
||||
Picasso.with(mContext)
|
||||
.load(new File(data.cover.path))
|
||||
.error(R.drawable.default_error)
|
||||
.resize(mImageSize, mImageSize)
|
||||
.centerCrop()
|
||||
.into(cover);
|
||||
// TODO 选择标识
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,234 @@
|
|||
package me.nereo.multi_image_selector.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.GridView;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.squareup.picasso.Callback;
|
||||
import com.squareup.picasso.Picasso;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import me.nereo.multi_image_selector.R;
|
||||
import me.nereo.multi_image_selector.bean.Image;
|
||||
|
||||
/**
|
||||
* 图片Adapter
|
||||
* Created by Nereo on 2015/4/7.
|
||||
*/
|
||||
public class ImageGridAdapter extends BaseAdapter {
|
||||
|
||||
private static final int TYPE_CAMERA = 0;
|
||||
private static final int TYPE_NORMAL = 1;
|
||||
|
||||
private Context mContext;
|
||||
|
||||
private LayoutInflater mInflater;
|
||||
private boolean showCamera = true;
|
||||
private boolean showSelectIndicator = true;
|
||||
private boolean justChangeIndicator = false;
|
||||
|
||||
private List<Image> mImages = new ArrayList<>();
|
||||
private List<Image> mSelectedImages = new ArrayList<>();
|
||||
|
||||
private int mItemSize;
|
||||
private GridView.LayoutParams mItemLayoutParams;
|
||||
|
||||
public ImageGridAdapter(Context context, boolean showCamera){
|
||||
mContext = context;
|
||||
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
this.showCamera = showCamera;
|
||||
mItemLayoutParams = new GridView.LayoutParams(GridView.LayoutParams.MATCH_PARENT, GridView.LayoutParams.MATCH_PARENT);
|
||||
}
|
||||
/**
|
||||
* 显示选择指示器
|
||||
* @param b
|
||||
*/
|
||||
public void showSelectIndicator(boolean b) {
|
||||
showSelectIndicator = b;
|
||||
}
|
||||
|
||||
public void setShowCamera(boolean b){
|
||||
if(showCamera == b) return;
|
||||
|
||||
showCamera = b;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 选择某个图片,改变选择状态
|
||||
* @param image
|
||||
*/
|
||||
public void select(Image image) {
|
||||
if(mSelectedImages.contains(image)){
|
||||
mSelectedImages.remove(image);
|
||||
}else{
|
||||
mSelectedImages.add(image);
|
||||
}
|
||||
justChangeIndicator = true;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置数据集
|
||||
* @param images
|
||||
*/
|
||||
public void setData(List<Image> images) {
|
||||
mSelectedImages.clear();
|
||||
justChangeIndicator = false;
|
||||
|
||||
if(images != null && images.size()>0){
|
||||
mImages = images;
|
||||
}else{
|
||||
mImages.clear();
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置每个Column的Size
|
||||
* @param columnWidth
|
||||
*/
|
||||
public void setItemSize(int columnWidth) {
|
||||
|
||||
if(mItemSize == columnWidth){
|
||||
return;
|
||||
}
|
||||
|
||||
mItemSize = columnWidth;
|
||||
|
||||
mItemLayoutParams = new GridView.LayoutParams(mItemSize, mItemSize);
|
||||
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewTypeCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if(showCamera){
|
||||
return position==0 ? TYPE_CAMERA : TYPE_NORMAL;
|
||||
}
|
||||
return TYPE_NORMAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return showCamera ? mImages.size()+1 : mImages.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image getItem(int i) {
|
||||
if(showCamera){
|
||||
if(i == 0){
|
||||
return null;
|
||||
}
|
||||
return mImages.get(i-1);
|
||||
}else{
|
||||
return mImages.get(i);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int i) {
|
||||
return i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int i, View view, ViewGroup viewGroup) {
|
||||
/* ViewHolde holde = null;
|
||||
|
||||
if(showCamera){
|
||||
int type = getItemViewType(i);
|
||||
if(view == null){
|
||||
|
||||
view = mInflater.inflate(R.layout.list_item_camera, viewGroup, false);
|
||||
}else{
|
||||
|
||||
}
|
||||
}else{
|
||||
if(view == null){
|
||||
view = mInflater.inflate(R.layout.list_item_image, viewGroup, false);
|
||||
holde = new ViewHolde(view);
|
||||
}else{
|
||||
holde = (ViewHolde) view.getTag();
|
||||
}
|
||||
}
|
||||
// 绑定数据
|
||||
if(holde != null) {
|
||||
holde.bindData(getItem(i));
|
||||
}*/
|
||||
|
||||
int type = getItemViewType(i);
|
||||
if(type == TYPE_CAMERA){
|
||||
view = mInflater.inflate(R.layout.list_item_camera, viewGroup, false);
|
||||
}else if(type == TYPE_NORMAL){
|
||||
ViewHolde holde;
|
||||
if(view == null){
|
||||
view = mInflater.inflate(R.layout.list_item_image, viewGroup, false);
|
||||
holde = new ViewHolde(view);
|
||||
}else{
|
||||
holde = (ViewHolde) view.getTag();
|
||||
if(holde == null){
|
||||
view = mInflater.inflate(R.layout.list_item_image, viewGroup, false);
|
||||
holde = new ViewHolde(view);
|
||||
}
|
||||
}
|
||||
if(holde != null) {
|
||||
holde.bindData(getItem(i));
|
||||
}
|
||||
}
|
||||
GridView.LayoutParams lp = (GridView.LayoutParams) view.getLayoutParams();
|
||||
if(lp.height != mItemSize){
|
||||
view.setLayoutParams(mItemLayoutParams);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
class ViewHolde {
|
||||
ImageView image;
|
||||
ImageView indicator;
|
||||
|
||||
ViewHolde(View view){
|
||||
image = (ImageView) view.findViewById(R.id.image);
|
||||
indicator = (ImageView) view.findViewById(R.id.checkmark);
|
||||
view.setTag(this);
|
||||
}
|
||||
|
||||
void bindData(final Image data){
|
||||
if(data == null) return;
|
||||
// 处理单选和多选状态
|
||||
if(showSelectIndicator){
|
||||
indicator.setVisibility(View.VISIBLE);
|
||||
if(mSelectedImages.contains(data)){
|
||||
// 设置选中状态
|
||||
indicator.setImageResource(R.drawable.btn_selected);
|
||||
}else{
|
||||
// 未选择
|
||||
indicator.setImageResource(R.drawable.btn_unselected);
|
||||
}
|
||||
}else{
|
||||
indicator.setVisibility(View.GONE);
|
||||
}
|
||||
File imageFile = new File(data.path);
|
||||
// 显示图片
|
||||
Picasso.with(mContext)
|
||||
.load(imageFile)
|
||||
.placeholder(R.drawable.default_error)
|
||||
.error(R.drawable.default_error)
|
||||
.resize(mItemSize, mItemSize)
|
||||
.centerCrop()
|
||||
.into(image);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package me.nereo.multi_image_selector.bean;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 文件夹
|
||||
* Created by Nereo on 2015/4/7.
|
||||
*/
|
||||
public class Folder {
|
||||
public String name;
|
||||
public String path;
|
||||
public Image cover;
|
||||
public List<Image> images;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
try {
|
||||
Folder other = (Folder) o;
|
||||
return this.path.equalsIgnoreCase(other.path);
|
||||
}catch (ClassCastException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
return super.equals(o);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package me.nereo.multi_image_selector.bean;
|
||||
|
||||
/**
|
||||
* 图片实体
|
||||
* Created by Nereo on 2015/4/7.
|
||||
*/
|
||||
public class Image {
|
||||
public String path;
|
||||
public String name;
|
||||
public long time;
|
||||
|
||||
public Image(String path, String name, long time){
|
||||
this.path = path;
|
||||
this.name = name;
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
try {
|
||||
Image other = (Image) o;
|
||||
return this.path.equalsIgnoreCase(other.path);
|
||||
}catch (ClassCastException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
return super.equals(o);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package me.nereo.multi_image_selector.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Environment;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* 文件操作类
|
||||
* Created by Nereo on 2015/4/8.
|
||||
*/
|
||||
public class FileUtils {
|
||||
|
||||
public static File createTmpFile(Context context){
|
||||
|
||||
String state = Environment.getExternalStorageState();
|
||||
if(state.equals(Environment.MEDIA_MOUNTED)){
|
||||
// 已挂载
|
||||
File pic = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
|
||||
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(new Date());
|
||||
String fileName = "multi_image_"+timeStamp+"";
|
||||
File tmpFile = new File(pic, fileName+".jpg");
|
||||
return tmpFile;
|
||||
}else{
|
||||
File cacheDir = context.getCacheDir();
|
||||
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.CHINA).format(new Date());
|
||||
String fileName = "multi_image_"+timeStamp+"";
|
||||
File tmpFile = new File(cacheDir, fileName+".jpg");
|
||||
return tmpFile;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package me.nereo.multi_image_selector.utils;
|
||||
|
||||
import android.media.ExifInterface;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* 时间处理工具
|
||||
* Created by Nereo on 2015/4/8.
|
||||
*/
|
||||
public class TimeUtils {
|
||||
|
||||
public static String timeFormat(long timeMillis, String pattern){
|
||||
SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.CHINA);
|
||||
return format.format(new Date(timeMillis));
|
||||
}
|
||||
|
||||
public static String formatPhotoDate(long time){
|
||||
return timeFormat(time, "yyyy年MM月dd日");
|
||||
}
|
||||
|
||||
public static String formatPhotoDate(String path){
|
||||
File file = new File(path);
|
||||
if(file.exists()){
|
||||
long time = file.lastModified();
|
||||
return formatPhotoDate(time);
|
||||
}
|
||||
return "1970-01-01";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="#CDCECE" android:state_enabled="false" />
|
||||
<item android:color="#FFFFFF" android:state_enabled="true" />
|
||||
<item android:color="#CDCECE" android:state_pressed="false" />
|
||||
<item android:color="#FFFFFF" android:state_pressed="true" />
|
||||
<item android:color="#CDCECE" />
|
||||
</selector>
|
||||
|
After Width: | Height: | Size: 603 B |
|
After Width: | Height: | Size: 642 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 333 B |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 362 B |
|
After Width: | Height: | Size: 986 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 191 B |
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_pressed="true">
|
||||
<shape android:shape="rectangle">
|
||||
<corners android:radius="2dp" />
|
||||
<solid android:color="#44BF1A" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<item android:state_enabled="true">
|
||||
<shape android:shape="rectangle">
|
||||
<corners android:radius="2dp" />
|
||||
<solid android:color="#44BF1A" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<item android:state_enabled="false">
|
||||
<shape android:shape="rectangle">
|
||||
<corners android:radius="2dp" />
|
||||
<solid android:color="#337523" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<corners android:radius="2dp" />
|
||||
<solid android:color="#337523" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
</selector>
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent" android:layout_height="match_parent">
|
||||
|
||||
|
||||
<include
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?android:attr/actionBarSize"
|
||||
layout="@layout/cmp_customer_actionbar" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/image_grid"
|
||||
android:background="#181819"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical" android:layout_width="match_parent"
|
||||
android:background="#21282C"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/btn_back"
|
||||
android:src="@drawable/btn_back"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:text="图片"
|
||||
android:layout_toRightOf="@+id/btn_back"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="20sp"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/commit"
|
||||
android:background="@drawable/action_btn"
|
||||
android:minHeight="1dp"
|
||||
android:minWidth="1dp"
|
||||
android:text="完成"
|
||||
android:layout_marginRight="16dp"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp"
|
||||
android:paddingTop="5dp"
|
||||
android:paddingBottom="5dp"
|
||||
android:textColor="@color/default_text_color"
|
||||
android:textSize="14sp"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<GridView
|
||||
android:id="@+id/grid"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:horizontalSpacing="@dimen/space_size"
|
||||
android:verticalSpacing="@dimen/space_size"
|
||||
android:paddingBottom="48dp"
|
||||
android:clipToPadding="false"
|
||||
android:numColumns="3"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/timeline_area"
|
||||
tools:text="2015年4月1日"
|
||||
android:textColor="#CDCECE"
|
||||
android:textSize="14sp"
|
||||
android:paddingLeft="10sp"
|
||||
android:paddingTop="5dp"
|
||||
android:paddingBottom="5dp"
|
||||
android:background="#cc000000"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<RelativeLayout
|
||||
android:clickable="true"
|
||||
android:id="@+id/footer"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:background="#cc000000"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/category_btn"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:layout_centerVertical="true"
|
||||
android:textColor="#CDCECE"
|
||||
tools:text="所有图片"
|
||||
android:textSize="16sp"
|
||||
android:gravity="center"
|
||||
android:drawableRight="@drawable/text_indicator"
|
||||
android:drawablePadding="5dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<View
|
||||
android:layout_toLeftOf="@+id/preview"
|
||||
android:layout_width="1dp"
|
||||
android:background="#8828292A"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<Button
|
||||
android:visibility="gone"
|
||||
android:id="@+id/preview"
|
||||
tools:text="预览(1)"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:minHeight="1dp"
|
||||
android:minWidth="1dp"
|
||||
android:background="@null"
|
||||
android:textColor="@color/default_text_color"
|
||||
android:textSize="14sp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:background="#343535"
|
||||
android:layout_width="match_parent" android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:drawableTop="@drawable/asy"
|
||||
android:drawablePadding="10dp"
|
||||
android:layout_gravity="center"
|
||||
android:text="拍摄照片"
|
||||
android:textSize="14sp"
|
||||
android:textColor="#CDCECE"
|
||||
android:gravity="center_horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</FrameLayout>
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingRight="10dp"
|
||||
android:background="@android:color/white"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/cover"
|
||||
tools:src="@drawable/btn_back"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:scaleType="centerCrop"
|
||||
android:layout_width="@dimen/folder_cover_size"
|
||||
android:layout_height="@dimen/folder_cover_size" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_marginLeft="16dp"
|
||||
android:orientation="vertical"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/name"
|
||||
tools:text="img"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@android:color/black"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/size"
|
||||
tools:text="1张"
|
||||
android:layout_marginTop="5dp"
|
||||
android:textSize="12sp"
|
||||
android:textColor="#AFAFAF"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/indicator"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:src="@drawable/default_check"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent" android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image"
|
||||
android:scaleType="centerCrop"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/checkmark"
|
||||
android:layout_gravity="top|right"
|
||||
android:layout_marginTop="5.5dp"
|
||||
android:layout_marginRight="5.5dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/btn_unselected"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<dimen name="space_size">2dp</dimen>
|
||||
<dimen name="folder_cover_size">72dp</dimen>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<resources>
|
||||
<string name="app_name">multi-image-selector</string>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1 @@
|
|||
include ':app', ':multi-image-selector'
|
||||