将视图添加到具有时间延迟的活动?
Posted
技术标签:
【中文标题】将视图添加到具有时间延迟的活动?【英文标题】:Adding views to activity with time delay? 【发布时间】:2020-11-25 22:54:58 【问题描述】:我正在尝试修改现有示例应用程序,当用户触摸屏幕时,该应用程序会将视图添加到主活动。这些视图是围绕屏幕浮动的位图图像。触摸屏幕上的任意位置会在该位置添加这些图像之一。
它通过为每次触摸创建一个新视图(位图图像)来做到这一点。
它按原样工作正常,但我正在尝试添加一个功能,它以编程方式添加这些视图而无需任何用户输入。
在下面的代码中,我添加了 onResume() 来尝试此功能。 (在 onCreate() 中添加相同的代码也不起作用。)
不幸的是,它没有像我希望的那样添加它们——它不是在用户启动应用程序后每 500 毫秒添加一个,而是暂停 5 秒,然后一次添加所有十个。
显然我是 android dev 的新手,所以我不知道从哪里开始。我需要做些什么来实现延迟,使其每半秒添加一个新视图?为什么默认情况下会这样做?
谢谢!
class ImageScreen : Activity()
public override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.imagescreen)
mFrame = findViewById<View>(R.id.frame) as FrameLayout
mBitmap = BitmapFactory.decodeResource(resources, R.drawable.myBitmapImage)
mFrame!!.setOnTouchListener _, event ->
createImage(event.x, event.y)
true
override fun onResume()
super.onResume()
for (i in 0..10)
createImage(xpos.random(), ypos.random())
sleep(500)
private fun createImage(x: Float, y: Float)
mFrame!!.addView(myImage(applicationContext, x, y))
inner class myImage internal constructor(context: Context, x: Float, y: Float) : View(context)
private fun createScaledBitmap(r: Random)
mScaledBitmap = Bitmap.createScaledBitmap(mBitmap!!, mScaledBitmapWidth, mScaledBitmapWidth, false)
fun start()
val executor = Executors.newScheduledThreadPool(1)
mMoverFuture = executor.scheduleWithFixedDelay(
if (changePosIfStillOnScreen())
postInvalidate()
else stop(false)
, 0, REFRESH_RATE.toLong(), TimeUnit.MILLISECONDS)
private fun stop()
mFrame!!.removeView(this@myImage)
@Synchronized
override fun onDraw(canvas: Canvas)
canvas.save()
canvas.drawBitmap(mScaledBitmap!!, mXPos, mYPos, mPainter)
canvas.restore()
// Additional code, such as functions and variable declarations that are not pertinent to this question, have been removed for simplicity
【问题讨论】:
【参考方案1】:注意:下面的sn-p是从java角度看的,可能需要修改成kotlin
Handler handler = new Handler(getMainLooper());
Runnable runnable = new Runnable()
@Override
public void run()
if (counter < 5)
createImage(0, 0); //your positions
handler.postDelayed(this, 500);
counter++;
;
handler.postDelayed(runnable, 500);
注意:counter 是一个 int 变量来确定...计数。
推理:
您在任何 UI 类(活动、片段、视图)中执行的所有代码都默认为 UI 线程。如果您在该线程中执行任何 Thread.sleep()
操作,则整个 UI 将暂时冻结,这在某些情况下可能导致 ANR 崩溃 ANR。Handler
可以在这里为您提供帮助。它需要一个Looper
引用来实例化。当您调用post(Runnable)
或可选的postDelayed(Runnable, long millis)
时,它将采用Runnable
并在UI 线程上执行它(延迟或其他方式)。但是,对于每次使用,您都需要再次调用 post
,即在 Runnable
中递归调用 post
。我希望这会有所帮助!! p>
【讨论】:
谢谢!那工作得很好。但是我仍然不完全清楚为什么所有十个视图最初同时出现。我知道 sleep() 冻结了线程,但是假设我对冻结的线程没问题(在那段时间我不需要任何用户输入),为什么在添加其他视图之间不简单地冻结线程十次?是否存在假设设计者希望一次添加所有元素的 UI 线程的某些属性? 就我对视图层次结构的了解而言,想要膨胀视图与实际膨胀的视图之间有一点延迟,因为所有视图调用都在后端排队。这可能是因为睡眠-唤醒周期太快,视图无法在屏幕上具体化。val executor = Executors.newScheduledThreadPool(1) mMoverFuture = executor.scheduleWithFixedDelay( if (changePosIfStillOnScreen()) postInvalidate() else stop(false) , 0, REFRESH_RATE.toLong(), TimeUnit.MILLISECONDS)
这可能是加载图像的部分,在您设置图像和显示图像之间引入了轻微的延迟。【参考方案2】:
它会暂停 5 秒,然后一次添加所有 10 个,这是因为您在代码中使用了sleep(500)
,它会冻结主线程(UI 线程)。
使用handler实现延时动作,Ref:https://developer.android.com/reference/android/os/Handler
【讨论】:
以上是关于将视图添加到具有时间延迟的活动?的主要内容,如果未能解决你的问题,请参考以下文章