我正试图弄清楚如何从接收方收到进度更新后更新特定项目的进度栏。
这是我的收件人片段:
private val mReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
when(intent.action) {
PROGRESS_UPDATE_ACTION -> {
val resId = intent.extras.getInt("resourceID")
val progress = intent.extras.getInt("contentLength$resId")
val maxProgress = intent.extras.getLong("maxProgress$resId")
adapter.update(resId, progress, maxProgress)
}
}
}
}
适配器是从数据库填充的。每个项目都有一个唯一的resourceID。
private fun loadDataFromBox(){
val query = SaveOfflineManager().getAll()
val saveOfflineData = LinkedHashMap<Int, SaveOfflineData>()
query.forEach {
saveOfflineData[it.resourceID!!] = it
}
adapter.setData(saveOfflineData)
adapter.notifyDataSetChanged()
}
这是我的简化适配器。如您所见,我不知道如何处理从接收方接收更新的方法。我尝试搜索解决方案数小时,但似乎找不到任何解决方案。
class SaveOfflineAdapter : RecyclerView.Adapter<SaveOfflineAdapter.SimpleViewHolder>() {
private var downloadMap : LinkedHashMap<Int, SaveOfflineData> = LinkedHashMap()
private var utils : Utils = Utils()
fun setData(downloadist : LinkedHashMap<Int, SaveOfflineData>) {
this.downloadMap.clear()
this.downloadMap = downloadist
this.notifyDataSetChanged()
}
fun update(resourceID : Int, progress : Int, maxProgress : Long) {
// update progress for a specific resourceID
// what to do here?
this.notifyDataSetChanged() // makes app real slow when called repeatedly
}
override fun getItemCount(): Int {
return downloadMap.count()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SimpleViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.save_offline_container_layout, parent, false)
return SimpleViewHolder(view)
}
override fun onBindViewHolder(holder: SimpleViewHolder, position: Int) {
holder.savedData = ArrayList(downloadMap.values)[position]
if (ArrayList(downloadMap.values)[position].status == "Completed") {
holder.downloadProgress?.visibility = View.INVISIBLE
} else {
holder.downloadProgress?.visibility = View.VISIBLE
// update progress here??
// holder.downloadProgress.progress = holder.savedData.progress!!
// holder.downloadProgress.max = holder.savedData.totalContentLength!!
}
}
inner class SimpleViewHolder(v: View, var savedData: SaveOfflineData? = null) : RecyclerView.ViewHolder(v) {
var downloadProgress : ProgressBar? = v.findViewById(R.id.saveOffProgress)
}
}
简化的片段代码:
class SaveOfflineFragment: BaseFragment(), View.OnClickListener{
var adapter = SaveOfflineAdapter()
var tabKey = 0
private var saveOfflineRecyclerView : RecyclerView? = null
private val mReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
when(intent.action) {
PROGRESS_UPDATE_ACTION -> {
val resId = intent.extras.getInt("resourceID")
val progress = intent.extras.getInt("contentLength$resId")
val maxProgress = intent.extras.getLong("maxProgress$resId")
adapter.update(resId, progress, maxProgress)
}
DOWNLOAD_DONE_ACTION -> {
loadDataFromBox()
}
}
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
rootView = inflater.inflate(R.layout.saveoffline_layout, container, false)
activity!!.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
ScreenTracking.getInstance().track(TAG_SAVE_OFFLINE_FRAG + tabKey, false)
getViews()
setIds()
setViews()
return rootView
}
private fun getViews() {
saveOfflineRecyclerView = rootView!!.recyclerview_main
}
private fun setIds(){
val idRecyclerView: IntArray = intArrayOf(R.id.saveOfflineRecyclerView1, R.id.saveOfflineRecyclerView2, R.id.saveOfflineRecyclerView3, R.id.saveOfflineRecyclerView4)
val position = tabKey - 1
saveOfflineRecyclerView!!.id = idRecyclerView [position]
}
private fun setViews(){
saveOfflineRecyclerView!!.layoutManager = LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false)
saveOfflineRecyclerView!!.layoutManager!!.isItemPrefetchEnabled = true
saveOfflineRecyclerView!!.isNestedScrollingEnabled = false
saveOfflineRecyclerView!!.setHasFixedSize(true)
saveOfflineRecyclerView!!.setItemViewCacheSize(20)
saveOfflineRecyclerView!!.isDrawingCacheEnabled = true
saveOfflineRecyclerView!!.drawingCacheQuality = View.DRAWING_CACHE_QUALITY_HIGH
adapter.hasStableIds()
saveOfflineRecyclerView!!.adapter = adapter
}
override fun onClick(v: View?) {
when (v!!.id) {
R.id.saveOfflineSearchBtn1, R.id.saveOfflineSearchBtn2, R.id.saveOfflineSearchBtn3, R.id.saveOfflineSearchBtn4 -> {
}
R.id.confirmDeleteCancel -> {
}
R.id.confirmDeleteYes -> {
}
}
}
override fun onResume() {
println("On resume, registering receiver")
super.onResume()
val mIntentFilter = IntentFilter()
mIntentFilter.addAction(PROGRESS_UPDATE_ACTION)
mIntentFilter.addAction(DOWNLOAD_DONE_ACTION)
BuriIOApp.context.registerReceiver(mReceiver, mIntentFilter)
}
override fun onPause() {
println("onpause unregistering receiver")
BuriIOApp.context.unregisterReceiver(mReceiver)
super.onPause()
}
override fun onAttach(context: Context?) {
super.onAttach(context)
tabKey = arguments!!.getInt("tabKey")
fragmentCallback = context as FragmentCallback
loadDataFromBox()
}
private fun loadDataFromBox(){
val query = SaveOfflineManager().getAll()
val saveOfflineData = LinkedHashMap<Int, SaveOfflineData>()
query.forEach {
saveOfflineData[it.resourceID!!] = it
}
adapter.setData(saveOfflineData)
adapter.notifyDataSetChanged()
}
companion object {
fun newInstance(tabKey : Int): SaveOfflineFragment {
val args = Bundle()
args.putInt("tabKey", tabKey)
val fragment = SaveOfflineFragment()
fragment.arguments = args
return fragment
}
}
}
答案 0 :(得分:1)
在update
方法中,您必须找到要更新的项目,然后将最后的更改应用于该项目。像这样的东西:
fun update(resourceID : Int, progress : Int, maxProgress : Long) {
if (downloadMap.get(resourceID)!=null) {
downloadMap.get(resourceID).progress = progress
downloadMap.get(resourceID).totalContentLength = maxProgress
}
this.notifyDataSetChanged() // makes app real slow when called repeatedly
}
然后在onBindViewHolder
方法中,您必须处理进度状态,例如:
Override fun onBindViewHolder(holder: SimpleViewHolder, position: Int) {
holder.savedData = ArrayList(downloadMap.values)[position]
if (ArrayList(downloadMap.values)[position].status == "Completed") {
holder.downloadProgress?.visibility = View.INVISIBLE
} else {
holder.downloadProgress?.visibility = View.VISIBLE
holder.downloadProgress.progress = holder.savedData.progress!!
holder.downloadProgress.max = holder.savedData.totalContentLength!!
}
}
提示:在update
方法中,您可以使用notifyItemChanged
代替notifyDataSetChanged
。这是反弹的唯一一项,并且有更好的表现。见下文:
fun update(resourceID : Int, progress : Int, maxProgress : Long) {
val data = downloadMap.get(resourceID)
if (data!=null) {
data.progress = progress
data.totalContentLength = maxProgress
val index = ArrayList(downloadMap.values).indexOf(data)
this.notifyItemChanged(index)
}
}