How to use timer into recyclerView on Android - android

Why not help me any people???
In my application i want show timer in per items of recyclerView !
I write below codes with Kotlin language, but when scroll recyclerView timers reseted and start again from startTime not continue it!
My problem is timer reset, i want when scroll on recyclerView items, timers not reseted and i want continue timer!
My adapter codes:
class AuctionsTodayAdapter(val context: Context, val model: MutableList<AuctionsTodayResponse.Res.Today>) :
RecyclerView.Adapter<AuctionsTodayAdapter.MyHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyHolder {
val view = LayoutInflater.from(context).inflate(R.layout.row_bidzila_list, parent, false)
return MyHolder(view)
}
override fun getItemCount(): Int {
return model.size
}
override fun onBindViewHolder(holder: MyHolder, position: Int) {
val modelUse = model[position]
holder.setData(modelUse)
}
override fun onViewAttachedToWindow(holder: MyHolder) {
val pos = holder.adapterPosition
val modelUse = model[pos]
holder.handler.post { holder.timer(modelUse.calculateEnd, 1000) }
}
override fun onViewDetachedFromWindow(holder: MyHolder) {
if (holder.timmer != null) {
holder.timmer.cancel()
}
}
inner class MyHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var handler = Handler(Looper.getMainLooper())
lateinit var timmer: CountDownTimer
fun setData(model: AuctionsTodayResponse.Res.Today) {
model.image.let {
Glide.with(context)
.load(Constants.BIDZILA_BASE_URL + it)
.apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.RESOURCE))
.into(itemView.rowBidzila_img)
}
model.title.let { itemView.rowBidzila_title.text = it }
}
fun timer(millisInFuture: Long, countDownInterval: Long): CountDownTimer {
timmer = object : CountDownTimer(millisInFuture * 1000, countDownInterval) {
override fun onTick(millisUntilFinished: Long) {
var seconds = (millisUntilFinished / 1000).toInt()
val hours = seconds / (60 * 60)
val tempMint = seconds - hours * 60 * 60
val minutes = tempMint / 60
seconds = tempMint - minutes * 60
itemView.rowBidzila_timer.rowBidzila_timer.text =
String.format("%02d", hours) + ":" + String.format(
"%02d",
minutes
) + ":" + String.format("%02d", seconds)
}
override fun onFinish() {
itemView.rowBidzila_timer.rowBidzila_timer.text = "Finished"
}
}.start()
return timmer
}
}
}
My models :
data class Today(
#SerializedName("auction_status")
val auctionStatus: String = "", // accept
#SerializedName("base_price")
val basePrice: Int = 0, // 120000
#SerializedName("bid_number")
val bidNumber: Int = 0, // 1
#SerializedName("calculate_end")
var calculateEnd: Long = 0, // -9815
#SerializedName("can_offer_before")
val canOfferBefore: Int = 0, // 1
#SerializedName("capacity")
val capacity: Int = 0, // 25
#SerializedName("current_price")
val currentPrice: Int = 0, // 224000
#SerializedName("discount")
val discount: Int = 0, // 400000
#SerializedName("end")
val end: Int = 0, // 1548650312
#SerializedName("end_date")
val endDate: String = "", // 2019-01-28 08:08:32
#SerializedName("end_time")
val endTime: String = "", // 2019-01-28 08:08:32
#SerializedName("final_discount")
val finalDiscount: Int = 0, // 176000
#SerializedName("final_price")
val finalPrice: Int = 0, // 224000
#SerializedName("id")
val id: Int = 0, // 2629
#SerializedName("image")
val image: String = "", // /img/product/5bd94ed3cb9d2.png
#SerializedName("lastbid")
val lastbid: Any = Any(), // null
#SerializedName("live")
val live: String = "",
#SerializedName("max_price")
val maxPrice: Int = 0, // 240000
#SerializedName("max_price_percent")
val maxPricePercent: Int = 0, // 60
#SerializedName("name")
val name: String = "",
#SerializedName("number_of_users")
val numberOfUsers: Int = 0, // 14
#SerializedName("order")
val order: Int = 0, // 0
#SerializedName("price")
val price: Int = 0, // 400000
#SerializedName("product_id")
val productId: Int = 0, // 671
#SerializedName("registered")
val registered: String = "", // null
#SerializedName("registereduser")
val registereduser: Int = 0, // 14
#SerializedName("second_image")
val secondImage: String = "",
#SerializedName("start_date")
val startDate: String = "", // 2019-01-28 08:00:00
#SerializedName("tag")
val tag: String = "",
#SerializedName("tag_color")
val tagColor: String = "", // ff3232
#SerializedName("tag_description")
val tagDescription: String = "",
#SerializedName("title")
val title: String = "",
#SerializedName("winner_avatar")
val winnerAvatar: String = "", // /img/avatar/009-social-11.png
#SerializedName("winner_id")
val winnerId: Int = 0, // 57582
#SerializedName("winner_name")
val winnerName: String = "", // Arashr1
val running: Boolean = true,
var thread: Thread
) {
init {
thread = Thread(Runnable {
while (running) {
calculateEnd--
try {
Thread.sleep(1000)
} catch (e: InterruptedException) {
e.printStackTrace()
}
}
})
thread.start()
}
}
How can i fix it?

