添加视图到 activity 有时间延迟?
Adding views to activity with time delay?
我正在尝试修改现有的示例应用程序,该应用程序会在用户触摸屏幕时向主 activity 添加视图。这些视图是在屏幕上浮动的位图图像。触摸屏幕上的任意位置会在该位置添加这些图像之一。
它通过为每次触摸创建一个新视图(位图图像)来实现。
它按原样工作得很好,但我正在尝试添加一个功能,它可以在没有任何用户输入的情况下以编程方式添加这些视图。
在下面的代码中,我添加了 onResume() 来尝试此功能。 (在 onCreate() 中添加相同的代码也不起作用。)
不幸的是,它没有像我希望的那样添加它们——它不是在用户启动应用程序后每 500 毫秒添加一个,而是暂停 5 秒,然后一次添加所有十个。
显然我是 android 开发人员的新手,所以我不知道从这里去哪里。
我需要做什么才能实现延迟,使其每半秒添加一个新视图?为什么它默认这样做?
谢谢!
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
对于它暂停5秒然后一次添加所有十个,那是因为你在代码中使用sleep(500)
,它会冻结主线程(UI线程)。
使用handler实现延迟动作,Ref: https://developer.android.com/reference/android/os/Handler
注:以下代码段是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 class(活动、片段、视图)中执行的所有代码都默认为 UI 线程。如果您在该线程中执行任何 Thread.sleep()
操作,整个 UI 将暂时冻结,这在某些情况下会导致 ANR 崩溃 ANR.
Handler
可以帮到你。它需要一个 Looper
引用来实例化。当您调用 post(Runnable)
或可选的 postDelayed(Runnable, long millis)
时,它将采用 Runnable
并在 UI 线程上执行它 (延迟或其他).但是,对于每次使用,您需要再次调用 post
,即在 Runnable
.
中使 post
调用递归
希望对您有所帮助!!
我正在尝试修改现有的示例应用程序,该应用程序会在用户触摸屏幕时向主 activity 添加视图。这些视图是在屏幕上浮动的位图图像。触摸屏幕上的任意位置会在该位置添加这些图像之一。
它通过为每次触摸创建一个新视图(位图图像)来实现。
它按原样工作得很好,但我正在尝试添加一个功能,它可以在没有任何用户输入的情况下以编程方式添加这些视图。
在下面的代码中,我添加了 onResume() 来尝试此功能。 (在 onCreate() 中添加相同的代码也不起作用。)
不幸的是,它没有像我希望的那样添加它们——它不是在用户启动应用程序后每 500 毫秒添加一个,而是暂停 5 秒,然后一次添加所有十个。
显然我是 android 开发人员的新手,所以我不知道从这里去哪里。
我需要做什么才能实现延迟,使其每半秒添加一个新视图?为什么它默认这样做?
谢谢!
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
对于它暂停5秒然后一次添加所有十个,那是因为你在代码中使用sleep(500)
,它会冻结主线程(UI线程)。
使用handler实现延迟动作,Ref: https://developer.android.com/reference/android/os/Handler
注:以下代码段是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 class(活动、片段、视图)中执行的所有代码都默认为 UI 线程。如果您在该线程中执行任何 Thread.sleep()
操作,整个 UI 将暂时冻结,这在某些情况下会导致 ANR 崩溃 ANR.
Handler
可以帮到你。它需要一个 Looper
引用来实例化。当您调用 post(Runnable)
或可选的 postDelayed(Runnable, long millis)
时,它将采用 Runnable
并在 UI 线程上执行它 (延迟或其他).但是,对于每次使用,您需要再次调用 post
,即在 Runnable
.
中使 post
调用递归
希望对您有所帮助!!