zoukankan      html  css  js  c++  java
  • Android 从 Android 本地图库选择多个图片

    原文地址

    本文说明如何从 Android 本地图库选择多个图片。作者考虑很多解决方案。

    演示从 Android 本地图库选择多个图片,有两个方法可以实现从图库中选择多个图片:

    • 用 Intent 获取多个图片
    • 自定义图库从本地获取和加载图片

    下载 Demo

    下载 Demo 后将 QDReader 图片目录复制到 sd 卡上

    环境


    • Windows 2008 R2 64 位
    • Eclipse ADT V22.6.2,Android 4.4.2(API 19)
    • SAMSUNG GT-8618,Android OS 4.1.2

    用 Intent 获取多个图片


    通过使用下面代码,尝试与选择单张图片相同的解决方案来实现:

    Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE);

    我以为这样可以,但不能选择多张图片。经过查看资料,作者意识到可以使用 SEND_MULTIPLE intent(发送多意向),但是没有找到实现选择多个图片的方法。

    自定义图库


    因为我们不知道如何实现发送多个意向(Intent)的解决方案,所以可以用自定义图库的解决办法,来实现获取图片,并加载到 ​GridView。我的一个朋友 Vikas Kanani 已经探索和分享了这一解决方案。我试图实现相同的解决方案,但发现它的一些问题:

    • 如果图片数量很大,比如 2000~5000,加载就会相当慢
    • 如果加载更多图片,可能会崩溃

    为了解决以上问题,我用异步加载图片,这样每个图片都是异步获得的。

    2014-09-03_170627_副本

    图 1 项目结构

    1_副本

    图 2 演示从 Android 本地图库选择多个图片(左:选择前;右:选择后)

    解决方案实现如下所示。

    • 定义图片每个网格的布局——row_multiphoto_item.xml
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
     
        <ImageView
            android:id="@+id/imageView1"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:src="@drawable/ic_launcher" />
     
        <CheckBox
            android:id="@+id/checkBox1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignRight="@+id/imageView1"
            android:layout_centerVertical="true" />
     
    </RelativeLayout>
    • 定义图片 GridView 的布局——ac_image_grid.xml
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
     
        <GridView
            android:id="@+id/gridview"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_above="@+id/button1"
            android:columnWidth="100dip"
            android:gravity="center"
            android:horizontalSpacing="4dip"
            android:numColumns="auto_fit"
            android:stretchMode="columnWidth"
            android:verticalSpacing="2dip" />
     
        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:onClick="btnChoosePhotosClick"
            android:text="Select Photos" />
     
    </RelativeLayout>
    • 定义 UILApplication 类,声明应用程序级别的配置设置。
    public class UILApplication extends Application {
     
        @Override
        public void onCreate() {
            super.onCreate();
     
            // This configuration tuning is custom. You can tune every option, you
            // may tune some of them,
            // or you can create default configuration by
            // ImageLoaderConfiguration.createDefault(this);
            // method.
            ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
                    getApplicationContext())
                    .threadPoolSize(3)
                    .threadPriority(Thread.NORM_PRIORITY - 2)
                    .memoryCacheSize(1500000)
                    // 1.5 Mb
                    .denyCacheImageMultipleSizesInMemory()
                    .discCacheFileNameGenerator(new Md5FileNameGenerator())
                    .enableLogging() // Not necessary in common
                    .build();
            // Initialize ImageLoader with configuration.
            ImageLoader.getInstance().init(config);
        }
    }
    • 定义 BaseActivity 类,创建一个单件实例的 ImageLoader 类。
    public abstract class BaseActivity extends Activity {
     
        protected ImageLoader imageLoader = ImageLoader.getInstance();
     
    }
    • 现在可以定义一个主 activity 类——MainActivity,编写代码从本地图库获得图片。该类还定义了一个 GridView 的 ImageAdapter 类。
    public class MainActivity extends BaseActivity {
     
        private ArrayList<String> imageUrls;
        private DisplayImageOptions options;
        private ImageAdapter imageAdapter;
     
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.ac_image_grid);
     
            initData();
            initGallery();
        }
     
        private void initData() {
            this.imageUrls = new ArrayList<String>();
     
            final String[] columns = { MediaStore.Images.Media.DATA,
                    MediaStore.Images.Media._ID };
            final String orderBy = MediaStore.Images.Media.DATE_TAKEN;
            Cursor imagecursor = this
                    .getApplicationContext()
                    .getContentResolver()
                    .query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns,
                            null, null, orderBy + " DESC");
            for (int i = 0; i < imagecursor.getCount(); i++) {
                imagecursor.moveToPosition(i);
                int dataColumnIndex = imagecursor
                        .getColumnIndex(MediaStore.Images.Media.DATA);
                imageUrls.add(imagecursor.getString(dataColumnIndex));
                Log.i("imageUrl", imageUrls.get(i));
            }
        }
     
        private void initGallery() {
            options = new DisplayImageOptions.Builder()
                    .showStubImage(R.drawable.stub_image)
                    .showImageForEmptyUri(R.drawable.image_for_empty_url)
                    .cacheInMemory().cacheOnDisc().build();
     
            imageAdapter = new ImageAdapter(this, imageUrls);
            GridView gridView = (GridView) findViewById(R.id.gridview);
            gridView.setAdapter(imageAdapter);
            // gridView.setOnItemClickListener(new OnItemClickListener() {
            // @Override
            // public void onItemClick(AdapterView<?> parent, View view,
            // int position, long id) {
            // startImageGalleryActivity(position);
            // }
            // });
        }
     
        @Override
        protected void onStop() {
            imageLoader.stop();
            super.onStop();
        }
     
        public void btnChoosePhotosClick(View v) {
     
            ArrayList<String> selectedItems = imageAdapter.getCheckedItems();
            Toast.makeText(MainActivity.this,
                    "Total photos selected: " + selectedItems.size(),
                    Toast.LENGTH_SHORT).show();
            Log.d(MainActivity.class.getSimpleName(), "Selected Items: "
                    + selectedItems.toString());
        }
     
        /**
         * Description GridView Adapter
         */
        public class ImageAdapter extends BaseAdapter {
     
            ArrayList<String> mList;
            LayoutInflater mInflater;
            Context mContext;
            SparseBooleanArray mSparseBooleanArray;
     
            public ImageAdapter(Context context, ArrayList<String> imageList) {
                // TODO Auto-generated constructor stub
                mContext = context;
                mInflater = LayoutInflater.from(mContext);
                mSparseBooleanArray = new SparseBooleanArray();
                mList = new ArrayList<String>();
                this.mList = imageList;
            }
     
            public ArrayList<String> getCheckedItems() {
                ArrayList<String> mTempArry = new ArrayList<String>();
     
                for (int i = 0; i < mList.size(); i++) {
                    if (mSparseBooleanArray.get(i)) {
                        mTempArry.add(mList.get(i));
                    }
                }
     
                return mTempArry;
            }
     
            @Override
            public int getCount() {
                return imageUrls.size();
            }
     
            @Override
            public Object getItem(int position) {
                return null;
            }
     
            @Override
            public long getItemId(int position) {
                return position;
            }
     
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
     
                if (convertView == null) {
                    convertView = mInflater.inflate(R.layout.row_multiphoto_item,
                            null);
                }
     
                CheckBox mCheckBox = (CheckBox) convertView
                        .findViewById(R.id.checkBox1);
                final ImageView imageView = (ImageView) convertView
                        .findViewById(R.id.imageView1);
     
                imageLoader.displayImage("file://" + imageUrls.get(position),
                        imageView, options, new SimpleImageLoadingListener() {
                            @Override
                            public void onLoadingComplete(Bitmap loadedImage) {
                                Animation anim = AnimationUtils.loadAnimation(
                                        MainActivity.this, R.anim.fade_in);
                                imageView.setAnimation(anim);
                                anim.start();
                            }
                        });
     
                mCheckBox.setTag(position);
                mCheckBox.setChecked(mSparseBooleanArray.get(position));
                mCheckBox.setOnCheckedChangeListener(mCheckedChangeListener);
     
                return convertView;
            }
     
            OnCheckedChangeListener mCheckedChangeListener = new OnCheckedChangeListener() {
     
                @Override
                public void onCheckedChanged(CompoundButton buttonView,
                        boolean isChecked) {
                    // TODO Auto-generated method stub
                    mSparseBooleanArray.put((Integer) buttonView.getTag(),
                            isChecked);
                }
            };
        }
    }

    注意:

    • 本文使用了图片加载库 universal-image-loader 包,在 libs 目录中。
    • 下载 Demo 后,将 QDReader 图片目录复制到 sd 卡上。

    下载 Demo

  • 相关阅读:
    Python正则表达式如何进行字符串替换实例
    Python正则表达式如何进行字符串替换实例
    Python正则表达式如何进行字符串替换实例
    Python正则表达式如何进行字符串替换实例
    得益于AI,这五个行业岗位需求将呈现显著增长趋势
    得益于AI,这五个行业岗位需求将呈现显著增长趋势
    Python实现二叉堆
    Python实现二叉堆
    ubuntu14.04安装OpenVirteX
    ubuntu下sh文件使用
  • 原文地址:https://www.cnblogs.com/liuning8023/p/3954156.html
Copyright © 2011-2022 走看看