You can use a model. And in this model you can set last counted value. and in your ViewHolder you will start time from last counted value from your model. I hope you understand

Related

How to get Folder size and number of Files avaliable from Folder path in Kotlin

i am trying to create a video player app using kotlin , First of all I got the videos files by using MediaStore , than store this in ArrayList so far it's been perfect but When I made a folder list of videos, I tried to find out the size of those folders and how many video files there are in those folders, but I failed. like this (Image)
Check this image for more clear
This is my data class code (VideoItem.Kt)
import android.net.Uri
data class VideoItem(
val id: String,
val title: String,
val duration: Long = 0,
val folderName: String,
val size: String,
val path: String,
val dateAdded: String,
val artUri: Uri
)
data class FolderItem(
val id: String,
val folderName: String,
val folderSize: Long
)
This is my MainActivity Code To get Allvideos Using MediaStore
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
companion object {
lateinit var videoList: ArrayList<VideoItem>
lateinit var folderList: ArrayList<FolderItem>
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
folderList = ArrayList()
videoList = getAllVideos()
setFragment(VideoviewFragment())
}
private fun setFragment(fragment: Fragment) {
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.FrameLayout, fragment)
transaction.disallowAddToBackStack()
transaction.commit()
}
#SuppressLint("Recycle", "Range")
private fun getAllVideos(): ArrayList<VideoItem> {
val tempList = ArrayList<VideoItem>()
val tempFolderList = ArrayList<String>()
val projection = arrayOf(
MediaStore.Video.Media.TITLE,
MediaStore.Video.Media.SIZE,
MediaStore.Video.Media._ID,
MediaStore.Video.Media.BUCKET_DISPLAY_NAME,
MediaStore.Video.Media.DATA,
MediaStore.Video.Media.DATE_ADDED,
MediaStore.Video.Media.DURATION,
MediaStore.Video.Media.BUCKET_ID
)
val cursor = this.contentResolver.query(
MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
projection,
null,
null,
MediaStore.Video.Media.DATE_ADDED + " DESC"
)
if (cursor != null)
if (cursor.moveToNext())
do {
val titleC =
cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.TITLE))
val idC = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media._ID))
val folderNameC =
cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.BUCKET_DISPLAY_NAME))
val folderIdC =
cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.BUCKET_ID))
val sizeC = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.SIZE))
val pathC = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.DATA))
val dateAddedC =
cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.DATE_ADDED))
val durationC =
cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.DURATION))
.toLong()
try {
val file = File(pathC)
val artUriC = Uri.fromFile(file)
val video = VideoItem(
title = titleC,
id = idC,
folderName = folderNameC,
size = sizeC,
path = pathC,
duration = durationC,
dateAdded = dateAddedC,
artUri = artUriC
)
if (file.exists()) tempList.add(video)
//for adding Folders
if (!tempFolderList.contains(folderNameC)) {
tempFolderList.add(folderNameC)
val folderSizeC = getFileLength(pathC)
folderList.add(
FolderItem(
id = folderIdC,
folderName = folderNameC,
folderSize = folderSizeC
)
)
}
} catch (_: Exception) {
}
} while (cursor.moveToNext())
cursor?.close()
return tempList
}
private fun getFileLength(path: String?): Long {
return if (!isExistFile(path)) 0 else File(path.toString()).length()
}
private fun isExistFile(path: String?): Boolean {
val file = File(path.toString())
return file.exists()
}
}
This is my RecyclerviwAdapter Code(FolderAdapter.kt)
class FoldersAdapter(private val context: Context, private var foldersList: ArrayList<FolderItem>) :
RecyclerView.Adapter<FoldersAdapter.MyHolder>() {
class MyHolder(binding: FolderItemBinding) : RecyclerView.ViewHolder(binding.root) {
val folderName = binding.folderName
val noofFiles = binding.nooffiles
val folderSize = binding.foldersize
val root = binding.root
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyHolder {
return MyHolder(FolderItemBinding.inflate(LayoutInflater.from(context), parent, false))
}
override fun onBindViewHolder(holder: MyHolder, position: Int) {
holder.folderName.text = foldersList[position].folderName
val size: Long = foldersList[position].folderSize
holder.folderSize.text = android.text.format.Formatter.formatFileSize(context, (size))
holder.root.setOnClickListener {
val intent = Intent(context, FolderVideosActivity::class.java)
intent.putExtra("position", position)
ContextCompat.startActivity(context, intent, null)
}
}
override fun getItemCount(): Int {
return foldersList.size
}
}
This is my all codes now please check out all code and suggest the best.
Thank you
Use this function for size
private fun getFolderSize(f: File): Long {
var size: Long = 0
if (f.isDirectory) {
for (file in f.listFiles()!!) {
size += getFolderSize(file)
}
} else {
size = f.length()
}
return size
}
And Count number of files Use this
val length = File("/path/to/folder").listFiles()?.size

BulletSpan which has newline is not working in Android

i'm using BulletSpan which is customized.
i want to display long text that has '\n'.
every lines are fine except for the text line which has '\n'.
bulleetspan can't apply the indent to the newline text.
this is the result.
and the last text is one text. and the text has '\n' inside.
and the code is..
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val source = listOf("Spans are powerful markup objects that you can use to style text at a character or paragraph level.",
"By attaching spans to text objects, you can change text in a variety of ways, ",
"including adding color, making the text clickable,\scaling the text size,\nand drawing text in a customized way.")
val sb = SpannableStringBuilder()
for (i in source.indices) {
val length = sb.length
sb.append(source[i])
sb.append("\n")
sb.setSpan(CustomBulletSpan(
bulletRadius = dip(8),
gapWidth = dip(14),
mColor = color(),
mWantColor = true
), length, length + 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
}
binding.tvResult.text = sb
}
private fun dip(dp: Int): Int {
return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dp.toFloat(),
resources.displayMetrics
).toInt()
}
private fun color(): Int {
return ContextCompat.getColor(applicationContext, R.color.gray);
}
}
and the customBullentSpan code is..
class CustomBulletSpan(
val bulletRadius: Int = STANDARD_BULLET_RADIUS,
val gapWidth: Int = STANDARD_GAP_WIDTH,
val mColor: Int = STANDARD_COLOR,
val mWantColor: Boolean = false
) : LeadingMarginSpan {
companion object {
// Bullet is slightly bigger to avoid aliasing artifacts on mdpi devices.
private const val STANDARD_BULLET_RADIUS = 4
private const val STANDARD_GAP_WIDTH = 2
private const val STANDARD_COLOR = 0
}
private var mBulletPath: Path? = null
override fun getLeadingMargin(first: Boolean): Int {
return 2 * bulletRadius + gapWidth
}
override fun drawLeadingMargin(
c: Canvas,
p: Paint,
x: Int,
dir: Int,
top: Int,
baseline: Int,
bottom: Int,
text: CharSequence,
start: Int,
end: Int,
first: Boolean,
layout: Layout?
) {
if ((text as Spanned).getSpanStart(this) == start) {
val style = p.style
p.style = Paint.Style.FILL
var oldColor = 0
if (mWantColor) {
oldColor = p.color
p.color = mColor
}
val yPosition = if (layout != null) {
val line = layout.getLineForOffset(start)
layout.getLineBaseline(line).toFloat() - bulletRadius * 1.3f
} else {
(top + bottom) / 1.3f
}
val xPosition = (x + dir * bulletRadius).toFloat()
if (c.isHardwareAccelerated) {
if (mBulletPath == null) {
mBulletPath = Path()
mBulletPath!!.addCircle(0.0f, 0.0f, bulletRadius.toFloat(), Path.Direction.CW)
}
c.save()
c.translate(xPosition, yPosition)
c.drawPath(mBulletPath!!, p)
c.restore()
} else {
c.drawCircle(xPosition, yPosition, bulletRadius.toFloat(), p)
}
if (mWantColor) {
p.color = oldColor
}
p.style = style
}
}
}
how can i solve this problem??
You could just get the string and split by \n and apply span
var len = 0
for (i in source.indices) {
if (source[i].contains("\n")) {
val splitted = source[i].split("\n")
for (k in splitted.indices) {
len = sb.length
sb.append(splitted[k])
sb.append("\n")
sb.setSpan(
CustomBulletSpan(
bulletRadius = dip(8),
gapWidth = dip(14),
mColor = color(),
mWantColor = true
), len, len + 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE
)
}
} else {
len = sb.length
sb.append(source[i])
sb.append("\n")
sb.setSpan(
CustomBulletSpan(
bulletRadius = dip(8),
gapWidth = dip(14),
mColor = color(),
mWantColor = true
), len, len + 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE
)
}
}
The other way is to split and add it to new list and iterate over the same and apply spans
val newList = mutableListOf<String>()
for (item in source) {
if(item.contains("\n")) {
val split = item.split("\n")
for (splitItem in split){
newList.add(splitItem)
}
} else{
newList.add(item)
}
}

