繁体   English   中英

如何在从 Firebase android kotlin 获取数据时显示加载的项目

[英]How to display items loading while data is being fetched from Firebase android kotlin

我有一个RecyclerView和我的Fragment 我正在从Firebase Realtime Database中获取数据到 RecyclerView。

我需要这样做,以便在加载数据时,我会看到某种加载效果。 我怎样才能做到这一点?

我的Fragment:

private var _binding: FragmentDayDetailBinding? = null
private val binding get() = _binding!!

private var ref: DatabaseReference? = null
private lateinit var adapter: DayDetailAdapter

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View {
    _binding = FragmentDayDetailBinding.inflate(inflater, container, false)

    setupRecyclerView()
    initDatabase()

    return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    readFromDatabase()
}

private fun setupRecyclerView() {
    adapter = DayDetailAdapter()
    binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
    binding.recyclerView.adapter = adapter
}

private fun initDatabase() {
    FirebaseApp.initializeApp(requireContext())

    ref = FirebaseDatabase.getInstance()
        .getReference("IMIT")
        .child("groups")
}

private fun readFromDatabase() {
    ref?.addValueEventListener(object: ValueEventListener {
        override fun onDataChange(snapshot: DataSnapshot) {
            if (snapshot.exists()) {

                val list = ArrayList<Day>()

                for (daySnapshot in snapshot.children) {
                    val day = daySnapshot.getValue(Day::class.java)

                    list.add(day!!)
                }

                adapter.submitList(list)

            } else {
                binding.apply {
                    lrDbEmpty.visibility = View.VISIBLE
                    recyclerView.visibility = View.INVISIBLE
                }
            }
        }

        override fun onCancelled(error: DatabaseError) {

        }
    })
}

override fun onDestroyView() {
    super.onDestroyView()
    _binding = null
}

来自RecyclerView Adapter:

class ViewHolder(private val binding: ItemSubjectDetailBinding): RecyclerView.ViewHolder(binding.root) {

    fun bind(day: Day) = with(binding) {
        tvSubject.text = day.subject
        tvInfo.text = "${day.teacher}, ${day.type}"
        tvTime.text = day.time
        tvAud.text = day.classroom
    }

    companion object {
        fun from(parent: ViewGroup): ViewHolder {
            val layoutInflater = LayoutInflater.from(parent.context)
            val binding = ItemSubjectDetailBinding.inflate(layoutInflater, parent, false)
            return ViewHolder(binding)
        }
    }
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    return ViewHolder.from(parent)
}

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    with(holder) {
        bind(getItem(position))
    }
}

class ItemComparator: DiffUtil.ItemCallback<Day>() {
    override fun areItemsTheSame(oldItem: Day, newItem: Day): Boolean {
        return oldItem == newItem
    }

    override fun areContentsTheSame(oldItem: Day, newItem: Day): Boolean {
        return oldItem == newItem
    }
}

你已经半路了

在片段的中心创建一个进度

<ProgressBar
      android:id="@+id/progress_bar"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      />

保持它可见直到获取数据( onDataChange调用)然后隐藏 progressBar

override fun onDataChange(snapshot: DataSnapshot) {

    binding.progressBar.visibility = View.GONE

    if (snapshot.exists()) {
        // rest of your code
    }
}

我更喜欢动态添加视图。
我使用彩票播放器等待 animation。 添加显示等待有两种方法。 这样,您可以添加 animation 或非活动 class 的任何类型的视图。 它可以帮助您更好地以 MVVM 形式实现。
这是两种方法的实现。

1- 按 ID 创建和删除
2- 通过 LiveData 创建和删除

class AddViewNonActivity(
private val viewGroup: ViewGroup
) {
fun addCustomWait(): Int {
    val relativeLayout =
        RelativeLayout(viewGroup.context)
    val relativeParams =
        RelativeLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT)
    val lottieParams =
        RelativeLayout.LayoutParams(600, 600)
    relativeLayout.setBackgroundColor(
        viewGroup.context.getColor(R.color.wait_transparent)
    )
    relativeLayout.gravity = CENTER
    val lottieLoading = LottieAnimationView(viewGroup.context)
    lottieLoading.setAnimation("lottie/space-runner.json")
    lottieLoading.repeatCount = INFINITE
    lottieLoading.speed = 1f
    lottieLoading.playAnimation()
    relativeLayout.addView(lottieLoading, lottieParams)
    val viewId = View.generateViewId()
    viewGroup.addView(relativeLayout, relativeParams)
    relativeLayout.id = viewId
    relativeLayout.isClickable = true
    return viewId
}

fun removeCustomWait(
    waitViewId: Int
) {
    for (view in viewGroup) {
        if (view.id == waitViewId)
            viewGroup.removeView(view)
    }
}

fun addLiveCustomWait(
    lifecycleOwner: LifecycleOwner,
    liveData: LiveData<Boolean>) {
    var viewId = 0
    liveData.observe(lifecycleOwner) {
        if (it) {
            removeCustomWait(viewId)
            viewId = addCustomWait()
        } else {
            removeCustomWait(viewId)
        }
    }
  }
}

活动调用方法

class DynamicViewActivity : AppCompatActivity() {
private lateinit var binding : ActivityDynamicViewBinding
private val liveShowWait =MutableLiveData(false)

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityDynamicViewBinding.inflate(layoutInflater)
    setContentView(binding.root)

    var waitId = 0
    initialWait()

    binding.btnAddView.setOnClickListener {
        waitId = AddViewNonActivity(binding.root).addCustomWait()
    }

    binding.btnRemoveView.setOnClickListener {
        AddViewNonActivity(binding.root).removeCustomWait(waitId)
    }

    binding.btnLiveAddView.setOnClickListener {
        liveShowWait.postValue(true)
    }

    binding.btnLiveRemoveView.setOnClickListener {
        liveShowWait.postValue(false)
    }
}

private fun initialWait() =
    AddViewNonActivity(binding.root).addLiveCustomWait(this as 
LifecycleOwner, liveShowWait)
}

Github 链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM