android-recyclerview 相关问题

RecyclerView小部件是ListView和GridView的更高级和灵活的版本。

在导航栏中使用片段时不显示回收器视图

我在使用导航栏时遇到回收站视图不起作用的问题。 最初我编写了代码,将我的 4 个片段添加到导航栏配置中,并且导航工作正常...

回答 1 投票 0

当视图离开屏幕时,Android 动画在 RecyclerView 中停止工作

我这样设置动画: @覆盖 公共无效onBindViewHolder(ViewHolder持有者,int位置){ 动画 anim = AnimationUtils.loadAnimation(context, R.anim.rotate); ...

回答 3 投票 0

HorizontalScrollView 内的 RecyclerView 未显示所有项目

我在 HorizontalScrollView 中有一个 RecyclerView。我没有在 RecyclerView 中看到所有项目。我看过,即使适配器中的列表有 7 个项目,onBindViewHolder 也只会调用 4 个...

回答 4 投票 0

如何将 SpanSizeLookup 逻辑添加到 VerticalGridView?

我正在开发一个用于电视平台的应用程序,当带有 GridLayoutManager 的默认 RecyclerView 无法正确处理 DPAD 的焦点控制时,我遇到了一个问题。它有以下问题: 重点是

回答 2 投票 0

将视图模型传递到回收器视图适配器中会导致内存泄漏吗?

目前我正在试验视图模型,想知道将视图模型传递给 recyclerview 适配器是否会导致内存泄漏?适配器中视图模型的唯一目的是提供...

回答 1 投票 0

RecyclerView 移动到 ListFragment 时会无限期加载

我已经按照本教程进行操作:https://developer.android.com/codelabs/android-room-with-a-view-kotlin。 代码工作完美,但我想将 RecyclerView 移动到片段。 现在列表已加载

回答 1 投票 0

希望 recyclerview 在创建活动时从下到上开始,并在添加新项目时再次在底部滚动

我的 Android 应用程序中有一个名为 ChatActivity 的活动。这是 xml 布局: 我的 Android 应用程序中有一个名为 ChatActivity 的活动。这是 xml 布局: <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/main" android:layout_width="match_parent" android:layout_height="match_parent" android:windowSoftInputMode="adjustResize" tools:context=".ui.home.ui.chat.ChatActivity"> <com.google.android.material.appbar.MaterialToolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:navigationIcon="?attr/homeAsUpIndicator" app:navigationIconTint="@color/black" app:title="@string/chat" app:titleCentered="true" > <de.hdodenhof.circleimageview.CircleImageView android:id="@+id/ivProfile" android:layout_width="@dimen/_30sdp" android:layout_height="@dimen/_30sdp" android:src="@drawable/ic_dummy_user" android:layout_marginHorizontal="@dimen/_10sdp" android:layout_gravity="end" /> </com.google.android.material.appbar.MaterialToolbar> <androidx.recyclerview.widget.RecyclerView android:id="@+id/rvMessages" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_constraintTop_toBottomOf="@id/toolbar" android:paddingBottom="@dimen/_95sdp" app:layout_constraintHorizontal_bias="1.0" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintVertical_bias="1.0" tools:listitem="@layout/item_message_sent" /> <com.google.android.material.textfield.TextInputLayout android:id="@+id/tiMessage" style="@style/textInputLayout" android:layout_width="0dp" android:layout_height="wrap_content" android:maxHeight="@dimen/_200sdp" android:layout_marginLeft="@dimen/_5sdp" android:layout_marginRight="@dimen/_35sdp" android:layout_marginTop="5dp" android:layout_marginBottom="5dp" app:errorEnabled="false" android:layout_marginVertical="@dimen/_5sdp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" > <com.google.android.material.textfield.TextInputEditText android:layout_width="match_parent" android:layout_height="wrap_content" android:maxHeight="@dimen/_200sdp" android:autofillHints="name" android:hint="@string/message" android:inputType="textMultiLine" /> </com.google.android.material.textfield.TextInputLayout> <ImageView android:id="@+id/ivSend" android:layout_width="@dimen/_25sdp" android:layout_height="@dimen/_25sdp" android:src="@drawable/ic_send_message" app:layout_constraintRight_toRightOf="parent" app:layout_constraintBottom_toBottomOf="parent" android:layout_marginBottom="@dimen/_12sdp" app:layout_constraintLeft_toRightOf="@id/tiMessage" app:tint="@color/blue" /> </androidx.constraintlayout.widget.ConstraintLayout> 当我打开 textInput 字段时,布局不适应它,它仅显示要打开的键盘,但是当我在键盘中键入时,它确实会在文本输入布局中键入,但在键入时用户无法看到文本输入布局。关闭键盘 + 回收视图开始从上到下滚动,但我希望它像聊天一样,从下到上。在添加的新消息上,它确实滚动到底部,但在现有列表的最后一项上,而不是在新项目上。 我尝试过使用 android:windowSoftInputMode="adjustResize" 作为键盘和 private fun scrollToBottom() { binding.rvMessages.scrollToPosition(adapter.itemCount -1) } 用于回收视图。 欢迎任何优化代码/改进的建议。我的活动代码是: @AndroidEntryPoint class ChatActivity : AppCompatActivity() { private lateinit var binding: ActivityChatBinding private lateinit var database: DatabaseReference private lateinit var adapter: ChatAdapter private var currentUserId: Int = 0 private var otherUserId: Int = 0 private lateinit var conversationId: String private var convoId = "" override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() binding = ActivityChatBinding.inflate(layoutInflater) setContentView(binding.root) ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets -> val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) insets } binding.toolbar.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() } val userDetails = intent.getParcelableExtra<ConnectionDetailDTO>("USER_DETAILS") val currentUser = Paper.book().read<User>(Constant.k_user) currentUserId = currentUser?.id!! otherUserId = userDetails?.id!! binding.toolbar.title = userDetails.name Glide.with(this).load(userDetails.profileUrl).placeholder(R.drawable.ic_dummy_user).into(binding.ivProfile) binding.ivProfile.setOnClickListener{showProfile()} adapter = ChatAdapter(currentUserId) binding.rvMessages.layoutManager = LinearLayoutManager(this) binding.rvMessages.adapter = adapter scrollToBottom() val database = FirebaseDatabase.getInstance() val reference = database.getReference("Conversations") reference.addValueEventListener(object : ValueEventListener { override fun onDataChange(dataSnapshot: DataSnapshot) { val messages = mutableListOf<Message>() for (conversationSnapshot in dataSnapshot.children) { val conversationIdParts = conversationSnapshot.key?.split("_") if (conversationIdParts?.size == 3) { val firstUserId = conversationIdParts[1] val secondUserId = conversationIdParts[2] convoId = "conversation_${firstUserId}_${secondUserId}" if (firstUserId == currentUserId.toString() && secondUserId == otherUserId.toString() || firstUserId == otherUserId.toString() && secondUserId == currentUserId.toString()) { val conversationMessages = mutableListOf<Message>() for (messageSnapshot in conversationSnapshot.child("messages").children) { val content = messageSnapshot.child("content").value.toString() val date = messageSnapshot.child("date").value.toString() val messageId = messageSnapshot?.child("id")?.value.toString() val isRead = messageSnapshot.child("isRead").value as? Boolean ?: false val name = messageSnapshot.child("name").value.toString() val senderEmail = messageSnapshot.child("senderEmail").value.toString() val type = messageSnapshot.child("type").value.toString() val message = Message(content, date, messageId, isRead, name, senderEmail, type) conversationMessages.add(message) Log.d(TAG, "onDataChange: $message") } messages.addAll(conversationMessages) } } } Log.d(TAG, "onDataChange: $messages") adapter.updateMessages(messages) } override fun onCancelled(databaseError: DatabaseError) { println("Error: ${databaseError.message}") } }) binding.ivSend.setOnClickListener { val messageText = binding.tiMessage.editText?.text.toString().trim() if (messageText.isNotEmpty()) { val conversationId1 = "conversation_${currentUserId}_${otherUserId}" val conversationId2 = "conversation_${otherUserId}_${currentUserId}" reference.child(conversationId1).get().addOnCompleteListener { task -> if (task.isSuccessful) { val data = task.result?.value val conversationId = if (data != null) { conversationId1 } else { conversationId2 } val messageReference = reference.child(conversationId).child("messages").push() val message = Message( content = messageText, date = SimpleDateFormat( "yyyy-MM-dd HH:mm:ss", Locale.getDefault() ).format(Date()), id = messageReference.key!!, isRead = false, name = currentUser?.name ?: "", senderEmail = currentUserId.toString(), type = "text" ) messageReference.setValue(message) binding.tiMessage.editText?.setText("") scrollToBottom() } } addUser(currentUserId.toString()) } } } private fun scrollToBottom() { binding.rvMessages.scrollToPosition(adapter.itemCount -1) } } 我尝试了 StackOverFLow 和 Chat GPT 的回收器视图解决方案 回收视图开始从上到下滚动,但我希望它是 就像聊天一样,从下到上。添加新消息后,它会滚动到 底部,但在现有列表的最后一项上,而不是在新项目上。 我尝试过使用.. recyclerView 从顶部开始并且不会在新项目上滚动到底部的原因是因为您在将项目添加到适配器之前调用了scrollToBottom()。 删除scrollToBottom()中的binding.ivSend.setOnClickListener{}并将其添加到adapter.updateMessages(messages)下面 Log.d(TAG, "onDataChange: $messages") adapter.updateMessages(messages) scrollToBottom() 这样,当首次从数据库加载项目以及添加新项目时,回收器视图将向下滚动。 为了更容易阅读代码,我建议您将代码排序到方法中,而不是将所有内容都放在 override fun onCreate(savedInstanceState: Bundle?) {} 中。 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() binding = ActivityChatBinding.inflate(layoutInflater) setContentView(binding.root) ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets -> val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) insets } setArgs() setupUI() setupDatabase() setupListeners() } private fun setArgs(){ userDetails = intent.getParcelableExtra<ConnectionDetailDTO>("USER_DETAILS") currentUser = Paper.book().read<User>(Constant.k_user) } private fun setupUI(){ //toolbar binding.toolbar.setNavigationOnClickListener { onBackPressedDispatcher.onBackPressed() } binding.toolbar.title = userDetails.name Glide.with(this).load(userDetails.profileUrl).placeholder(R.drawable.ic_dummy_user).into(binding.ivProfile) binding.ivProfile.setOnClickListener{showProfile()} //recycler view adapter = ChatAdapter(currentUser.id) binding.rvMessages.layoutManager = LinearLayoutManager(this) binding.rvMessages.adapter = adapter } private fun setupDatabase(){ database = FirebaseDatabase.getInstance() reference = database.getReference("Conversations") } private fun setupListeners(){ reference.addValueEventListener(object : ValueEventListener { override fun onDataChange(dataSnapshot: DataSnapshot) { val messages = mutableListOf<Message>() for (conversationSnapshot in dataSnapshot.children) { val conversationIdParts = conversationSnapshot.key?.split("_") if (conversationIdParts?.size == 3) { val firstUserId = conversationIdParts[1] val secondUserId = conversationIdParts[2] convoId = "conversation_${firstUserId}_${secondUserId}" if (firstUserId == currentUser.id.toString() && secondUserId == currentUser.id.toString() || firstUserId == userDetails.id.toString() && secondUserId == currentUser.id.toString()) { val conversationMessages = mutableListOf<Message>() for (messageSnapshot in conversationSnapshot.child("messages").children) { val content = messageSnapshot.child("content").value.toString() val date = messageSnapshot.child("date").value.toString() val messageId = messageSnapshot?.child("id")?.value.toString() val isRead = messageSnapshot.child("isRead").value as? Boolean ?: false val name = messageSnapshot.child("name").value.toString() val senderEmail = messageSnapshot.child("senderEmail").value.toString() val type = messageSnapshot.child("type").value.toString() val message = Message(content, date, messageId, isRead, name, senderEmail, type) conversationMessages.add(message) Log.d(TAG, "onDataChange: $message") } messages.addAll(conversationMessages) } } } Log.d(TAG, "onDataChange: $messages") adapter.updateMessages(messages) } override fun onCancelled(databaseError: DatabaseError) { println("Error: ${databaseError.message}") } }) binding.ivSend.setOnClickListener { val messageText = binding.tiMessage.editText?.text.toString().trim() if (messageText.isNotEmpty()) { val conversationId1 = "conversation_${currentUser.id}_${userDetails.id}" val conversationId2 = "conversation_${userDetails.id}_${currentUser.id}" reference.child(conversationId1).get().addOnCompleteListener { task -> if (task.isSuccessful) { val data = task.result?.value val conversationId = if (data != null) { conversationId1 } else { conversationId2 } val messageReference = reference.child(conversationId).child("messages").push() val message = Message( content = messageText, date = SimpleDateFormat( "yyyy-MM-dd HH:mm:ss", Locale.getDefault() ).format(Date()), id = messageReference.key!!, isRead = false, name = currentUser?.name ?: "", senderEmail = currentUser.id.toString(), type = "text" ) messageReference.setValue(message) binding.tiMessage.editText?.setText("") scrollToBottom() } } addUser(currentUser.id.toString()) } } } 最后我建议您阅读 MVVM 设计模式以获取更多代码结构。

回答 1 投票 0

我的 MainActivity.java 有问题,当我将 FirebaseRecycler 适配器放入 OnStart()r 中时,OnStart() 方法不会调用 CheckUserExistence()

我的 MainActivity.java 代码中有一个问题,我在其中显示所有用户帖子,问题出在我的 onStart() 方法中,当我将 FirebaseRecyclerAdapter 放入 onStart() 方法中时,onStart() 不会调用

回答 1 投票 0

如何在Coordinator布局中添加拉动刷新

我在CoordiantorLayout中有一个AppBar和RecyclerView。 SwipeToRefresh 必须全屏,但 RecyclerView 不能向下滚动。 我在 AppBar 中有一个 RecyclerView 和 CoordiantorLayout。 SwipeToRefresh 必须全屏,但 RecyclerView 不能向下滚动。 <com.google.android.material.appbar.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:layout_width="match_parent" android:layout_height="128dp"/> </com.google.android.material.appbar.AppBarLayout> <androidx.recyclerview.widget.RecyclerView android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> <androidx.swiperefreshlayout.widget.SwipeRefreshLayout android:layout_width="match_parent" android:layout_height="match_parent" /> </androidx.coordinatorlayout.widget.CoordinatorLayout> 如何在没有库的情况下在 Coordinator 布局中添加全屏拉动刷新。 您可以在 AppBar 未完全展开时禁用滑动刷新布局,并在 AppBar 完全展开时启用它。 vAppBar.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { _, verticalOffset -> vSwipeRefresh.isEnabled = verticalOffset == 0 }) 我添加了 swipetorefresh 顶层,如上面的答案。我用下面的代码解决了向上滚动的问题。感谢穆罕默德雷扎:) recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener(){ @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { int topRowVerticalPosition = (recyclerView == null || recyclerView.getChildCount() == 0) ? 0 : recyclerView.getChildAt(0).getTop(); swipeRefreshLayout.setEnabled(topRowVerticalPosition >= 0); } @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); } }); 尝试将 SwipeRefreshLayout 设置为根父级,如下所示: <?xml version="1.0" encoding="utf-8"?> <androidx.swiperefreshlayout.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <androidx.coordinatorlayout.widget.CoordinatorLayout android:layout_width="match_parent" android:layout_height="match_parent"> <androidx.recyclerview.widget.RecyclerView android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> <com.google.android.material.appbar.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:layout_width="match_parent" android:layout_height="128dp" /> </com.google.android.material.appbar.AppBarLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout> 我也面临着同样的问题 然后我用编程解决了它 binding.appbar.addOnOffsetChangedListener { _, verticalOffset -> binding.swipeRefreshLayout.isEnabled = verticalOffset == 0 } 要将 SwipeRefreshLayout 与 CoordinatorLayout 和 FloatingActionButton (FAB) 一起使用,您可以按照以下步骤操作: 更新布局 XML: 打开要添加组件的 XML 布局文件。 包括 <androidx.swiperefreshlayout.widget.SwipeRefreshLayout> 元素作为父布局。 在 SwipeRefreshLayout 内部,包含 CoordinatorLayout 和其他视图。 这是一个例子:<androidx.swiperefreshlayout.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/swipe_refresh_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <CoordinatorLayout android:layout_width="match_parent" android:layout_height="match_parent"> <com.google.android.material.appbar.MaterialToolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" android:elevation="4dp" app:popupTheme="@style/ThemeOverlay.MaterialComponents.Light" app:title="My Toolbar" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" app:layout_anchor="@id/toolbar" app:layout_anchorGravity="bottom" /> <com.google.android.material.floatingactionbutton.FloatingActionButton android:id="@+id/fab_scroll_top" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_arrow_upward" app:layout_anchor="@id/recycler_view" app:layout_anchorGravity="bottom|end" app:layout_margin="@dimen/fab_margin" /> </CoordinatorLayout> </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

