我有这个有 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 弹出后不会显示。
这里是短裤图片以获取更多信息。
我的假设是:
即使在我用 B 替换 A 后,'onQueryTextListener' 是否还在听。
我是否应该添加不同的片段交易。 (但是,导航是在 itemrecyclerview 适配器上,而不是在片段本身上)
一定是我不了解导致这个问题的原因
关于我假设的第一点,我已经尝试在运行“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) {
}
})
}
}
如果您能帮助我了解导致我的问题的原因,请告诉我。谢谢
如果不查看您的代码,很难确定问题的原因,但这里有一些可能的解决方案:
确保在修改数据集后在 RecyclerView 适配器上调用 notifyDataSetChanged()。此方法更新 RecyclerView 以反映对数据所做的任何更改。
检查当 SearchView 查询文本更改时您是否正确过滤了数据。确保过滤后的数据被传递到 RecyclerView 适配器。
确认您在执行 onQueryTextChange() 方法时没有意外清除 RecyclerView 数据。如果您在搜索查询更改时将适配器的数据设置为空列表或 null,这可能会导致 RecyclerView 消失。
确保 RecyclerView 仍然附加到活动/片段并且不会被过早销毁。您可以通过在 RecyclerView 的 onDetachedFromWindow() 方法中添加日志语句或断点来检查这一点。
如果您使用 replace() 方法在片段之间切换,请尝试改用 add() 和 hide() 方法。这确保了前一个片段不会被破坏,并且可以在用户导航回来时恢复。然后您可以使用 show() 将所需的片段带到前面。
希望这些解决方案之一可以帮助您解决问题。如果没有,请提供更多信息或代码片段,以便我们更好地帮助您。