我有一个应用程序,允许用户在屏幕上拖动形状。我使用自定义表面视图进行拖动。每次表面视图获得OnTouchEvent时,它都会更改图形图像的位置,并调用OnDraw来更新屏幕。
因此,在发生touchevent之前,不会绘制位图图像。我试图使Costume表面视图无效,但根据调试器,OnDraw永远不会被调用。
所以现在我的屏幕是空白的,直到有人触摸屏幕
//代码
public class cPlay extends cBase implements OnClickListener {
/** Called when the activity is first created. */
// sound
private SoundPool soundPool;
private int soundID;
boolean loaded = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.play);
int w=getWindowManager().getDefaultDisplay().getWidth();
int h=getWindowManager().getDefaultDisplay().getHeight();
BallView ballView=new BallView(this,w,h);
setContentView(ballView);
// Does not update screen??????
ballView.invalidate();
....
...
....} // end of class
public class BallView extends SurfaceView implements SurfaceHolder.Callback {
private Bitmap bitmap ;
private int x=20,y=20;int width,height;
cShapeParent MyShapes;
cTarget MyTargetShapes;
Context context;
int counter=0;
// sound
private SoundPool soundPool;
private int soundID;
boolean loaded = false;
public BallView(Context InContext,int w,int h) {
super(InContext);
context=InContext;
int counter=0;
int Page=0;
width=w;
height=h;
getHolder().addCallback(this);
setFocusable(true);
MyShapes=new cShapeParent(context,w,h);
MyTargetShapes= new cTarget(context,w,h);
MyShapes.SetTargets( MyTargetShapes );
// load in bitmaps
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
bitmap =BitmapFactory.decodeResource(getResources(), R.drawable.ball_green);
canvas.drawColor(Color.BLUE);//To make background
// canvas.drawBitmap(bitmap,x-(bitmap.getWidth()/2),y-(bitmap.getHeight()/2),null);
// See if we shoyld drag it
for(int i=MyShapes.Amount-1; i>=0; i--)
{
if (MyShapes.Intersect(i,x,y))
{
// see if we can drag it
if ( MyShapes.getDragFlag(i)==false)
break;
// yes drag this image
MyShapes.SetCenter(i, x, y);
// if the target was found
// make it so we can no loner drag it
if (MyShapes.CheckTarget(i))
{
MyShapes.SetDrag(i,false);
MyShapes.SetToTarget(i);
if (++counter>2)
DisplayNextScreen();
}
break;
}
}
// Draw target shapes
// NOTE: draw these first so they are on the bottom
for(int i=0; i<MyShapes.Amount;i++)
{
int x=MyTargetShapes.GetX(i);
int y=MyTargetShapes.GetY(i);
int w=MyTargetShapes.GetW(i);
int h=MyTargetShapes.GetH(i);
Rect br=new Rect( x, y,w+x, h+y);
Bitmap m= MyTargetShapes.MyImages[i];
canvas.drawBitmap(m, null, br, null);
}
// Draw shapes that can be dragged
for(int i=0; i<MyShapes.Amount;i++)
{
int x=MyShapes.GetX(i);
int y=MyShapes.GetY(i);
int w=MyShapes.GetW(i);
int h=MyShapes.GetH(i);
Rect br=new Rect( x, y, x+w,y+h);
Bitmap m= MyShapes.MyImages[i];
canvas.drawBitmap(m, null, br, null);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
x=(int)event.getX();
y=(int)event.getY();
if(x<25)
x=25;
if(x> width)
x=width;
if(y <25)
y=25;
if(y > height)
y=height;
updateBall();
return true;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {
// TODO Auto-generated method stub
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
private void updateBall() {
Canvas canvas = null;
try {
canvas = getHolder().lockCanvas(null);
synchronized (getHolder()) {
this.onDraw(canvas);
}
}
finally {
if (canvas != null) {
getHolder().unlockCanvasAndPost(canvas);
}
}
}
void DisplayNextScreen()
{
/////////////////////////////////////
// call up dialog
final Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.custom);
dialog.setTitle("Title...");
// set the custom dialog components - text, image and button
TextView text = (TextView) dialog.findViewById(R.id.text);
text.setText("Android custom dialog example!");
ImageView image = (ImageView) dialog.findViewById(R.id.image);
image.setImageResource(R.drawable.ic_launcher);
Button dialogButton = (Button) dialog.findViewById(R.id.dialogButtonOK);
// if button is clicked, close the custom dialog
dialogButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
MyTargetShapes.SetUp(1);
MyShapes.SetUp(1);
MyShapes.SetTargets( MyTargetShapes );
counter =0;
}
});
dialog.show();
} // end methed
void StartSound(int soundID )
{
AudioManager audioManager = (AudioManager) context.getSystemService("audio");
float actualVolume = (float) audioManager
.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume = (float) audioManager
.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float volume = actualVolume / maxVolume;
// Is the sound loaded already?
soundPool.play(soundID, volume, volume, 1, 0, 1f);
// Log.e("Test", "Playe");
}
} // end class
答案 0 :(得分:0)
您可以尝试将invalidate();
调用添加到BallView(Context InContext,int w,int h)
构造函数的末尾,而不是从其他类调用它。
答案 1 :(得分:0)
我在我的应用中遇到了类似的问题。 invalidate()不会重绘形状。所以我找到的解决方案是将形状提取到显示UI上的组件的类中,然后通过从UI类访问它来从主活动更新组件。
SurfaceView类:
@覆盖 public void onDraw(Canvas canvas){
Log.d("check","="+color);
Log.e("check","after set:"+buf);
Log.i("new view ", " on draw ");
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(5);
paint.setColor(Color.WHITE);
path = new Path();
path.moveTo(0, 30); /*For Borders*/
path.lineTo(30, 0);
path.lineTo(-30, 0);
path.close();
path.offset(20, -5);
canvas.drawPath(path, paint);
UI类:
public void show(查看锚点,int颜色){ 预演();
int xPos, yPos, arrowPos;
mDidAction = false;
}
showArrow(((onTop) ? R.id.arrow_down : R.id.arrow_up), arrowPos,color);
setAnimationStyle(screenWidth, anchorRect.centerX(), onTop);
mWindow.showAtLocation(anchor, Gravity.NO_GRAVITY, xPos, yPos);
}
R.id.arrow_down是使用NewView类绘制的形状。
在事件的主要活动中调用这样的函数:
btn1 = (Button) this.findViewById(R.id.btn1);
btn1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.d("In","View");
quickAction.show(v,Color.BLUE);
}
});
这将根据需要更新视图。 希望这有助于