Am I stuck in Kotlin While-Loop?

I was making Count-up Timer.
It works well when I press pause button or stop button, but the app freezes when I press start button.
I suspected that I was stuck in while loop but algorithm doesn't reach the codes before while loop.
What is wrong in my codes?
class MainActivity( var second : Int = 0 , var minute : Int = 0 , var hour : Int = 0 , var ongoing : Boolean = false ) : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initLayout()
}
private fun initLayout(): Unit {
val startButton: Button = findViewById(R.id.startButton)
val pauseButton: Button = findViewById(R.id.pauseButton)
val stopButton: Button = findViewById(R.id.stopButton)
var realTime : TextView = findViewById(R.id.Realtime)
startButton.setOnClickListener {
realTime.text = "0"//doesn't reach here
buttonOn()
countTime(realTime)
}
pauseButton.setOnClickListener {
buttonOff()
countTime(realTime)
}
stopButton.setOnClickListener {
buttonOff()
countTime(realTime)
}
}
private fun buttonOn(): Unit {
this.ongoing = true
}
private fun buttonOff(): Unit {
this.ongoing = false
}
private fun showTime(second: Int, minute: Int, hour: Int): String {
var secondShow: String = if (second < 10) "0$second" else second.toString()
var minuteShow: String = if (minute < 10) "0$minute" else minute.toString()
var hourShow: String = if (hour < 10) "0$hour" else hour.toString()
return "$hourShow:$minuteShow:$secondShow"
}
private fun countTime(textView: TextView): Unit {
var text = 0
textView.text = text.toString()
textView.text = showTime(this.second, this.minute, this.hour)
while (this.ongoing) {
Thread.sleep(1_000)
this.second++
if (this.second == 60) {
this.second = 0
this.minute++
if (this.minute == 60) {
this.minute = 0
this.hour++
}
}
textView.text = showTime(this.second, this.minute, this.hour)
//buttonOff reach here
}
}
}

