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


    

    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


  • 相关阅读:
    《图解HTTP》读书笔记
    Python3 官方文档翻译
    Python3 官方文档翻译
    支付宝Payto接口的C#.net实现方法
    updatepanel用法之triggers(局部刷新,全部刷新)使用示例
    SQL Server中解决死锁
    js字符串与16进制互相转换
    文字超出隐藏并显示省略号,表格固定表头,两表格左右对齐,
    SQL Server中行列转换 Pivot UnPivot
    查看SQL Server日志 Part 1
  • 原文地址:https://www.cnblogs.com/hehehaha/p/6147296.html
Copyright © 2020-2023  润新知