回答 5 投票 0

获取 java.lang.IndexOutOfBoundsException:对于我的适配器代码,索引 8 超出长度 8 的范围

我的 logcat 看起来像: logcat 应用程序崩溃 类 ChatAdapter(private val currentUserId: Int) : RecyclerView.Adapter() { 私有 val 消息 = mutableListO...

回答 1 投票 0


检查 smoothScrollToPosition 何时完成

我想检查 smoothScrollToPosition 何时完成滚动回 recyclerview 的第一项。我尝试这样做,只有在 smoothScrollToPosition 仍然存在时才有效

回答 3 投票 0

无尽滚动kotlin回收视图/ListView

我拼命尝试使用 kotlin 在 Android 应用程序上实现无限滚动。所有教程要么毫无用处,因为它们没有正确解释事情。例如: https://github.com/

回答 3 投票 0

带动态页码导航的分页

所以,我想创建图像中显示的视图。 这是我正在开发的项目的用户界面! 首先我认为我应该使用回收器视图等,但后来我认为逻辑将非常困难! 现在我...

回答 1 投票 0

分页动态页码导航

所以,我想创建图像中显示的视图。 这是我正在开发的项目的用户界面! 首先我认为我应该使用回收器视图等,但后来我认为逻辑将非常困难! 现在我...

回答 1 投票 0

ComposeView 未附加到窗口 - Jetpack Compose

我尝试将 FlexBox 布局与 JetpackCompose 结合使用。我假设我可以使用普通的 RecyclerView 并使用 ComposeView 来渲染我的视图。 所以我从文档开始并尝试了所有...

回答 1 投票 0

在Android中的列表视图和网格视图之间高效切换,平滑过渡

我正在尝试实现一个视图切换,使用户能够在Android中的“列表视图”和“网格视图”之间切换。然而,我已经做到了这一点,但我对结果并不满意

回答 1 投票 0

点击当前fragment的空白处即可看到Recyclerview

在我的主要活动中,我有一个 RecyclerView。假设我单击一个名为“Back to 80s”的项目,它会打开一个相应的片段(占据整个窗口)。然而,有一个问题:...

回答 1 投票 0

回收站视图中自动调整图像卡视图

我正在研究RecyclerView以在CardView中显示图像。 我使用 GridLayoutManager 并且在每行中指定了 3 个项目: mLayoutManager = new GridLayoutManager(context,3); 问题:图像...

回答 2 投票 0

java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“void android.widget.TextView.setText(java.lang.CharSequence)”

我正在使用 Android Studio 和 firebase 开发一个聊天应用程序,因此为了区分消息发送者和接收者,我尝试了以下代码: 消息适配器: 导入 android.content.Cont...

回答 1 投票 0

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