How not to create a new object every time?

How can I stop creating a quoteData variable every time in my view model?
This solution is working, but the amount of repetitive code is terrifying
class QuoteDetailsViewModel(application: Application) : AndroidViewModel(application) {
private val quoteRepository: QuoteRepository = QuoteRepository(application)
private val quoteId = MutableLiveData<String>("")
val quoteAuthor = MutableLiveData<String>("")
val quoteContent = MutableLiveData<String>("")
val quoteDescription = MutableLiveData<String>("")
val quoteLastUpdate = MutableLiveData<String>("")
val onSaveClickEvent = MutableLiveData<ViewModelEvent<Unit>>()
val onCancelClickEvent = MutableLiveData<ViewModelEvent<Unit>>()
val onDeleteClickEvent = MutableLiveData<ViewModelEvent<String?>>()
var isNewQuote = false
fun setInitialData(arguments: Bundle?) {
if (arguments != null) {
val quoteData = arguments.getSerializable(KEY_DATA) as Quote
isNewQuote = false
quoteData.let { quote ->
quoteId.postValue(quote.id)
quoteAuthor.postValue(quote.author)
quoteContent.postValue(quote.quote)
quoteDescription.postValue(quote.description)
quoteLastUpdate.postValue(quote.lastUpdated.getFormattedDate())
}
} else {
isNewQuote = true
}
}
fun onViewClick(viewId: Int) {
val currentTime = Calendar.getInstance().time
when (viewId) {
R.id.actionSave -> {
if (!isNewQuote) {
val quoteData = Quote(
id = this.quoteId.value ?: "",
author = this.quoteAuthor.value ?: "",
quote = this.quoteContent.value ?: "",
description = this.quoteDescription.value ?: "",
lastUpdated = currentTime
)
quoteRepository.update(quoteData)
} else {
val quoteData = Quote(
id = UUID.randomUUID().toString(),
author = this.quoteAuthor.value ?: "",
quote = this.quoteContent.value ?: "",
description = this.quoteDescription.value ?: "",
lastUpdated = currentTime
)
quoteRepository.insert(quoteData)
}
onSaveClickEvent.postValue(ViewModelEvent(Unit))
}
R.id.actionCancel -> onCancelClickEvent.postValue(ViewModelEvent(Unit))
R.id.actionDelete -> onDeleteClickEvent.postValue(ViewModelEvent(this.quoteId.value))
}
}
fun onDeleteItemResult(guid: String?) {
val currentTime = Calendar.getInstance().time
val quoteData = Quote(
id = guid ?: "",
author = this.quoteAuthor.value ?: "",
quote = this.quoteContent.value ?: "",
description = this.quoteDescription.value ?: "",
lastUpdated = currentTime
)
quoteRepository.delete(quoteData)
}
companion object {
fun newBundle(quote: Quote?): Bundle {
return Bundle().apply {
putSerializable(KEY_DATA, quote)
}
}
}
}
Also here is code of my Quote:
#Entity(tableName = "quotes")
class Quote(
#PrimaryKey
val id: String,
val author: String,
val quote: String,
val description: String,
#ColumnInfo(name = "last_updated")
val lastUpdated: Date?
) : Serializable
And here is the code when I click on a list item
val allQuotes: LiveData<List<Quote>>
init {
allQuotes = quoteRepository.allQuotes
}
fun onListItemClick(itemIndex: Int) {
onListItemClickEvent.postValue(
ViewModelEvent(QuoteDetailsViewModel.newBundle(allQuotes.value?.getOrNull(itemIndex)))
)
}
Then I get to my view model - QuoteDetailsViewModel

android viewmodel observer inside RecyclerView.Adapter.onBindViewHolder() update every item

I need to download images from AWS S3 and update ImageViews inside a recycler view. I am using ViewModel for downloading files from S3. A file object is observing inside onBindViewHolder() method and once receive the file my intention was to update the image belongs with that particular holder.
But the problem is if there were two rows, then two images need to download. So each view holder will attach with the observer. After downloading the first file, both the image views inside the recycler view become updated with the first image and after downloading the second image, both images updated with the second image. I am a little bit confuse about working. Please help me with this.
I cannot use Glide for this. Because S3 have authentication. So, I need to use S3 library for downloading files.
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)
}
This is my viewmodel
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
}
}

Categories

Resources