zoukankan      html  css  js  c++  java
  • 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


  • 相关阅读:
    PAT (Advanced Level) 1086. Tree Traversals Again (25)
    PAT (Advanced Level) 1085. Perfect Sequence (25)
    PAT (Advanced Level) 1084. Broken Keyboard (20)
    PAT (Advanced Level) 1083. List Grades (25)
    PAT (Advanced Level) 1082. Read Number in Chinese (25)
    HDU 4513 吉哥系列故事――完美队形II
    POJ Oulipo KMP 模板题
    POJ 3376 Finding Palindromes
    扩展KMP
    HDU 2289 Cup
  • 原文地址:https://www.cnblogs.com/hehehaha/p/6147296.html
Copyright © 2011-2022 走看看