2017-01-12 3 views
0

Я использую Picasso для загрузки изображения в моем классе Android View. В частности, я загружаю изображение в растровое изображение. В onCreate() я использую:Ждите ответа на вызов Picasso до invalidate()

Picasso.with(getContext()).load(R.drawable.img).into(target); 

В TargetonBitmapLoaded метод я назначить загруженный Bitmap к MyBitmap. И затем в методе onDraw я использую canvas.drawBitmap(myBitmap,....), чтобы нарисовать фон.

Но проблема в том, что onDraw() метод outpaces Target Callback, и я получаю всю свою графику сначала без фона, и фон добавляется только через некоторое время.

Я добавил invalidate()Target в onBitmapLoaded() сделать это, как только он был загружен, но до сих пор onDraw() метод идет раньше.

Как я могу отложить метод onDraw(), пока не получу Target callback? Я не знаю, как решить проблему, потому что, насколько я понял, оба целевого обратного вызова и onDraw() вызываются в основном потоке. Не могли бы вы порекомендовать что-нибудь?

Вот мой пример кода: (Это простой Toe игра Tic Tac Логика игра была удалена, чтобы не сделать код образца тяжелым, но в случае необходимости я могу отправить все это с удовольствием -..))

` общественного класса GameViewStatic расширяет View реализует SoundPool.OnLoadCompleteListener {

public class GameThread extends Thread { 

    @Override 
    public void run() { 

     //code for making players move 
     postInvalidate(); 
     try { 
      Thread.sleep(500); 
     } catch (InterruptedException e) { 
     } 
     //code for making comp move 
     postInvalidate(); 

    } 

} 

private Rect[][] rects = new Rect[3][3]; 
private static final int size = 3; 
private Paint mPaint; 
private Paint mCirclePaint; 
private Paint mCrossPaint; 
public static final int WIDTH = 960; 
public static final int HEIGHT = 1280; 
float touchX = 0; 
float touchY = 0; 
private Bitmap bitmap; 
public SimplePlayGround simplePlayGround; 
private Bot bot; 
private boolean flag; 
private Thread gameThread; 
private boolean firstThread = false; 
private int[][] winningFields; 
private SoundPool mSoundPool; 
private int soundID; 
private int streamId; 
final int MAX_STREAMS = 5; 
final List<Target> targets = new ArrayList<>(); 
public static int playerWin; 


public GameViewStatic(Context context) { 
    super(context); 
    mSoundPool = new SoundPool(MAX_STREAMS, AudioManager.STREAM_MUSIC, 0); 
    mSoundPool.setOnLoadCompleteListener(this); 
    soundID = mSoundPool.load(context, R.raw.win, 1); 
    init(); 

} 


public GameViewStatic(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    mSoundPool = new SoundPool(MAX_STREAMS, AudioManager.STREAM_MUSIC, 0); 
    mSoundPool.setOnLoadCompleteListener(this); 
    soundID = mSoundPool.load(context, R.raw.win, 1); 
    init(); 
} 

public GameViewStatic(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
    mSoundPool = new SoundPool(MAX_STREAMS, AudioManager.STREAM_MUSIC, 0); 
    mSoundPool.setOnLoadCompleteListener(this); 
    soundID = mSoundPool.load(context, R.raw.win, 1); 
    init(); 
} 

public void init() { 

    mPaint = new Paint(); 
    mPaint.setColor(Color.BLACK); 
    mPaint.setStrokeWidth(10); 
    mCirclePaint = new Paint(); 
    mCirclePaint.setColor(Color.RED); 
    mCirclePaint.setStrokeWidth(10); 
    mCrossPaint = new Paint(); 
    mCrossPaint.setColor(Color.BLUE); 
    mCrossPaint.setStrokeWidth(10); 
    mCrossPaint.setStyle(Paint.Style.STROKE); 
    mPaint.setStyle(Paint.Style.STROKE); 
    mCirclePaint.setStyle(Paint.Style.STROKE); 
    simplePlayGround = new SimplePlayGround(); 
    simplePlayGround.start(); 
    bot = new Bot(); 
    firstThread = true; 
    Target mTarget = new Target() { 

     @Override 
     public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { 
      GameViewStatic.this.bitmap = bitmap; 
      invalidate(); 
      targets.remove(this); 
     } 

     @Override 
     public void onBitmapFailed(Drawable errorDrawable) { 
      targets.remove(this); 

     } 

     @Override 
     public void onPrepareLoad(Drawable placeHolderDrawable) { 

     } 


    }; 

    targets.add(mTarget); 
    Picasso.with(getContext()).load(R.drawable.kletka3). 
      memoryPolicy(MemoryPolicy.NO_STORE, MemoryPolicy.NO_CACHE).into(targets.get(0)); 

} 


@Override 
public void onLoadComplete(SoundPool soundPool, int i, int i1) { 

} 


@Override 
protected void onDraw(Canvas canvas) { 
    if (bitmap != null) { 

     final float scaleFactorX; 
     final float scaleFactorY; 

     if (getWidth() > WIDTH || getHeight() > HEIGHT) { 
      scaleFactorX = (float) getWidth()/WIDTH; 
      scaleFactorY = (float) getHeight()/HEIGHT; 
     } else { 
      scaleFactorX = 1; 
      scaleFactorY = 1; 
     } 
     final int savedState = canvas.save(); 
     canvas.scale(scaleFactorX, scaleFactorY); 

     canvas.drawBitmap(bitmap, 0, 0, null); 
     canvas.restoreToCount(savedState); 

     // ... drawing game field 
    } 
} 


public boolean onTouchEvent(MotionEvent event) { 
    if (firstThread || !gameThread.isAlive()) { 
     if (event.getAction() == MotionEvent.ACTION_DOWN) { 
      flag = false; 
      touchX = event.getX(); 
      touchY = event.getY(); 
      gameThread = new GameThread(); 
      gameThread.setDaemon(true); 
      gameThread.start(); 
      firstThread = false; 
     } 

    } 
    return true; 
} 

static class SavedState extends BaseSavedState { 
    String savedPlayground; 
    String savedBot; 
    int playerWin; 
    int compWin; 


    SavedState(Parcelable superState) { 
     super(superState); 
    } 

    private SavedState(Parcel in) { 
     super(in); 
     savedPlayground = in.readString(); 
     savedBot = in.readString(); 
     playerWin = in.readInt(); 
     compWin = in.readInt(); 
    } 

    @Override 
    public void writeToParcel(Parcel out, int flags) { 
     super.writeToParcel(out, flags); 
     out.writeString(savedPlayground); 
     out.writeString(savedBot); 
     out.writeInt(playerWin); 
     out.writeInt(compWin); 
    } 

    public static final Parcelable.Creator<SavedState> CREATOR = 
      new Parcelable.Creator<SavedState>() { 
       public SavedState createFromParcel(Parcel in) { 
        return new SavedState(in); 
       } 

       public SavedState[] newArray(int size) { 
        return new SavedState[size]; 
       } 
      }; 
} 

@Override 
public Parcelable onSaveInstanceState() { 
    Parcelable superState = super.onSaveInstanceState(); 
    SavedState ss = new SavedState(superState); 
    ss.savedPlayground = new Gson().toJson(simplePlayGround); 
    ss.savedBot = new Gson().toJson(bot); 
    ss.playerWin = this.playerWin; 
    return ss; 
} 

@Override 
public void onRestoreInstanceState(Parcelable state) { 
    if (!(state instanceof SavedState)) { 
     super.onRestoreInstanceState(state); 
     return; 
    } 

    SavedState ss = (SavedState) state; 
    super.onRestoreInstanceState(ss.getSuperState()); 
    simplePlayGround = new Gson().fromJson(ss.savedPlayground, SimplePlayGround.class); 
    bot = new Gson().fromJson(ss.savedBot, Bot.class); 
    this.playerWin = ss.playerWin; 


} 

} '

+0

Можете ли вы опубликовать более полный образец кода? –

+0

Несомненно. Я постараюсь сделать это как можно короче – Vitalii

ответ

0

Давайте предположим, что ваша точка зрения распространяется View, вы можете предотвратить View втягивания, не вызывая super.onDraw(canvas) в том же переопределен метод:

public class TargetView extends View implements Target{ 

     private boolean canDraw = false; 
     @Override 
     protected void onDraw(Canvas canvas) { 
      if(canDraw) 
      super.onDraw(canvas); 

     } 

     @Override 
     public void onBitmapLoaded(android.graphics.Bitmap bitmap, Picasso.LoadedFrom from){ 
      canDraw = true; 
      invalidate(); 
      setBackground(....); 
     } 
    } 

Если вы используете Target обратный вызов, вы, вероятно, нужно добавить сеттера для canDraw.

+0

На самом деле я не называю super.onDraw (canvas), а мой класс View не реализует Target, Target - это внутренний анонимный класс, но это условие с canDraw может помочь. Тогда, возможно, я мог бы просто использовать if (myBitmap! = Null) в методе onDraw, чтобы не добавлять новую переменную? Потому что, вероятно, тогда мне нужно будет установить значение false при восстановлении состояния. – Vitalii

+0

Да, 'myBitmap! = Null' может быть разумной заменой. –

+0

Это оказалось таким простым решением. Я не знаю почему, но я думал о том, как отложить метод 'onDraw()' вместо того, чтобы добавлять в него новое условие. В любом случае, спасибо за помощь и за такой быстрый ответ! – Vitalii

Смежные вопросы