English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
アプリケーションとして使用する場合、ローカルの画像を選択する際にはまずシステムのアルバムを考えるのはもちろんです。しかし、Androidスマートフォンは多種多様で、さらにピクセルの向上や大图が戻れないなどの異常要因により、対応する機種が難しいです。微信やQQもそれぞれのアプリに画像選択機能を統合し、システム提供の画像選択器を放棄しています。ここではQQを模倣してローカル画像選択器を作成しました、PS:以前、"模倣"を"防ぐ"と書かれていたことがありましたが、今日は特に注意して確認しました、間違いないようにしてください。
まず效果图を一つご紹介します、画像がなければ真実はないですネ~~~~
実現する効果は大体こんな感じです:
1.単一選択:ローカル画像選択フォルダーに移動し、フォルダーを選択後、そのフォルダーのすべての画像に入ります。画像を選択後、その画像のアドレス情報に戻ります。
2.複数選択:画像フォルダーに移動し、フォルダーを選択し、画像を選択し、右上の小さな円をクリックしてその画像を選択し、画像の他の部分をクリックして大图を確認し、プレビューをクリックして選択した画像を確認し、フォルダーを越えて画像を選択することができます。
この効果を達成するために、いくつかのことを行う必要があります:
1.すべての画像が含まれるフォルダーを読み込む:
ここではContentResolverを使用してメディアファイルを読み取ります。
String[] columns = {MediaStore.Images.Media._ID, MediaStore.Images.Thumbnails.DATA, MediaStore.Images.Media.DATA, MediaStore.Images.Media.BUCKET_ID, MediaStore.Images.Media.BUCKET_DISPLAY_NAME, "COUNT("1) AS count"}; String selection = "0==0) GROUP BY (" + MediaStore.Images.Media.BUCKET_ID; String sortOrder = MediaStore.Images.Media.DATE_MODIFIED; Cursor cursor = contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, selection, null, sortOrder);
これはシンプルなSQLクエリ文で、フォルダーをグループ化し、フォルダー内の画像数を返します。
2.指定されたフォルダー下のすべての画像を読み取ります:
特定のディレクトリを選択した場合、そのディレクトリ下のすべての画像を読み取る必要があります。
String[] columns = new String[]{MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA}; /*上記の指定されたフォルダーに含まれるファイルパスを持つ画像を検索します。--これで、検索結果のファイルが現在のフォルダーに属することを保証できます。*/ String whereclause = MediaStore.Images.ImageColumns.DATA + " like '" + folderPath + "/%'"; Log.i("queryGalleryPicture", "galleryPath:"); + folderPath); Cursor corsor = c.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, whereclause, null, null);
ここでのクエリはファイル名に基づいてフィルタリングされており、画像のパスにフォルダのパスが含まれている場合、そのフォルダの画像とみなされます。
3.UIインタラクション
まずすべての画像を含むフォルダを表示する際に、画像を含むフォルダを非同期で読み込み、読み込みが成功した後、リストを表示します。ここではRecyclerViewを使用してリスト情報を表示し、特定のディレクトリをクリックした場合、そのディレクトリの画像を読み込みます。画像表示ページでは、クリックした画像が選択リストに含まれているかどうかを確認し、含まれている場合には削除し、含まれていない場合には追加します。ここでの画像読み込みにはオープンソースフレームワークImageLoaderを使用しています。
if (mSelectlist.contains(imageBean)) { //クリックしたitemが既に選択されている画像の場合、削除します mSelectlist.remove(imageBean); subSelectPosition(); } else { //選択リストに含まれていない場合、追加します if (mSelectlist.size() >= maxCount) { Toast.makeText(mContext, mContext.getResources().getString(R.string.publish_select_photo_max, maxCount), Toast.LENGTH_SHORT).show(); return; } mSelectlist.add(imageBean); imageBean.selectPosition = mSelectlist.size(); } //クリック項目が変更されたことを通知します notifyItemChanged(position);
また、画像を1枚削除すると、その画像の順番が変わるようにして、UIの変更項目を通知します。
異なるActivity間の遷移時、画像リストListを渡す必要があるため、intentを使って渡すことを考慮したが、intentで渡した後、list.get(position).containsを使って同一オブジェクトかどうかを比較した際には常に異なるオブジェクトとして認識されてしまいます。確認してみてください。したがって、選択した画像とフォルダ内のすべての画像を保存する観察者クラスをここで定義しました。大图を確認する際に、画像を選択したり選択を解除したりした場合、観察者を通じて更新を通知します。
/** * 画像選択が変更されたことを通知します */ public void updateImageSelectChanged () { setChanged(); notifyObservers(imgSelectObj); }
以上のことをもちまして、私たちの画像選択器を使用することができます:
単一選択時、必要な場所で呼び出します:
/*単一選択、パラメータはcontext、コールバック*/ FolderListActivity.startSelectSingleImgActivity(this, 2); 複数選択時: /*パラメータはcontext、コールバックコード、渡された画像リスト、選択可能な最大枚数*/ FolderListActivity.startFolderListActivity(this, 1, null, 9);
最後にActivityのonActivityResultで返された画像データを受け取ります:
List<ImageFolderBean> list = (List<ImageFolderBean>) data.getSerializableExtra("list");
ソースコードのダウンロード先:
https://github.com/JarekWang/photoselect
以上に記載されているのは、編集者が皆さんに紹介したAndroid 高仿QQ画像選択器の全ての説明であり、皆さんに役立つことを願っています。
声明:本文の内容はインターネットからネットワーク上のユーザーにより自発的に貢献し、自己でアップロードされたものであり、本サイトは所有権を持ちません。人工的な編集は行われていません。著作権侵害の可能性のある内容を見つけた場合は、以下のメールアドレスまでお知らせください:notice#oldtoolbag.com(メールを送信する際、#を@に置き換えてください。報告を行い、関連する証拠を提供してください。一旦確認がとりあえず、本サイトは侵害される可能性のある内容をすぐに削除します。)