如何在安卓画布的onDraw()中添加延迟?



我正在做一个项目。它在安卓画布上画同心圆。当用户拖动屏幕时,所有圆圈都会相应移动。这是我到目前为止的代码。

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:background="@android:color/white">
<RelativeLayout
android:id="@+id/scrollableSpace"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true">
<project.myProject.DrawOrbit
android:id="@+id/orbitsRegion"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true" />

</RelativeLayout>
</RelativeLayout>

主要活动.java

public class MainActivity extends AppCompatActivity implements View.OnTouchListener
{
PointF center;
center.x=500;center.y=500;
float radius[]={100,200,300,400,500};
DrawOrbit orbit;
int startX=0,startY=0,currentX=0,currentY=0;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout layout=(RelativeLayout)findViewById(R.id.scrollableSpace);
orbit.draw(center,radius);
layout.setOnTouchListener(this);
}   

@Override
public boolean onTouch(View v, MotionEvent motionEvent)
{
final int action= motionEvent.getAction();
switch(action & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
{              
startX=(int)motionEvent.getRawX();
startY=(int)motionEvent.getRawY();             
break;
}
case MotionEvent.ACTION_MOVE:
{
currentX=(int)motionEvent.getRawX();
currentY=(int)motionEvent.getRawY();               
float diffX=currentX-startX;
float diffY=currentY-startY;
startX=currentX;
startY=currentY;
center.x+=diffX;
center.y+=diffY;
orbit.draw(center,radius);
break;
}          
}
return true;
}
}

画轨道.java

public class DrawOrbit extends View
{
PointF center;
float radius[];
public DrawOrbit(Context context) {
super(context);
}
public DrawOrbit(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public DrawOrbit(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
paint.setColor(Color.BLACK);
paint.setStrokeWidth(2);
paint.setStyle(Paint.Style.STROKE);
int len=radius.length;
for(int a=0;a<len;a++)
{
canvas.drawCircle(center.x,center.y,radius[a],paint);
}
}   
public void draw(PointF center, float radius[])
{
this.center=center;
this.radius=radius;
invalidate();        
requestLayout();
}
}

我想做的是圆圈应该一个接一个地出现。首先是最内层的圆圈,然后在一段时间延迟后下一个圆圈,然后是下一个,依此类推。拖动屏幕时应该会看到相同的效果。我怎样才能做到这一点?任何帮助将不胜感激。

你要找的是超时。我建议创建一个新线程来绘制所有内容,并从绘制第一个圆开始,让方法如下所示:

public void drawCircle() {
//Draw logic
TimeUnit.SECONDS.sleep(3);
drawNextCircle();
}
//Assuming on java 1.8+
Thread thread = new Thread() => {
drawCircle();
}

这将做的是让线程休眠 3 秒钟,然后在时间段结束后继续正常运行。您也可以将其更改为其他时间度量,例如TimeUnit.MILLISECONDSTimeUnit.MINUTES

编辑:您可能不希望在主线程中执行此操作,因为无论您将线程置于超时状态,它都会阻止整个应用程序工作,因此将其放在单独的线程中几乎必须使其正常工作。

编辑 2:与上面的代码相比,添加一个单独的 util 方法到超时然后通过反射调用另一个方法更有意义,但需要相同的代码。

想出了我自己问题的答案。我不得不使用一个处理程序,将延迟与 for 循环变量相乘,然后做 1 然后是 2,依此类推。圆圈以获得所需的效果。这是代码。

主要活动.java

public class MainActivity extends AppCompatActivity implements View.OnTouchListener
{
PointF center;
center.x=500;center.y=500;
float radius[]={100,200,300,400,500};
DrawOrbit orbit;
int startX=0,startY=0,currentX=0,currentY=0;
Handler handler1 = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout layout=(RelativeLayout)findViewById(R.id.scrollableSpace);
for (int a = 0; a<radius.length ;a++)
{
final int index=a;
handler1.postDelayed(new Runnable() {
@Override
public void run() {
orbit.draw(center,radius,index);
}
}, 300 * a);
}
layout.setOnTouchListener(this);
}   

@Override
public boolean onTouch(View v, MotionEvent motionEvent)
{
final int action= motionEvent.getAction();
switch(action & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
{              
startX=(int)motionEvent.getRawX();
startY=(int)motionEvent.getRawY();             
break;
}
case MotionEvent.ACTION_MOVE:
{
currentX=(int)motionEvent.getRawX();
currentY=(int)motionEvent.getRawY();               
float diffX=currentX-startX;
float diffY=currentY-startY;
startX=currentX;
startY=currentY;
center.x+=diffX;
center.y+=diffY;
break;
} 
case MotionEvent.ACTION_UP:
{
for (int a = 0; a<radius.length ;a++)
{
final int index=a;
handler1.postDelayed(new Runnable() {
@Override
public void run() {
orbit.draw(center,radius,index);
}
}, 300 * a);
}
break;
}
}
return true;
}
}

画轨道.java

public class DrawOrbit extends View
{
PointF center;
float radius[];
int index;
public DrawOrbit(Context context) {
super(context);
}
public DrawOrbit(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public DrawOrbit(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
paint.setColor(Color.BLACK);
paint.setStrokeWidth(2);
paint.setStyle(Paint.Style.STROKE);
int len=radius.length;
for(int a=0;a<index;a++)
{
canvas.drawCircle(center.x,center.y,radius[a],paint);
}
}   
public void draw(PointF center, float radius[],int index)
{
this.center=center;
this.radius=radius;
this.index=index;
invalidate();        
requestLayout();
}
}

最新更新