2012-01-05 2 views
0

У меня есть вид сверху, и всякий раз, когда я касаюсь экрана, изображение появляется в том месте, которое я касаюсь. Это здорово, но я не могу понять, как разместить фон на SurfaceView. Я попытался использовать OnDraw, чтобы нарисовать фон сразу (без необходимости касаться его), и это работает только некоторое время. Сила сильно закрывается.Android: Фон на SurfaceView?

Кто-нибудь захочет посмотреть мой код и посмотреть, можно ли получить фоновое изображение на поверхности? Заранее спасибо.

класс MyView extends SurfaceView реализует SurfaceHolder.Callback { private Thready _thread; private ArrayList _graphicsz = new ArrayList(); private GraphicObject _currentGraphic = null;

public MyView(Context context) { 
    super(context); 
    getHolder().addCallback(this); 
    _thread = new Thready(getHolder(), this); 
    setFocusable(true); 
} 

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    synchronized (_thread.getSurfaceHolder()) { 
     GraphicObject graphic = null; 
     if (event.getAction() == MotionEvent.ACTION_DOWN) { 
      graphic = new GraphicObject(BitmapFactory.decodeResource(getResources(), R.drawable.cat1small)); 
      graphic.getCoordinates().setX((int) event.getX() - graphic.getGraphic().getWidth()/2); 
      graphic.getCoordinates().setY((int) event.getY() - graphic.getGraphic().getHeight()/2); 
      _currentGraphic = graphic; 
     } else if (event.getAction() == MotionEvent.ACTION_MOVE) { 
      _currentGraphic.getCoordinates().setX((int) event.getX() - _currentGraphic.getGraphic().getWidth()/2); 
      _currentGraphic.getCoordinates().setY((int) event.getY() - _currentGraphic.getGraphic().getHeight()/2); 
     } else if (event.getAction() == MotionEvent.ACTION_UP) { 
      _graphicsz.add(_currentGraphic); 
      _currentGraphic = null; 
     } 

     return true; 
    } 
} 

@Override 
public void onDraw(Canvas canvas) { 


    canvas.drawColor(Color.BLACK); 
    Bitmap bitmap1; 
    GraphicObject.Coordinates coords1; 
    for (GraphicObject graphic : _graphicsz) { 
     bitmap1 = graphic.getGraphic(); 
     coords1 = graphic.getCoordinates(); 
     canvas.drawBitmap(bitmap1, coords1.getX(), coords1.getY(), null); 
    } 
    // draw current graphic at last... 
    if (_currentGraphic != null) { 
     bitmap1 = _currentGraphic.getGraphic(); 
     coords1 = _currentGraphic.getCoordinates(); 
     canvas.drawBitmap(bitmap1, coords1.getX(), coords1.getY(), null); 
    } 
} 

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
    // TODO Auto-generated method stub 
} 

public void surfaceCreated(SurfaceHolder holder) { 
    _thread.setRunning(true); 
    _thread.start(); 
} 




public void surfaceDestroyed(SurfaceHolder holder) { 
    // simply copied from sample application LunarLander: 
    // we have to tell thread to shut down & wait for it to finish, or else 
    // it might touch the Surface after we return and explode 
    boolean retry = true; 
    _thread.setRunning(false); 
    while (retry) { 
     try { 
      _thread.join(); 
      retry = false; 
     } catch (InterruptedException e) { 
      // we will try it again and again... 
     } 
    } 
} 

}

класс нитевидный расширяет тему { частное SurfaceHolder _surfaceHolder; частный MyView _panel; private boolean _run = false;

public Thready(SurfaceHolder surfaceHolder, MyView panel) { 
    _surfaceHolder = surfaceHolder; 
    _panel = panel; 
} 

public void setRunning(boolean run) { 
    _run = run; 
} 

public SurfaceHolder getSurfaceHolder() { 
    return _surfaceHolder; 
} 

@Override 
public void run() { 
    Canvas c; 
    while (_run) { 
     c = null; 
     try { 
      c = _surfaceHolder.lockCanvas(null); 
      synchronized (_surfaceHolder) { 
       _panel.onDraw(c); 
      } 
     } finally { 
      // do this in a finally so that if an exception is thrown 
      // during the above, we don't leave the Surface in an 
      // inconsistent state 
      if (c != null) { 
       _surfaceHolder.unlockCanvasAndPost(c); 
      } 
     } 
    } 
} 

}

класс GraphicObject { /** * Содержит координаты графического объекта. */ public class Координаты { private int _x = 100; private int _y = 0;

public int getX() { 
     return _x + _bitmap.getWidth()/2; 
    } 

    public void setX(int value) { 
     _x = value - _bitmap.getWidth()/2; 
    } 

    public int getY() { 
     return _y + _bitmap.getHeight()/2; 
    } 

    public void setY(int value) { 
     _y = value - _bitmap.getHeight()/2; 
    } 

    public String toString() { 
     return "Coordinates: (" + _x + "/" + _y + ")"; 
    } 
} 

private Bitmap _bitmap; 
private Coordinates _coordinates; 

public GraphicObject(Bitmap bitmap) { 
    _bitmap = bitmap; 
    _coordinates = new Coordinates(); 
} 

public Bitmap getGraphic() { 
    return _bitmap; 
} 

public Coordinates getCoordinates() { 
    return _coordinates; 
} 

}

ответ

0

Ну, что меня поражает первых от всех (и что может быть причиной многих проблем) заключается в следующем:

вы создаете новое растровое изображение слишком часто

Каждый раз, когда вы получаете событие касания, вы загружаете его в растровые изображения ... и вы можете получить от 80 до 100 touchevents ev во второй!

Итак, для начала определите глобальные растровые изображения (private Bitmap bmp1; и т. Д.), Загрузите их где-нибудь еще и ТОГДА используйте их в своем событии касания.

Также удалите загрузку/создание bmp с помощью onDraw и переместите его в другое место.

После того, как вы это сделали, посмотрите, что произойдет; у вас может быть больше проблем (REALY быстрая проверка вашего кода казалась прекрасной), но не создание и загрузка растровых изображений 80 раз в секунду определенно поможет :)