Android BottomSheet:以选取图片为例(2)

附录文章5简单介绍了常见的分享面板在BottomSheet中的具体应用。本文再以常见的选取图片为例写一个例子。

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<com.flipboard.bottomsheet.BottomSheetLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/bottomsheet"
android:layout_width="match_parent"
android:layout_height="match_parent"> <RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"> <Button
android:id="@+id/image_picker_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|top"
android:layout_marginBottom="16dp"
android:text="选择"
/> <ImageView
android:id="@+id/image_picker_selected"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:layout_below="@id/image_picker_button"
/> </RelativeLayout> </com.flipboard.bottomsheet.BottomSheetLayout>

上层Java代码:

package zhangphil.demo;

import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast; import com.bumptech.glide.Glide;
import com.flipboard.bottomsheet.BottomSheetLayout;
import com.flipboard.bottomsheet.commons.ImagePickerSheetView; import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale; public class MainActivity extends AppCompatActivity { private static final int REQUEST_STORAGE = 0;
private static final int REQUEST_IMAGE_CAPTURE = REQUEST_STORAGE + 1;
private static final int REQUEST_LOAD_IMAGE = REQUEST_IMAGE_CAPTURE + 1;
protected BottomSheetLayout bottomSheetLayout;
private Uri cameraImageUri = null;
private ImageView selectedImage; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bottomSheetLayout = (BottomSheetLayout) findViewById(R.id.bottomsheet);
bottomSheetLayout.setPeekOnDismiss(true);
selectedImage = (ImageView) findViewById(R.id.image_picker_selected);
findViewById(R.id.image_picker_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (checkNeedsPermission()) {
requestStoragePermission();
} else {
showSheetView();
}
}
});
} private boolean checkNeedsPermission() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED;
} @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void requestStoragePermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_STORAGE);
} else {
// Eh, prompt anyway
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_STORAGE);
}
} @TargetApi(Build.VERSION_CODES.M)
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == REQUEST_STORAGE) {
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
showSheetView();
} else {
// Permission denied
Toast.makeText(this, "Sheet is useless without access to external storage :/", Toast.LENGTH_SHORT).show();
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
} /**
* Show an {@link ImagePickerSheetView}
*/
private void showSheetView() {
ImagePickerSheetView sheetView = new ImagePickerSheetView.Builder(this)
.setMaxItems(30)
.setShowCameraOption(createCameraIntent() != null)
.setShowPickerOption(createPickIntent() != null)
.setImageProvider(new ImagePickerSheetView.ImageProvider() {
@Override
public void onProvideImage(ImageView imageView, Uri imageUri, int size) {
Glide.with(MainActivity.this)
.load(imageUri)
.centerCrop()
.crossFade()
.into(imageView);
}
})
.setOnTileSelectedListener(new ImagePickerSheetView.OnTileSelectedListener() {
@Override
public void onTileSelected(ImagePickerSheetView.ImagePickerTile selectedTile) {
bottomSheetLayout.dismissSheet();
if (selectedTile.isCameraTile()) {
dispatchTakePictureIntent();
} else if (selectedTile.isPickerTile()) {
startActivityForResult(createPickIntent(), REQUEST_LOAD_IMAGE);
} else if (selectedTile.isImageTile()) {
showSelectedImage(selectedTile.getImageUri());
} else {
genericError();
}
}
})
.setTitle("选择一张照片...")
.create(); bottomSheetLayout.showWithSheetView(sheetView);
} /**
* For images captured from the camera, we need to create a File first to tell the camera
* where to store the image.
*
* @return the File created for the image to be store under.
*/
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File imageFile = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
); // Save a file: path for use with ACTION_VIEW intents
cameraImageUri = Uri.fromFile(imageFile);
return imageFile;
} /**
* This checks to see if there is a suitable activity to handle the `ACTION_PICK` intent
* and returns it if found. {@link Intent#ACTION_PICK} is for picking an image from an external app.
*
* @return A prepared intent if found.
*/
@Nullable
private Intent createPickIntent() {
Intent picImageIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
if (picImageIntent.resolveActivity(getPackageManager()) != null) {
return picImageIntent;
} else {
return null;
}
} /**
* This checks to see if there is a suitable activity to handle the {@link MediaStore#ACTION_IMAGE_CAPTURE}
* intent and returns it if found. {@link MediaStore#ACTION_IMAGE_CAPTURE} is for letting another app take
* a picture from the camera and store it in a file that we specify.
*
* @return A prepared intent if found.
*/
@Nullable
private Intent createCameraIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
return takePictureIntent;
} else {
return null;
}
} /**
* This utility function combines the camera intent creation and image file creation, and
* ultimately fires the intent.
*
* @see {@link #createCameraIntent()}
* @see {@link #createImageFile()}
*/
private void dispatchTakePictureIntent() {
Intent takePictureIntent = createCameraIntent();
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent != null) {
// Create the File where the photo should go
try {
File imageFile = createImageFile();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(imageFile));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
} catch (IOException e) {
// Error occurred while creating the File
genericError("Could not create imageFile for camera");
}
}
} @Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
Uri selectedImage = null;
if (requestCode == REQUEST_LOAD_IMAGE && data != null) {
selectedImage = data.getData();
if (selectedImage == null) {
genericError();
}
} else if (requestCode == REQUEST_IMAGE_CAPTURE) {
// Do something with imagePath
selectedImage = cameraImageUri;
} if (selectedImage != null) {
showSelectedImage(selectedImage);
} else {
genericError();
}
}
} private void showSelectedImage(Uri selectedImageUri) {
selectedImage.setImageDrawable(null);
Glide.with(this)
.load(selectedImageUri)
.crossFade()
.fitCenter()
.into(selectedImage);
} private void genericError() {
genericError(null);
} private void genericError(String message) {
Toast.makeText(this, message == null ? "Something went wrong." : message, Toast.LENGTH_SHORT).show();
} }

