在 fragment popbackstack 中添加 SearchView onquerylistener 后,recyclerview 不会显示

问题描述 投票:0回答:1

我有这个有 bottomnav 的主要活动,每个导航显示不同的片段。有'HomeFragment'显示来自实时数据库的帖子的recyclerview,还有已经成功过滤帖子的searchView。问题是,HomeFragment 中 recyclerview 上的每个项目都有一个文本视图,可以导航(替换当前片段)到指定的其他片段。比方说 --- homeFragment 有 recyclerview,是 'A' --- 和 --- 导航片段是 'B'.---

当我在A中单击项目列表上的可点击文本视图时,它将转到B。在 B 中,它有后退按钮,我已经编写了 popbackstack() 代码,所以当它被点击时,它将返回到上一个片段。因为,并不是所有的B总是回到A。

当在A中单击项目列表时,它将转到B。当我从B弹出堆栈时,它将转到A(因为它是前一个堆栈)。片段交易对此很清楚。主要问题是,当我从 B. 返回到 A 时,一切正常,直到我在 A 中添加“onQueryTextListener”。 idk 是什么导致 recyclerview 在我从 B 弹出后不会显示。

这里是短裤图片以获取更多信息。

我的假设是:

  1. 即使在我用 B 替换 A 后,'onQueryTextListener' 是否还在听。

  2. 我是否应该添加不同的片段交易。 (但是,导航是在 itemrecyclerview 适配器上,而不是在片段本身上)

  3. 一定是我不了解导致这个问题的原因

关于我假设的第一点,我已经尝试在运行“onQueryTextListener”之前在搜索视图上添加点击监听器。但还是没用。

在我的第二个假设中,我尝试理解 popbackstack、替换或添加,但不要真正处理我的代码。当它从一开始只有一个目的地时,它只会将替换片段替换为前一个片段。而我的情况是,前一个片段不仅有一个要替换的目的地。这就是为什么我对以前的片段使用 popbackstack 但不替换它的原因。

搜索视图只有在 HomeFragment 上使用下面的当前代码时才有效。除了我一直试图解决的问题,搜索视图没有用。

为此,如果你们可以帮助我,这里是我的代码的详细信息。

HomeFragment.kt

class HomeFragment : Fragment(){
    private lateinit var refUsers : DatabaseReference
    private var firebaseUser: FirebaseUser? = null
    private var postAdapter: PostAdapter? = null
    private var postList: MutableList<Post>? = null
    private var dataList = ArrayList<Post>()

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val bind = FragmentHomeBinding.inflate(layoutInflater)

        bind.cvCategoryArt.setOnClickListener {
            parentFragmentManager.beginTransaction()
                .replace(R.id.mainContainer, CategoryArtFragment()).addToBackStack(null).commit()
        }

        bind.cvCategoryWriting.setOnClickListener {
            parentFragmentManager.beginTransaction()
                .replace(R.id.mainContainer, CategoryWritingFragment()).addToBackStack(null).commit()
        }

        bind.cvCategoryApplication.setOnClickListener {
            parentFragmentManager.beginTransaction()
                .replace(R.id.mainContainer, CategoryApplicationFragment()).addToBackStack(null).commit()
        }

        bind.cvCategoryDesign.setOnClickListener {
            parentFragmentManager.beginTransaction()
                .replace(R.id.mainContainer, CategoryDesignFragment()).addToBackStack(null).commit()
        }

        //RecyclerView
        var recyclerView: RecyclerView? = null
        recyclerView = bind.rvHome
        val linearLayoutManager = LinearLayoutManager(context)
        linearLayoutManager.reverseLayout = true
        linearLayoutManager.stackFromEnd = true
        recyclerView.layoutManager = linearLayoutManager

        refUsers = FirebaseDatabase.getInstance().reference.child("Posts")
        postList = ArrayList()
        dataList = ArrayList()
        val fragmentManager = parentFragmentManager
        postAdapter = context?.let { PostAdapter(it, postList as ArrayList<Post>,fragmentManager) }

        recyclerView.adapter = postAdapter

        bind.pbHomeRecycler.isVisible = true

        retrievePostHome(bind)

        bind.etSearch.setOnQueryTextListener(object : SearchView.OnQueryTextListener{
            override fun onQueryTextSubmit(query: String?): Boolean {
                return false
            }
            override fun onQueryTextChange(newText: String): Boolean {
                searchList(newText)
                return true
            }
        })

        return bind.root
    }

    fun searchList(text: String){
        val searchList = java.util.ArrayList<Post>()
        for (dataClass in postList!!){
            if (dataClass.getTitle().lowercase().contains(text.lowercase(Locale.getDefault()))){
                searchList.add(dataClass)
            }
        }
        postAdapter!!.searchDataList(searchList)
    }

    private fun retrievePostHome(bind: FragmentHomeBinding) {
        firebaseUser = FirebaseAuth.getInstance().currentUser
        val postsRef = FirebaseDatabase.getInstance().reference.child("Posts")
        postsRef.addValueEventListener(object : ValueEventListener {
            @SuppressLint("NotifyDataSetChanged")
            override fun onDataChange(p0: DataSnapshot) {
                postList?.clear()
                bind.pbHomeRecycler.isVisible = false

                for (snapshot in p0.children){
                    val post = snapshot.getValue(Post::class.java)
                    if (post!!.getPublisher() != firebaseUser!!.uid){
                        postList!!.add(post)
                    }
                    postAdapter!!.notifyDataSetChanged()
                }
            }

            override fun onCancelled(error: DatabaseError) {

            }
        })
    }

}

