2016-04-01 10 views
0

Ana Etkinlikte barındırılan özel bir Çizim Görünümüm var mı? Şu anda cihazın yönünü değiştirdiğinde çizim durumunu kaydetmeye çalışıyorum. Yönlendirme değişikliklerinden NullPointerException AFTER alıyorum. Böylece sorun olmadan çizebilirim ama cihazı döndürdüğümde çöküyor. Lütfen bana bir ipucu ver, çok sinirliyim. İşte benim çizimim. Bu çizgide NPE alınıyor: drawCanvas.drawPath(drawPath, drawPaint);Activity imha edilecek ve ayrıca görünümleri, Bir Bundle nesnede önemli verileri kaydetmek ve tekrar geri onSaveInstanceState(Bundle outState) yöntemi geçersiz gerekir cihaz rotasyon ile dönmeYönlendirme değiştiğinde parmak çizimi görünümünü nasıl kaydederim?

public class DrawingView extends View { 
    private static final String EXTRA_EVENT_LIST = "event_list"; 
    private static final String EXTRA_STATE = "instance_state"; 
    private ArrayList<MotionEvent> eventList = new ArrayList<MotionEvent>(100); 
    private ArrayList<MotionEvent> myObject = new ArrayList<MotionEvent>(100); 
    //drawing path 
    private Path drawPath; 
    //drawing and canvas paint 
    private Paint drawPaint, canvasPaint; 
    //initial color 
    private int paintColor = 0xFF660000, paintAlpha = 255; 
    //canvas 
    private Canvas drawCanvas; 

    //canvas bitmap 
    private Bitmap canvasBitmap; 
    //brush sizes 
    private float brushSize, lastBrushSize; 
    //erase flag 
    private boolean erase=false; 

    public DrawingView(Context context, AttributeSet attrs){ 
     super(context, attrs); 
     setupDrawing(); 
    } 

    //setup drawing 
    private void setupDrawing(){ 
     //prepare for drawing and setup paint stroke properties 
     brushSize = getResources().getInteger(R.integer.medium_size); 
     lastBrushSize = brushSize; 
     drawPath = new Path(); 
     drawPaint = new Paint(); 
     drawPaint.setColor(paintColor); 
     drawPaint.setAntiAlias(true); 
     drawPaint.setStrokeWidth(brushSize); 
     drawPaint.setStyle(Paint.Style.STROKE); 
     drawPaint.setStrokeJoin(Paint.Join.ROUND); 
     drawPaint.setStrokeCap(Paint.Cap.ROUND); 
     canvasPaint = new Paint(Paint.DITHER_FLAG); 
    } 


