- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我尝试在我的应用程序中创建一个通知覆盖层,它可以显示有关某些应用程序明智的重要事件的通知。
我决定使用 RecyclerView
将直接淹没在WindowManager
.
这适用于显示初始项目,但是项目不会更新。
下面是我的实现。所以当我调用 start
not1
和 not2
显示,但当 removeNotification
函数被调用,通知实际上已被删除,并且正在向适配器提交正确的列表,但屏幕上的 View 不会更新。
但是,如果我添加 windowManager.updateViewLayout(recyclerView, layoutParams)
在 submitList
之后里面 removeNotification
,一切似乎都按预期工作,但这次我失去了 RV 动画..
由于这是我第一次直接使用 WindowManager,我很困惑。如果可能的话,有人可以帮我弄清楚发生了什么以及如何实现我想要的。
class NotificationOverlay(private val context: Context) {
private val windowManager: WindowManager =
context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
private val layoutParams = WindowManager.LayoutParams().apply {
gravity = android.view.Gravity.TOP or android.view.Gravity.CENTER_HORIZONTAL
width = WindowManager.LayoutParams.MATCH_PARENT
height = WindowManager.LayoutParams.WRAP_CONTENT
format = PixelFormat.TRANSLUCENT
dimAmount = 0.5f
flags = WindowManager.LayoutParams.FLAG_DIM_BEHIND
type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL
}
private val notifications = mutableListOf<NotificationItem>().also {
it.addAll(listOf(
NotificationItem(title = "not 1", message = "first notification"),
NotificationItem(title = "not 2", message = "second notification")
))
}
private val notificationsAdapter = NotificationAdapter(::removeNotification)
private val recyclerView = RecyclerView(context).apply {
layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
adapter = notificationsAdapter
}
private fun removeNotification(notification: NotificationItem){
notifications.remove(notification)
notificationsAdapter.submitList(notifications)
if(notificationsAdapter.currentList.isEmpty()){
windowManager.removeView(recyclerView)
}
}
fun show(){
windowManager.addView(recyclerView, layoutParams)
notificationsAdapter.submitList(notifications)
}
}
已编辑
class NotificationAdapter(private val onCloseClicked: (NotificationItem) -> Unit):
ListAdapter<NotificationItem, NotificationAdapter.NotificationViewHolder>(DiffCallback()) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NotificationViewHolder {
val binding = ItemNotificationOverlayBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return NotificationViewHolder(binding, onCloseClicked)
}
override fun onBindViewHolder(holder: NotificationViewHolder, position: Int) {
holder.bind(currentList[position])
}
class NotificationViewHolder(private val itemBinding: ItemNotificationOverlayBinding, private val onCloseClicked: (NotificationItem) -> Unit): RecyclerView.ViewHolder(itemBinding.root) {
fun bind(item: NotificationItem) {
itemBinding.title.text = item.title
itemBinding.message.text = item.message
itemBinding.close.setOnClickListener {
onCloseClicked.invoke(item)
}
}
}
class DiffCallback : DiffUtil.ItemCallback<NotificationItem>() {
override fun areItemsTheSame(oldItem: NotificationItem, newItem: NotificationItem) =
oldItem.id == newItem.id
override fun areContentsTheSame(oldItem: NotificationItem, newItem: NotificationItem) =
oldItem == newItem
}
}
在这样一个简单的结构中,每个人都有什么问题?我已经快疯了,想扔掉这个 DiffUtils 并实现老派
notifyItemRemoved
已编辑 2
androidx.recyclerview.widget.AsyncListDiffer
主类
submitList
功能。它在那里进行以下检查:
if (newList == mList) {
// nothing to do (Note - still had to inc generation, since may have ongoing work)
if (commitCallback != null) {
commitCallback.run();
}
return;
}
因此,当我提交列表的相同引用时,甚至从未尝试计算我的差异。
toList()
@IamFr0ssT 建议的函数确实创建了列表的一个新实例,从而使计算我的差异的差异。如果你深入了解
toList()
函数,它最终会创建一个
ArrayList
的新实例基于提供的列表
...return ArrayList(this)
好吧,这个问题与
WindowManager
无关只是
DiffUtil
最佳答案
您正在传递 MutableList notifications
到适配器,并且适配器没有制作列表的副本,它只是使用相同的列表。
当您在 removeNotification
中编辑列表时回调,您正在编辑适配器正在使用的列表。
因此,当计算差异时,它会将它认为当前显示但未显示的列表与其自身进行比较。因此没有差异,也没有 notifyItemRemoved
或其他事件。
我想你可以做些什么来修复它,只需调用 .toList()
调用 submitList()
时在可变列表中:
class NotificationOverlay(private val context: Context) {
...
private fun removeNotification(notification: NotificationItem){
notifications.remove(notification)
notificationsAdapter.submitList(notifications.toList())
if(notificationsAdapter.currentList.isEmpty()){
windowManager.removeView(recyclerView)
}
}
fun show(){
windowManager.addView(recyclerView, layoutParams)
notificationsAdapter.submitList(notifications.toList())
}
}
另外,您如何获得 NotificationItem.id?每个条目应该不同。
关于android - WindowManager 内的 RecyclerView 不更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72688566/
我使用 WindowManager 添加了一个 View 。 它正确地显示了我想做的事情, 但我有一个问题。 这就是问题。 后退键不影响在android组件下(如事件) 我想要的是我添加的 View
I have drawn an overlay using WindowManager. it's width and height are WindowManager.LayoutParams.MA
我正在开发一个锁屏应用程序,我在服务中使用 WindowManager 添加一个 View 。我已经在 list 文件中为所有 Activity 设置了 Orientation PORTRAIT,但这
我在服务中有一个 WindowManger,我添加了一些标志: params = new WindowManager.LayoutParams( WindowManager.LayoutPar
这是我的代码: params = new WindowManager.LayoutParams( WindowManager.LayoutParams.FLAG_FULLSCREEN,
出于某种原因,我不断收到错误膨胀类消息,因为我正在尝试实现 引起:java.lang.NullPointerException 在 pap.crowslanding.GameView.(GameVie
我正在将 WPF 与当前最新、最好的版本 Caliburn.Micro (1.4.1) 一起使用。我用IWindowManager.ShowWindow(...)打开一个新的无模式窗口: privat
我正在尝试使用 WindowManager 覆盖屏幕,它运行良好,但覆盖屏幕不会覆盖页脚,而是覆盖标题。 这是我的代码。 wm = (WindowManager) getSystemService(C
我使用 wordpress,目前正在为 tinymce-editor 编写一个插件。我使用 windowmanager.open() 函数来显示一个模态,但是我不知道如何在这个模态中隐藏 ok 按钮。
我正在使用此代码通过调暗来更改 Activity 的亮度。 WindowManager.LayoutParams layoutParameters = getWindow().getAttribute
我对由 windowmanager 提供支持的 float 窗口有疑问。它停在屏幕边界处,但我希望它通过。 void startF(int x, int y) { removePopup();
我正在尝试使用 windowManager.open({...}) 创建一个模态窗口,它将有一个(可能很长)项目列表。确保它正确显示的唯一方法是将固定高度设置为模态并使其内容可滚动。 Document
WindowManager.removeViewImmediate() 的文档包含警告(强调我的): Special variation of ViewManager.removeView(View)
我有一个服务。我已经使用 WindowManager 在服务运行期间显示一些 UI。此外,我在此服务的生命周期内显示通知。 下面是我的服务类 public class DemoService exte
我(我希望)在为 Google TV 进行一些开发时遇到了一些小问题 我想要做的是我希望能够在右下角显示一个小窗口,这很好..问题是我不确定如何摆脱后台的屏幕保护程序 这是我目前的代码。 pu
显示在屏幕上的窗口 public class FlatingViewService extends Service{ public static WindowManager windowM
我已经针对同一问题查找了几个帖子,但似乎无法解决我的问题。我在整个应用程序中都使用了微调器,它们运行良好。当我尝试在弹出窗口中使用微调器时,选择它时出现错误。弹出窗口用于添加引用,我已经声明了一个全局
我的应用程序在特定时间向用户显示一个按钮作为 TYPE_SYSTEM_ALERT,我试图让用户 move 它。触摸和 move Action 确实使用以下代码注册,但按钮不会 move 。我错过了什么
有人可以在下面详细解释一下吗, 1- What is the use of ActivityManager & WindowManager? 2- What is the difference bet
我正在开发用于背景视频录制 的应用程序,这就是我使用 WindowManager 的原因,但它对我不起作用。出现以下错误: 08-23 15:38:21.021: E/AndroidRuntime(4
我是一名优秀的程序员,十分优秀!