Android ViewModel наблюдатель внутри RecyclerView.Adapter.onBindViewHolder () обновить каждый элемент - PullRequest
0 голосов
/ 09 апреля 2019

Мне нужно загрузить изображения из AWS S3 и обновить ImageViews в представлении переработчика.Я использую ViewModel для загрузки файлов из S3.Файловый объект наблюдает внутри метода onBindViewHolder () и после получения файла я намеревался обновить изображение, принадлежащее этому конкретному держателю.Но проблема в том, что если было две строки, то нужно скачать два изображения.Таким образом, каждый держатель представления будет прикреплен к наблюдателю.После загрузки первого файла оба вида изображений внутри вида переработчика обновляются первым изображением, а после загрузки второго изображения оба изображения обновляются вторым изображением.Я немного запутался в работе.Пожалуйста, помогите мне с этим.Я не могу использовать Glide для этого.Потому что у S3 есть аутентификация.Итак, мне нужно использовать библиотеку S3 для загрузки файлов.

override fun onBindViewHolder(holder: ListViewHolder, position: Int) {
        val postUrl = listData[position].postUrl
        val createdAt = listData[position].createdAt
        val postImage = listData[position].postImage
        val postVideo = listData[position].postVideo
        val postVideoThumbnail = listData[position].postVideoThumbnail
        val groupId = listData[position].groupId
        val postStatus = listData[position].postStatus
        val postId = listData[position].postId
        val userId = listData[position].userId
        val postHeading = listData[position].postHeading
        val postDescription = listData[position].postDescription
        val updatedAt = listData[position].updatedAt
        val profileName = listData[position].userName
        val profileImage = listData[position].profileImage
        val likeCount = listData[position].likeCount
        val commentCount = listData[position].commentCount

        var key = ""

        if(!profileImage.isNullOrEmpty()){
            Glide.with(activity).load(profileImage) to holder.imgProfile
        }
        holder.textName.text = profileName.substring(0, 1).toUpperCase() + profileName.substring(1).toLowerCase()
        holder.textPostedDateTime.text = SimpleDateFormat(POST_LIST_DATE_FORMAT).format(Date(createdAt))
        holder.textPostHeading.text = postHeading
        if(postDescription.isNullOrEmpty() || postDescription == "null"){
            holder.textPostDescription.visibility = View.GONE
        } else{
            holder.textPostDescription.visibility = View.VISIBLE
            holder.textPostDescription.text = postDescription
        }
        if(postUrl.isNullOrEmpty() || postUrl == "null"){
           holder.textPostLink.visibility = View.GONE
        } else{
            holder.textPostLink.visibility = View.VISIBLE
            holder.textPostLink.text = postUrl
        }
        if(postVideoThumbnail.isNullOrEmpty() || postVideoThumbnail == "null"){
            holder.imgPostVideoPreview.visibility = View.GONE
        } else{
            holder.imgPostVideoPreview.visibility = View.VISIBLE
            loadImageToFile(holder.imgPostVideoPreview, postVideoThumbnail, position)
            key = postVideoThumbnail
        }
        if(postImage.isNullOrEmpty() || postImage == "null"){
            holder.imgPostImagePreview.visibility = View.GONE
        } else{
            holder.imgPostImagePreview.visibility = View.VISIBLE
            loadImageToFile(holder.imgPostImagePreview, postImage, position)
            key = postImage
        }

        holder.textLikeCount.text = likeCount.toString()
        holder.textCommentCount.text = commentCount.toString()
        if(!isSelfPosts){
            holder.layoutCommentLikeShare.visibility = View.VISIBLE
            holder.imgAddComment.setOnClickListener {  }
            holder.imgAddLike.setOnClickListener {  }
            holder.imgShare.setOnClickListener {  }
        }
        holder.itemView.setOnClickListener {
            moveTOPostDetails(postId, listData[position], Environment.getExternalStorageDirectory().path + "/" + EXTERNAL_STORAGE_FOLDER_NAME + "/" + key.substring(key.lastIndexOf("/")+1))
        }
    }

    class ListViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val imgProfile: ImageView = itemView.imgProfile
        val textName: TextView = itemView.textName
        val textPostedDateTime: TextView = itemView.textPostedDateTime
        val textPostHeading: TextView = itemView.textPostHeading
        val textPostDescription: TextView = itemView.textPostDescription
        val textPostLink: TextView = itemView.textPostLink
        val imgPostVideoPreview: ImageView = itemView.imgPostVideoPreview
        val imgPostImagePreview: ImageView = itemView.imgPostImagePreview
        val textCommentCount: TextView = itemView.textCommentCount
        val textLikeCount: TextView = itemView.textLikeCount
        val layoutCommentLikeShare: LinearLayout = itemView.layoutCommentLikeShare
        val imgAddComment: ImageView = itemView.imgAddComment
        val imgAddLike: ImageView = itemView.imgAddLike
        val imgShare: ImageView = itemView.imgShare
    }

    private fun moveTOPostDetails(postId: String, fetchPostsResponseModel: FetchPostsResponseModel, imageFileName: String){
        val intent = Intent(activity, PostDetails::class.java)
        intent.putExtra("POST_DETAILS", fetchPostsResponseModel)
        intent.putExtra("IS_SELF_POST", isSelfPosts)
        intent.putExtra("IMAGE_FILE_NAME", imageFileName)
        activity.startActivity(intent)
    }

    private fun loadImageToFile(imageView: ImageView, key: String, position: Int){
        var postListAdapterViewModel: PostListAdapterViewModel = ViewModelProviders.of(fragment).get(PostListAdapterViewModel::class.java)

        postListAdapterViewModel.init(activity)

        postListAdapterViewModel.getMediaFile()?.observe(fragment, Observer<File>{ file ->
            var a=position
            imageView.setImageURI(Uri.fromFile(file))
        } )
        postListAdapterViewModel.performDownload(key)
    }

