我正在开发一个聊天应用程序。我有一个聊天活动,两个用户可以发送WhatsApp之类的消息,但我有个问题。
就像你在图中看到的(https://ibb.co/3cyYX01),滚动时视图乱糟糟的,我想我知道为什么了。
在查看了这些帖子后:RecyclerView在滚动时出错,Android:RecyclerView在滚动后内容出错
我假设问题可能出在函数onBindViewHolder
中的回收器视图适配器中,因为我在某些视图(VIEW.GONE和VIEW.VISIBLE)上使用了可见性选项,并且我认为这些视图正在以错误的可见性重新绘制。
此外,我在< code>onBindViewHolder中使用了< code > holder . setisrecyclable(false),以便检查是否是回收部分导致了问题,并且当我使用它时,它工作得很好。
这是RecyclerView适配器:
private const val SEND_LAYOUT = 0
private const val RECEIVED_LAYOUT = 1
class ChatRecyclerViewAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private lateinit var receiverUserPic: String
private lateinit var messageList: List<Message>
private lateinit var currentUserPic: String
private lateinit var currentUserUID: String
private lateinit var targetUID: String
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val viewHolder: RecyclerView.ViewHolder
val view: View
viewHolder = if (viewType == SEND_LAYOUT) {
view = LayoutInflater.from(parent.context)
.inflate(R.layout.sent_message_row, parent, false)
SentViewHolder(view)
} else {
view = LayoutInflater.from(parent.context)
.inflate(R.layout.recieved_message_row, parent, false)
ReceivedViewHolder(view)
}
return viewHolder
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
//holder.setIsRecyclable(false)
val currentMessage = messageList[position]
if (holder.itemViewType == SEND_LAYOUT) {
holder as SentViewHolder
holder.bindSentRow(currentMessage)
} else {
holder as ReceivedViewHolder
holder.bindReceivedRow(currentMessage)
}
}
override fun getItemCount(): Int {
return messageList.size
}
override fun getItemViewType(position: Int): Int {
val currentMessage = messageList[position]
return if (FirebaseAuth.getInstance().currentUser?.uid.equals(currentMessage.sender))
SEND_LAYOUT
else
RECEIVED_LAYOUT
}
inner class SentViewHolder(private val itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bindSentRow(message: Message) {
val sentMessageTextView =
itemView.findViewById<TextView>(R.id.sentMessage)
val sentImage = itemView.findViewById<ImageView>(R.id.sentImage)
val profileImage =
itemView.findViewById<ImageView>(R.id.sentMessageProfilePicture)
val sentIsSeenImageTextView =
itemView.findViewById<TextView>(R.id.sentIsSeenImageTextView)
val sentIsSeenTextView =
itemView.findViewById<TextView>(R.id.sentIsSeenTextView)
profileImage.setOnClickListener {
val visitProfileIntent = Intent(it.context, VisitProfileActivity::class.java)
visitProfileIntent.putExtra("targetUID", currentUserUID)
it.context.startActivity(visitProfileIntent)
}
if (message.message.equals("Sent you an image") && !message.url.equals("")) {
sentMessageTextView.visibility = View.GONE
sentIsSeenImageTextView.visibility = View.VISIBLE
sentIsSeenTextView.visibility = View.GONE
sentImage.visibility = View.VISIBLE
Glide.with(itemView.rootView).load(message.url)
.override(SIZE_ORIGINAL, SIZE_ORIGINAL)
.error(R.drawable.error_icon)
.placeholder(R.drawable.loading_icon)
.listener(object : RequestListener<Drawable?> {
override fun onLoadFailed(
@Nullable e: GlideException?,
model: Any,
target: Target<Drawable?>,
isFirstResource: Boolean
): Boolean {
return false
}
override fun onResourceReady(
resource: Drawable?,
model: Any?,
target: Target<Drawable?>?,
dataSource: DataSource?,
isFirstResource: Boolean
): Boolean {
return false
}
}).into(sentImage)
if (adapterPosition == messageList.size - 1) {
sentIsSeenImageTextView.visibility = View.VISIBLE
sentIsSeenTextView.visibility = View.GONE
if (message.seen == true) {
sentIsSeenImageTextView.text = "Seen"
} else {
sentIsSeenImageTextView.text = "Sent"
}
} else {
sentIsSeenImageTextView.visibility = View.GONE
}
} else {
sentMessageTextView.visibility = View.VISIBLE
sentMessageTextView.text = message.message
sentIsSeenImageTextView.visibility = View.GONE
if (adapterPosition == messageList.size - 1) {
sentIsSeenTextView.visibility = View.VISIBLE
sentIsSeenImageTextView.visibility = View.GONE
if (message.seen == true) {
sentIsSeenTextView.text = "Seen"
} else {
sentIsSeenTextView.text = "Sent"
}
}
}
Glide.with(itemView.rootView).load(currentUserPic).into(profileImage)
}
}
inner class ReceivedViewHolder(private val itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bindReceivedRow(message: Message) {
val receiveMessageTextView =
itemView.findViewById<TextView>(R.id.receivedMessage)
val receiveImage =
itemView.findViewById<ImageView>(R.id.receivedImage)
val receiveProfileImage =
itemView.findViewById<ImageView>(R.id.receivedMessageProfileImage)
receiveProfileImage.setOnClickListener {
val visitProfileIntent = Intent(it.context, VisitProfileActivity::class.java)
visitProfileIntent.putExtra("targetUID", targetUID)
it.context.startActivity(visitProfileIntent)
}
if (message.message.equals("Sent you an image") && !message.url.equals("")) {
receiveMessageTextView.visibility = View.GONE
receiveImage.visibility = View.VISIBLE
Glide.with(itemView.rootView).load(message.url).into(receiveImage)
} else {
receiveMessageTextView.visibility = View.VISIBLE
receiveMessageTextView.text = message.message
}
Glide.with(itemView.rootView).load(receiverUserPic).into(receiveProfileImage)
}
}
fun getMessageList(): List<Message> {
return messageList
}
fun setMessagesList(
newList: List<Message>,
userProfilePic: String,
userProfilePic1: String,
currentUID: String,
receiverUID: String
) {
messageList = newList
currentUserPic = userProfilePic
receiverUserPic = userProfilePic1
currentUserUID = currentUID
targetUID = receiverUID
notifyDataSetChanged()
}
}
粘贴链接: https://pastebin.com/Ri5pUAdk
非常感谢。
匿名用户
因为视图持有者正在被回收和重用,导致您的视图处于错误状态。
在< code>SendViewHolder类中,您只需通过将visibility设置为visible来处理if块中的< code > senimage 的状态。因此,您还需要在else块中将它的可见性设置为gone。
或者您可以先重置视图可见性,然后像下面这样显示它。
fun bindSendRow(message: Message) {
sentMessageTextView.visibility = View.GONE
sentImage.visibilty = View.GONE
if(shouldShowImage){
sentImage.visibility = View.VISIBLE
} else if(shouldShowText){
sentMessageTextView.visibility = View.VISIBLE
}
}
< code > recycle view 的工作就是基于此,它回收视图来显示列表。当您滚动时,屏幕外的< code >视图不会被销毁,而是再次被重新使用以显示新的列表项目。因此,如果您更改视图的< code>visibility或任何其他属性,并且不在< code>onBindViewHolder中再次重置它,那么它将显示在回收之前设置的所有属性。
fun bind(data: Data) {
val textView = itemView.findViewById<TextView>(R.id.tvText)
if(data.text.isEmpty()) {
textView.visibility = View.GONE
}
}
在上述方法中,当文本为空
时,我们隐藏文本视图
,但我们没有在或
条件中设置任何内容。因此,当
视图
(我们已将可见性设置为消失了
)将被回收时,它们将永远不会显示文本视图
,因为它正在重用
查看
。为了解决这个问题,我们必须分别为<code>true</code>和<code>false</code>条件设置视图的属性。
fun bind(data: Data) {
val textView = itemView.findViewById<TextView>(R.id.tvText)
if(data.text.isEmpty()) {
textView.visibility = View.GONE
} else {
textView.visibility = View.VISIBLE
}
}
在
SentViewHolder
和 ReceivedViewHolder
中,您将 ImageView
的可见性设置为可见
sentImage.visibility = View.VISIBLE
receiveImage.visibility = View.VISIBLE
但您从未将其设置为<code>消失</code>。
在< code >(message . message . equals(" Sent you a image ")的else条件中
利用UIScrollView实现视差滚动效果。在demo中,滑动ScrollView,背景图和文字的滚动速度不一样。直接用ScrollView 的协议,对其子视图的坐标进行随机系数比例的位置移动修正,从而实现视差滚动效果。没有用其他的框架,代码简单。 作者说:原创Demo 转载请注明出处。 [Code4App.com]
问题内容: 我有一个用CSS3进行动画处理的条形图,当前该动画在页面加载时激活。 我的问题是,由于之前有很多内容,因此给定的条形图不在屏幕上,因此当用户向下滚动到该条形图时,动画已经结束。 我正在寻找通过CSS3或jQuery仅在查看者看到图表时激活条形图上的CSS3动画的方法。 如果在页面加载后立即快速向下滚动,则可以看到该动画。 另外,我不知道这是否重要,但是我在页面上有此条形图的多个实例。
我试图实现某种排序工具栏-但没有工具栏(而不是工具栏,它将是一个下拉元素,它本质上是一个RelativeLayout,其正下方有LinearLayout(下拉列表中的扩展项目),一旦按下下拉菜单,它就会在整个布局上悬停。 我考虑过实现折叠工具栏并将下拉列表放入工具栏中,但这可能不是一个好主意,因为下拉列表不是像图像视图这样的静态组件。我还在我的应用程序中使用了ActionBar,因此迁移到工具栏很
我有一个水平ScrollView,它有两个元素:CardView和水平RecycerView。所以,当用户水平滚动时,我希望这两个元素滚动。 我想有这样的东西:Goal,橙色的线是CardView,黄色的线是RecycerView。当用户滚动时,两个元素滚动,如下所示:Scrolled Goal。 现在在我的应用程序中,当用户滚动时,只有RecycerView滚动。CardView保持在他的位置。
实现循环ScrollView。有以下特色: 1、循环的scrollview 2、类似于tableview的编程方式 3、可定制化的内容 4、灵活运用可用于移步加载图片 5、结构化,可扩展性高 [Code4App.com]
我有一个当用户滚动时显示隐藏单元格的tableView。不确定为什么会出现这种情况。 在视图中DidLoad() 用户点击按钮后,表格将以可设置动画的方式展开。 在 func tableView(_ tableView: UITableView, cellForRowAt 索引路径: 索引路径) - 当我滚动时,所有单元格都被隐藏。我看到它们是在单元格中创建的,但是,它们不会出现在我的屏幕上。为什