2017-01-12 2 views
0

私はAndroidビュークラスで画像を読み込むためにピカソを使用しています。特に私は画像をビットマップにロードしています。 onCreate()で 私が使用:Targetinvalidate()の前にピカソターゲットコールバックを待つ

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

私はmyBitmapにロードされたビットマップを割り当てるonBitmapLoaded方法。 そして、onDrawメソッドでは、canvas.drawBitmap(myBitmap,....)を使って背景を描画します。

しかし、問題は、onDraw()メソッドがTarget Callbackを上回り、最初にすべての自分のグラフィックをバックグラウンドなしで取得し、バックグラウンドはしばらくしてから追加されるということです。

私はすぐにそれがロードされていますが、それでもonDraw()方法は、先に行くと、それを描画するTargetonBitmapLoaded()invalidate()を追加しました。

コールバックを取得するまで、onDraw()メソッドを遅延させるにはどうすればよいですか?私は目標のコールバックとonDraw()の両方がメインスレッドで呼び出されているので、問題を解決する方法はわかりません。何かお勧めしますか?ここで

は、私のコードのサンプルです: (それはゲームロジックは、コードサンプルの重いをしないように削除されたシンプルなチックタックトーゲームです。しかし、必要であれば、私は喜んでそれをすべてを投稿することができます - 。。))

` パブリッククラスGameViewStaticビューが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

のは、あなたのビューがを拡張すると仮定しましょう実装拡張します10、あなたはViewが同じオーバーライドされた方法でsuper.onDraw(canvas)を呼び出していないことで描画されるのを防ぐことができます:あなたはTargetコールバックを使用している場合

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(....); 
     } 
    } 

、あなたはおそらくcanDraw用セッターを追加する必要があると思います。

+0

実際に私はsuper.onDraw(キャンバス)を呼び出さず、ViewクラスはTargetを実装していませんが、Targetは内部匿名クラスですが、canDrawを使用するとこの条件が役立ちます。次に、新しい変数を追加しないonDrawメソッドでif(myBitmap!= null)を使うだけかもしれません。おそらく私は状態を復元するときにそれをfalseに設定する必要があるからです。 – Vitalii

+0

はい、 'myBitmap!= null'は妥当な代替手段です。 –

+0

これは簡単な解決策であることが判明しました。私は理由を知らないが、新しい条件を追加するのではなく、 'onDraw()'メソッドを遅らせる方法を考えていた。とにかく、助けて、そのような速い返信のおかげで! – Vitalii

関連する問題