由于需要读取设备图象文件,须增加权限:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

本例中在加载图片时候使用了Glide,关于Glide,请查阅附录文章4。

代码运行结果--->

初始化状态:

点击button按钮弹出选择面板:

拖曳向上铺满窗口:

本例中的照片选取代码是一个相对比较独立、可以单独抽取出去的通用模块化代码,支持从图库中选取,也支持调用相机拍照出图,在其他项目中使用,只需要关注诸如本例中的button按钮事件以及最终的图片加载位置,就可以在自己的项目灵活使用。

附录文章:

1,《Android自底部平滑向上滑出面板的AndroidSlidingUpPanel》链接地址:http://blog.csdn.net/zhangphil/article/details/51444509


2,《Android音乐、视频类APP常用控件:DraggablePanel(1)》链接地址:http://blog.csdn.net/zhangphil/article/details/51566860 


3,《Android音乐、视频类APP常用控件:DraggablePanel(2)》链接地址:http://blog.csdn.net/zhangphil/article/details/51578665

4,《Android图片加载与缓存开源框架:Android Glide》链接地址http://blog.csdn.net/zhangphil/article/details/45535693

5,《Android BottomSheet:便捷易用的底部滑出面板(1)》链接地址:http://blog.csdn.net/zhangphil/article/details/51775955

Android BottomSheet:以选取图片为例(2)的更多相关文章

  1. Android BottomSheet:底部弹出Fragment面板(4)

     Android BottomSheet:底部弹出Fragment面板(4) BottomSheet不仅可以弹出轻量级的定制好的面板(见附录文章5,6,7),还可以弹出"重"的 ...

  2. Android BottomSheet:List列表或Grid网格展示(3)

     Android BottomSheet:List列表或Grid网格展示(3) BottomSheet可以显示多种样式的底部弹出面板风格,比如常见的List列表样式或者Grid网格样式,以一个例子 ...

  3. Android BottomSheet:便捷易用的底部滑出面板(1)

    Android BottomSheet:便捷易用的底部滑出面板(1) Android BottomSheet是github上的一个第三方开源项目,其主页:https://github.com/Flip ...

  4. Ubuntu 14.04 Android 使用Maven一个 用例project

    在说明书前面描述SDK通过使用Ant发展. 本文试图在此基础上使用Maven发展. 在这里,我们需要使用maven-android-plugin. 在本文中,参考官方文件: https://code. ...

  5. android一个上传图片的样例,包含怎样终止上传过程,假设在上传的时候更新进度条(一)

    先上效果图: Layout为: <? xml version="1.0" encoding="utf-8"?> <LinearLayout x ...

  6. 创建android画笔程序的样例(有镜面效果)

    先上图: 关键是在检測到手指移动的时候用mPath.quadTo的方法,android sdk解释是: Add a quadratic bezier from the last point, appr ...

  7. android发送短信样例

    Android应用开发中我们经常须要发送手机短信.这对于android平台来说,是最简单只是的功能了,无需太多代码,也无需自己定义代码,仅仅须要调用android提供的消息管理类SmsManager就 ...

  8. android自定义控件——以滑动开关为例

    0.引言 (1)Android从4.0开始提供了switch的滑动开关效果组件,但是之前版本却没有 (2)很多时候我们写程序,都希望把有用的通用的通用的东西封装起来,以便以后重用. 本文根据组件开发思 ...

  9. 基于Android Fragment功能的样例

    通过近期空暇时候对Fragment的学习,尝试着写了一个小Demo,将在开发的时候能经常使用到的Fragment知识放在一起,写过了这个Demo对Android Fragment的了解更加深入了,以后 ...

随机推荐

  1. 堆和栈的区别【以java为例潜入分析】

     Java的堆是一个运行时数据区,类的对象从中分配空间,这些对象通过new等指令建立. 堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,Java的垃圾收集器会自动 ...

  2. Vue学习-Element框架

    今天学了一个基于Vue2.0的桌面端组件库Element,号称是全世界最流行的Vue UI框架.感觉学会了之后就变身大牛了有木有. 好了,不吹牛皮了. Element官方文档通俗易懂,框架什么的安装引 ...

  3. 微信小程序setData的使用,通过[...]进行动态key赋值

    首先先介绍一下微信小程序Page.prototype.setData(Object data, Function callback)的讲解: setData函数用于将数据从逻辑层发送到视图层(异步), ...

  4. Eclipse/STS 在线安装阿里java代码规约插件

    1.打开Idea的在线安装插件界面,通过“Help”-->“Install New Software...” 进入 2. 在 “Work with” 栏输入插件包的下载地址:https://p3 ...

  5. [NOI2004]cashier 郁闷的出纳员

    Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常 ...

  6. linux学习之路4 系统目录架构

    linux树状文件系统结构 bin(binary) 保存可执行文件 也就是保存所有命令 boot 引导目录 保存所有跟系统有关的引导程序 其中Vmlinux文件最为重要,是系统内核 dev 保存所有的 ...

  7. H - Where is the Marble?(set+vector)

    Description Raju and Meena love to play with Marbles. They have got a lot of marbles with numbers wr ...

  8. Office Excel的几个快捷键记录

    Office Excel的几个快捷键记录: 切换Sheet:CTRL + PageUP/PageDown 另存为:F12

  9. [译]Customizing Operations

    Customizing Operations定制操作 There is an ongoing development today where more and more protocols are b ...

  10. 00-IT人士必去的10个网站

    IT人士必去的10个网站 1.Chinaunix 网址:http://www.chinaunix.net/ 简介:中国最大的linux/unix技术社区. 2.ITPub 网址:http://www. ...