    //size assigned to view 
    @Override 
    protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
     super.onSizeChanged(w, h, oldw, oldh); 
     canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); 
     drawCanvas = new Canvas(canvasBitmap); 
    } 

    //draw the view - will be called after touch event 
    @Override 
    protected void onDraw(Canvas canvas) { 
     canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint); 
     canvas.drawPath(drawPath, drawPaint); 
    } 

    //register user touches as drawing action 
    @Override 
    public boolean onTouchEvent(MotionEvent event) { 

     getParent().requestDisallowInterceptTouchEvent(true); 
     //respond to down, move and up events 
     switch (event.getAction()) { 

      case MotionEvent.ACTION_DOWN: 
      case MotionEvent.ACTION_MOVE: 
      case MotionEvent.ACTION_UP: 
       performTouchEvent(event); 

     } 
     //redraw 
     invalidate(); 
     eventList.add(MotionEvent.obtain(event)); 
     return true; 

    } 

    private void performTouchEvent(MotionEvent event) { 
     float touchX = event.getX(); 
     float touchY = event.getY(); 
     switch (event.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
       drawPath.moveTo(touchX, touchY); 
       break; 
      case MotionEvent.ACTION_MOVE: 
       drawPath.lineTo(touchX, touchY); 
       break; 
      case MotionEvent.ACTION_UP: 
       drawPath.lineTo(touchX, touchY); 
       drawCanvas.drawPath(drawPath, drawPaint); 
       drawPath.reset(); 
       break; 
     } 
     invalidate(); 
     eventList.add(MotionEvent.obtain(event)); 
    } 


    //update color 
    public void setColor(String newColor){ 
     invalidate(); 
     //check whether color value or pattern name 
     if(newColor.startsWith("#")){ 
      paintColor = Color.parseColor(newColor); 
      drawPaint.setColor(paintColor); 
      drawPaint.setShader(null); 
     } 
     else{ 
      //pattern 
      int patternID = getResources().getIdentifier(
        newColor, "drawable", "com.androbro.navigationdrawerproject"); 
      //decode 
      Bitmap patternBMP = BitmapFactory.decodeResource(getResources(), patternID); 
      //create shader 
      BitmapShader patternBMPshader = new BitmapShader(patternBMP, 
        Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); 
      //color and shader 
      drawPaint.setColor(0xFFFFFFFF); 
      drawPaint.setShader(patternBMPshader); 
     } 
    } 

    //set brush size 
    public void setBrushSize(float newSize){ 
     float pixelAmount = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 
       newSize, getResources().getDisplayMetrics()); 
     brushSize=pixelAmount; 
     drawPaint.setStrokeWidth(brushSize); 
    } 

    //get and set last brush size 
    public void setLastBrushSize(float lastSize){ 
     lastBrushSize=lastSize; 
    } 
    public float getLastBrushSize(){ 
     return lastBrushSize; 
    } 

    //set erase true or false 
    public void setErase(boolean isErase){ 
     erase=isErase; 
     if(erase) { 
      drawPaint.setColor(Color.WHITE);//set the color to white 
     } 
     else drawPaint.setColor(paintColor); //if erase is set to false, it will use the previous color. 
    } 

    //start new drawing 
    public void startNew(){ 
     drawCanvas.drawColor(0, PorterDuff.Mode.CLEAR); 
     invalidate(); 
    } 

    //return current alpha 
    public int getPaintAlpha(){ 
     return Math.round((float)paintAlpha/255*100); 
    } 

    //set alpha 
    public void setPaintAlpha(int newAlpha){ 
     paintAlpha=Math.round((float)newAlpha/100*255); 
     drawPaint.setColor(paintColor); 
     drawPaint.setAlpha(paintAlpha); 
    } 

    @Override 
    public Parcelable onSaveInstanceState() 
    { 
     Log.i("Saving", "drawing"); 
     Bundle bundle = new Bundle(); 
     bundle.putParcelable(EXTRA_STATE, super.onSaveInstanceState()); 
     bundle.putParcelableArrayList(EXTRA_EVENT_LIST, eventList); 

     return bundle; 
    } 

    @Override 
    public void onRestoreInstanceState(Parcelable state) 
    { 
     Log.i("OnRestore", "state"); 

     if (state instanceof Bundle) 
     { 
      Bundle bundle = (Bundle) state; 
      super.onRestoreInstanceState(bundle.getParcelable(EXTRA_STATE)); 
      eventList = bundle.getParcelableArrayList(EXTRA_EVENT_LIST); 
      if (eventList != null) { 
       Log.i("EventList", "is not null"); 
       myObject = new ArrayList<>(eventList); 
      } else{ 
       return; 
      } 

      for (MotionEvent event : myObject) { 
       Log.i("Event", "" + event); 
       performTouchEvent(event); 
      } 
      return; 
     } 
     super.onRestoreInstanceState(state); 
    } 
} 

cevap

0

sonra performTouchEvent() çağrılırken , Sadece bu nesne ParcelableInterface uygulamak gerektiğini unutmayın, Aslında sizin durumda Bitmap nesnesi Parcelable ama ekran boyutu değişikliği nedeniyle bir Bundle geçirirseniz, görünüm boyutu farklı olacak ve farklı boyutu ile bir Bitmap gerekir. bunu bir Bundle ve rotasyon sonra yeniden çizme Path kullanarak geçirebilmesi için

başka yolu da çizim Path genişletmek ve Parcelable uygulamaktır. durumunda

Kontrol bu Parcelable hakkında daha fazla bilgi edinmek istiyorum:

How can I make my custom objects Parcelable?

+0

Teşekkür! Yolu genişletmek için bakacak, makul bir seçim gibi görünüyor. – androider

+0

Benim için iyi şanslar –

İlgili konular