Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Explanation on the key techniques of implementing Picture Selector with Kotlin

2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly explains the "Kotlin to achieve the key technical points of the picture selector explain", the content of the article is simple and clear, easy to learn and understand, the following please follow the editor's ideas slowly in-depth, together to study and learn "Kotlin to achieve the key technical points of the picture selector to explain" it!

Catalogue

How to quickly get album classification

Handling of some abnormal situations

Recycleview-CursorAdapter

Is it necessary to use LoaderManager?

How to quickly get album classification

The so-called album classification, in fact, is to process all the media files in the media database and distinguish them according to the folder name, so that users can quickly choose according to the folder name when selecting pictures.

For example, we can look at the picture selection of Wechat:

Obviously, this classification table will not be included in the media database, and you need to deal with it manually. On some low-version android phones, you can add GROUP BY to the sql statement to deal with it, but the higher version can no longer be handled in this way.

You must manually process the cursor of your raw data, for example, when we query the media database:

The usual projection is as follows:

Val PROJECTION = arrayOf (MediaStore.Files.FileColumns._ID, COLUMN_BUCKET_ID, COLUMN_BUCKET_DISPLAY_NAME, MediaStore.MediaColumns.MIME_TYPE)

You can see that we only have four columns, namely, the file id, the folder id to which the file belongs, the folder name to which the file belongs, and the file type

So how to convert the original 4-column cursor quickly and easily?

We can create a virtual cursor MatrixCursor to extend our previous original cursor

Val MATRIX_COLUMNS = arrayOf (MediaStore.Files.FileColumns._ID, COLUMN_BUCKET_ID, COLUMN_BUCKET_DISPLAY_NAME, MediaStore.MediaColumns.MIME_TYPE, COLUMN_URI, COLUMN_COUNT)

In fact, two new columns have been added, one is the uri of the file, and the other is how many pictures are under the folder.

In this way, we only need to transfer the cursor to Cursoradapter to quickly complete the list of album categories.

Then how to make the conversion? Just go up and down the code:

{return withContext (Dispatchers.Default) {/ / key is the corresponding folder id value is the folder under which there are several pictures val bucketMap = hashMapOf () while (cursor.moveToNext ()) {val bucketId = cursor.getBucketId () if (bucketMap.containsKey (bucketId)) {val count = bucketMap [bucketId] bucketMap [bucketId] = countdown! + 1} else {bucketMap [bucketId] = 1L}} / / create a virtual cursor starting from the second record of cursor val matrixCursor = MatrixCursor (MATRIX_COLUMNS) / / the Cursor usually takes the first picture as the cover image val allAlbumCursor = MatrixCursor (MATRIX_COLUMNS) var allAlbumUri: Uri? = null var fileId: Long? = null if (cursor.moveToFirst ()) {/ / take the uri allAlbumUri = cursor.getUri () / / take the fileId of the first picture FileId = cursor.getFileId () Log.v ("wuyue" "allAlbumUri:$allAlbumUri") val bucketIdSet = hashSetOf () do {/ / if you already have this picture folder, then give up looking directly at the next if (bucketIdSet.contains (cursor.getBucketId () {continue} Var bucketDisplayName = "" if (cursor.getType (cursor.getColumnIndex (COLUMN_BUCKET_DISPLAY_NAME)) = = FIELD_TYPE_STRING) {bucketDisplayName = cursor.getBucketDisplayName ()} bucketIdSet.add (cursor.getBucketId ()) matrixCursor.addRow (arrayOf (cursor.getFileId (). ToString ()) Cursor.getBucketId (). ToString (), bucketDisplayName, cursor.getFileMimeType (), cursor.getUri (). ToString (), bucketMap [cursor.getBucketId ()]. ToString ()} while (cursor.moveToNext ())} allAlbumCursor.addRow (arrayOf (fileId?: ","-1 "," All ", allAlbumUri?.toString ()?:", ", cursor.count) MergeCursor (arrayOf (allAlbumCursor) MatrixCursor)}}

Briefly describe the train of thought.

1. Use the original cursor to figure out that the key of a map,map is the id value of the folder, that is, how many pictures are under this folder.

two。 Start traversing the original cursor, and then put the new row add into our virtual matrixCursor, because we only need to show the cover image

So for each album, we only need his latest picture, and the rest just skip it.

Handling of some abnormal situations

Mainly for some pictures, it is impossible to get the bucketDisplayName.

/ * get the name of the picture folder * / fun Cursor.getBucketDisplayName (): String = getString (getColumnIndex (COLUMN_BUCKET_DISPLAY_NAME))

For example, this picture:

For images stored directly in the root directory of the phone, the value of bucketDisplayName cannot be obtained, and it will crash if you directly use the extension function above.

So in general, we have to judge the Type of this cursor. If the return is not string but a null, just skip it. For the folder name of this kind of picture, it depends on the individual whether we put an empty string or write it directly to the mobile phone storage.

Recycleview-CursorAdapter

CursorAdapter is not currently done for Recycleview, only the version of listview, so if we want to use Recycleview, we need to customize a

Abstract class RecyclerViewCursorAdapter internal constructor (c: Cursor?): RecyclerView.Adapter () {private var mCursor: Cursor? = null private var mRowIDColumn = 0 protected abstract fun onBindViewHolder (holder: VH, cursor: Cursor?) Override fun onBindViewHolder (holder: VH, position: Int) {if (! isDataValid (mCursor)) {throw IllegalStateException ("Cannot bind view holder when cursor is in invalid state.")} if (! throw IllegalStateException ("Could not move cursor to position" + position + "when trying to bind view holder")} onBindViewHolder (holder) MCursor)} override fun getItemViewType (position: Int): Int {if (! mCursorfett.moveToPosition (position)) {throw IllegalStateException (("Could not move cursor to position" + position + "when trying to get item view type."))} return getItemViewType (position, mCursor)} protected abstract fun getItemViewType (position: Int Cursor: Cursor?): Int override fun getItemCount (): Int {return if (isDataValid (mCursor)) {else {0}} override fun getItemId (position: Int): Long {if (! isDataValid (mCursor)) {throw IllegalStateException ("Cannot lookup item id when cursor is in invalid state.")} If (! mCursorfett.moveToPosition (position)) {throw IllegalStateException (("Could not move cursor to position" + position + "when trying to get an item id"))} return mCursorsorfe.getLong (mRowIDColumn)} fun swapCursor (newCursor: Cursor?) {if (newCursor = mCursor) {return} If (newCursor! = null) {mCursor = newCursor mRowIDColumn = mCursorsorfett.getColumnIndexOrThrow (MediaStore.Files.FileColumns._ID) / / notify the observers about the new cursor notifyDataSetChanged ()} else {notifyItemRangeRemoved (0) ItemCount) mCursor = null mRowIDColumn =-1}} fun getCursor (): Cursor? {return mCursor} private fun isDataValid (cursor: Cursor?): Boolean {return cursor! = null & &! cursor.isClosed} init {setHasStableIds (true) swapCursor (c)}} is it necessary to use LoaderManager

Most of the open source image choices are based on LoaderManager, but it is not necessary. Now that it is 2021, why do you still use LoaderManager which is so difficult to use and abandoned by Google itself?

In fact, all you have to do is to use the livedata with cursor in viewModel.

Thank you for your reading, the above is the "Kotlin to achieve the key technical points of the picture selector to explain" the content, after the study of this article, I believe that you have a deeper understanding of the Kotlin to achieve the key technical points of the selector to explain this issue, the specific use of the need for you to practice and verify. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report