这是“PostAdapter”

class PostAdapter(
    private val mContext: Context,
    private var mPost: List<Post>,
    private val mParentFragmentManager: FragmentManager,
) : RecyclerView.Adapter<PostAdapter.ViewHolder>() {
    private var firebaseUser: FirebaseUser? = null

    inner class ViewHolder(@NonNull itemView: View) : RecyclerView.ViewHolder(itemView) {
        var profileImage: CircleImageView
        var tvUsername: TextView
        var likeButton: ImageView
        var tvTitle: TextView
        var tvPrice: TextView
        var tvDescription: TextView
        var tvSeeMore: TextView
        var postImage: ImageView
        var postCard : CardView

        init {
            profileImage = itemView.findViewById(R.id.cvProfile)
            tvUsername = itemView.findViewById(R.id.tvCvUsername)
            likeButton = itemView.findViewById(R.id.cvFav)
            tvTitle = itemView.findViewById(R.id.tvCvTitle)
            tvPrice = itemView.findViewById(R.id.tvCvPrice)
            tvDescription = itemView.findViewById(R.id.tvCvDesc)
            tvSeeMore = itemView.findViewById(R.id.tvCvSeeMore)
            postImage = itemView.findViewById(R.id.ivPostImage)
            postCard = itemView.findViewById(R.id.cvImagePost)

            tvSeeMore.setOnClickListener{
                val publisherId = mPost[adapterPosition].getPublisher()
                val postId = mPost[adapterPosition].getPostId()

                mParentFragmentManager.beginTransaction()
                    .replace(R.id.mainContainer, DetailPostFragment(publisherId, postId)).addToBackStack(null).commit()
            }

            profileImage.setOnClickListener {
                firebaseUser = FirebaseAuth.getInstance().currentUser

                val publisherId = mPost[adapterPosition].getPublisher()
                val postId = mPost[adapterPosition].getPostId()

                if (publisherId != firebaseUser!!.uid){
                    mParentFragmentManager.beginTransaction()
                        .replace(R.id.mainContainer, ProfileFragment(publisherId, postId)).addToBackStack(null).commit()
                }

            }
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(mContext).inflate(R.layout.item_timeline, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        firebaseUser = FirebaseAuth.getInstance().currentUser
        val post = mPost[position]

        if (post.getPost_image() == ""){
            holder.postCard.isVisible = false
        }else{
            Glide.with(mContext.applicationContext).load(post.getPost_image()).into(holder.postImage)
        }

        holder.tvTitle.text = post.getTitle()
        holder.tvDescription.text = post.getDescription()
        holder.tvPrice.text = post.getPriceRange()

        publisherInfo(holder.profileImage, holder.tvUsername, post.getPublisher())
    }

    private fun publisherInfo(
        profileImage: CircleImageView,
        tvUsername: TextView,
        publisher: String
    ) {
        val usersRef = FirebaseDatabase.getInstance().reference.child("User").child(publisher)

        usersRef.addValueEventListener(object : ValueEventListener {
            override fun onDataChange(snapshot: DataSnapshot) {
                if (snapshot.exists()) {
                    val user = snapshot.getValue(Users::class.java)

                    Glide.with(mContext.applicationContext).load(user!!.getProfile_image())
                        .into(profileImage)
                    tvUsername.text = user!!.getUserName()
                }
            }

            override fun onCancelled(error: DatabaseError) {

            }

        })
    }

    override fun getItemCount(): Int {
        return mPost.size
    }

    fun searchDataList(searchList: List<Post> = mPost){
        mPost = searchList
        notifyDataSetChanged()
    }

}

这里是“DetailFragment”

class DetailPostFragment(publisher: String, postId: String) : Fragment() {
    var refPosts : DatabaseReference? = null
    var refUsers : DatabaseReference? = null
    private var firebaseUser: FirebaseUser? = null
    private var publisherId = publisher
    private var postKey = postId

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        // Inflate the layout for this fragment
        val bind = FragmentDetailPostBinding.inflate(layoutInflater)

        bind.cvChatNowDetail.setOnClickListener {
            val chatIntent = ChatActivity.newIntent(activity!!, publisherId)
            startActivity(chatIntent)
        }

        bind.ivToolbarDetail.setOnClickListener {
            val popupMenu = PopupMenu(requireContext(), it)
            popupMenu.setOnMenuItemClickListener {
                when(it.itemId){
                    R.id.menuEditPost -> {
                        Toast.makeText(requireContext(), "Edit Post Clicked", Toast.LENGTH_LONG).show()
                        true
                    }
                    R.id.menuDeletePost -> {
                        /* Create a new instance of the AlertDialog class. */
                        var alertDialog: AlertDialog? = null
                        val builder = AlertDialog.Builder(requireContext())
                        /* Inflate the layout file for the dialog box. */
                        val view = DialogDeletePostBinding.inflate(layoutInflater)
                        /* Set the view of the dialog box. */
                        builder.setView(view.root)

                        view.btnConfirmCancel.setOnClickListener {
                            alertDialog?.dismiss()
                        }

                        view.btnConfirmYes.setOnClickListener {
                            alertDialog?.dismiss()

                            val dbRef = FirebaseDatabase.getInstance().getReference("Posts").child(postKey)
                            val mTask = dbRef.removeValue()

                            mTask.addOnSuccessListener {
                                Toast.makeText(requireContext(), "Post Successfully Deleted", Toast.LENGTH_LONG).show()

                                parentFragmentManager.beginTransaction()
                                    .replace(R.id.mainContainer, ProfileFragment()).addToBackStack(null).commit()
                            }.addOnCanceledListener {
                                Toast.makeText(requireContext(), "Error While Deleting Post", Toast.LENGTH_LONG).show()
                            }
                        }
                        /* Showing the dialog box. */
                        alertDialog = builder.create()
                        alertDialog.show()
                        true
                    }
                    else -> false
                }
            }
            popupMenu.inflate(R.menu.detailmenu)
            popupMenu.show()
        }

        bind.ivBackDetailPost.setOnClickListener {
            parentFragmentManager.popBackStackImmediate()
        }

        retrieveDetail(bind, publisherId, postKey)
        retrieveUser(bind)
        return bind.root
    }

    private fun retrieveUser(bind: FragmentDetailPostBinding) {
        refUsers = FirebaseDatabase.getInstance().getReference("User").child(publisherId)
        refUsers!!.addValueEventListener(object : ValueEventListener{
            override fun onDataChange(snapshot: DataSnapshot) {
                for (p0 in snapshot.children){

                    val userName = snapshot.child("userName").value.toString()
                    val profileImage = snapshot.child("profile_image").value.toString()

                    bind.tvDetailPostProfileName.text = userName
                    Glide.with(requireContext()).load(profileImage).into(bind.ivDetailPostProfile)
                }
            }

            override fun onCancelled(error: DatabaseError) {

            }
        })
    }

    private fun retrieveDetail(
        binding: FragmentDetailPostBinding,
        publisherId: String,
        postKey: String
    ){
//        println("publisherId = ${publisherId}")
//        println("postId = ${postId}")
        firebaseUser = FirebaseAuth.getInstance().currentUser

        refPosts = FirebaseDatabase.getInstance().getReference("Posts").child(postKey)
        refPosts!!.addListenerForSingleValueEvent(object : ValueEventListener{
            override fun onDataChange(snapshot: DataSnapshot) {

                val targetPost = snapshot.getValue(Post::class.java)
                binding.tvDetailPostTitle.text = targetPost!!.getTitle()
                binding.tvDetailPostDescription.text = targetPost.getDescription()
                binding.tvDetailPostDuration.text = targetPost.getDuration()
                binding.tvDetailPostPrice.text = targetPost.getPriceRange()
                binding.tvDetailPostPayments.text = targetPost.getPaymentMethods()

                if (targetPost.getPost_image() == ""){
                    binding.ivDetailPost.isVisible = false
                } else{
                    Glide.with(requireContext()).load(targetPost.getPost_image()).into(binding.ivDetailPost)
                }

                if (publisherId == firebaseUser!!.uid){
                    binding.cvChatNowDetail.isVisible = false
                    binding.cvSavePost.isVisible = false
                } else {
                    binding.ivToolbarDetail.isVisible = false
                }
            }

            override fun onCancelled(error: DatabaseError) {

            }

        })
    }
}

如果您能帮助我了解导致我的问题的原因,请告诉我。谢谢

kotlin android-fragments firebase-realtime-database android-recyclerview searchview
1个回答
0
投票

如果不查看您的代码,很难确定问题的原因,但这里有一些可能的解决方案:

确保在修改数据集后在 RecyclerView 适配器上调用 notifyDataSetChanged()。此方法更新 RecyclerView 以反映对数据所做的任何更改。

检查当 SearchView 查询文本更改时您是否正确过滤了数据。确保过滤后的数据被传递到 RecyclerView 适配器。

确认您在执行 onQueryTextChange() 方法时没有意外清除 RecyclerView 数据。如果您在搜索查询更改时将适配器的数据设置为空列表或 null,这可能会导致 RecyclerView 消失。

确保 RecyclerView 仍然附加到活动/片段并且不会被过早销毁。您可以通过在 RecyclerView 的 onDetachedFromWindow() 方法中添加日志语句或断点来检查这一点。

如果您使用 replace() 方法在片段之间切换,请尝试改用 add() 和 hide() 方法。这确保了前一个片段不会被破坏,并且可以在用户导航回来时恢复。然后您可以使用 show() 将所需的片段带到前面。

希望这些解决方案之一可以帮助您解决问题。如果没有,请提供更多信息或代码片段,以便我们更好地帮助您。

© www.soinside.com 2019 - 2024. All rights reserved.