Это моя модель представления

class PostListAdapterViewModel(application: Application):AndroidViewModel(application){

private val file = MutableLiveData<File>()
private lateinit var context: Context
fun init(context: Context) {
    this.context = context
    AWSMobileClient.getInstance().initialize(context).execute()
}
fun performDownload(key : String){
    val credentials = BasicAWSCredentials(AMAZON_S3_ACCESS_KEY, AMAZON_S3_SECRET_KEY)
    val s3Client = AmazonS3Client(credentials)
    val transferUtility = TransferUtility.builder()
        .context(context)
        .awsConfiguration(AWSMobileClient.getInstance().configuration)
        .s3Client(s3Client)
        .build()

    val downloadObserver = transferUtility.download (
        key,
        File(Environment.getExternalStorageDirectory().path + "/" + EXTERNAL_STORAGE_FOLDER_NAME + "/" + key.substring(key.lastIndexOf("/")+1)))

    // Attach a listener to get state updates
    downloadObserver.setTransferListener(object : TransferListener {
        override fun onStateChanged(id: Int, state: TransferState) {
            if (state == TransferState.COMPLETED) {
                // Handle a completed upload.
                file.value = File(Environment.getExternalStorageDirectory().path + "/" + EXTERNAL_STORAGE_FOLDER_NAME + "/" + key.substring(key.lastIndexOf("/")+1))
            }
        }

        override fun onProgressChanged(id: Int, current: Long, total: Long) {
            try {
                val done = (((current.toDouble() / total) * 100.0).toInt()) //as Int
                Log.d("PostListAdapterVM", "DOWNLOAD - - ID: $id, percent done = $done")
            }
            catch (e: Exception) {
                Log.e("PostListAdapterVM", "Trouble calculating progress percent", e)
            }
        }

        override fun onError(id: Int, ex: Exception) {
            Log.d("PostListAdapterVM", "DOWNLOAD ERROR - - ID: $id - - EX: ${ex.message.toString()}")
        }
    })

    // If you prefer to poll for the data, instead of attaching a
    // listener, check for the state and progress in the observer.
    if (downloadObserver.state == TransferState.COMPLETED) {
        // Handle a completed upload.
    }

    Log.d("PostListAdapterVM", "Bytes Transferrred: ${downloadObserver.bytesTransferred}")
}

fun getMediaFile(): MutableLiveData<File> {
    return file
}

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...