DrawerView очищается, когда я поворачиваю телефон - PullRequest
0 голосов
/ 16 января 2019

Когда я поворачиваю телефон, мой DrawerView очищается. Когда я поворачиваю свой телефон в моем классе, DrawerView работает onSizeChanged, и после этого мой drawView пуст. Я добавил android:configChanges="keyboardHidden|orientation|screenSize" в свой AndroidManifest, но он не работает.

Это мой ящик:

public class DrawerView extends View {
    private Bitmap mBitmap;
    private Canvas mCanvas;
    private Path mPath;
    private Paint mBitmapPaint;
    private float mX, mY, sX, sY;
    private boolean isSigned = false;

    public DrawerView(Context c) {
        super(c);
        mPath = new Path();
        mBitmapPaint = new Paint(Paint.DITHER_FLAG);
        mBitmapPaint.setColor(Color.WHITE);
    }

    public DrawerView(Context c, Bitmap bitmap) {
        super(c);
        mPath = new Path();
        mBitmapPaint = new Paint(Paint.DITHER_FLAG);
        mBitmapPaint.setColor(Color.WHITE);
        mBitmap = bitmap;
    }

    public void setIsSigned(boolean isSigned) {
        this.isSigned = isSigned;
    }

    public boolean isSigned() {
        return isSigned;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);
        mCanvas = new Canvas(mBitmap);
        mCanvas.drawColor(Color.WHITE);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
        canvas.drawPath(mPath, mPaint);
    }

    public void clear() {
        setDrawingCacheEnabled(true);
        mCanvas.drawColor(Color.WHITE);
        invalidate();
    }

    private void drawDot(float x, float y) {
        mCanvas.drawCircle(x, y, 2.0f, mPaint);
    }

    private void touch_start(float x, float y) {
        mPath.reset();
        mPath.moveTo(x, y);
        mX = x;
        mY = y;
        sX = x;
        sY = y;
    }

    private void touch_move(float x, float y) {
        mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
        mX = x;
        mY = y;
        mCanvas.drawPath(mPath, mPaint);
    }

    private void touch_up() {
        mPath.lineTo(mX, mY);
        mCanvas.drawPath(mPath, mPaint);
        mPath.reset();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        this.isSigned = true;
        float x = event.getX();
        float y = event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                touch_start(x, y);
                break;
            case MotionEvent.ACTION_MOVE:
                touch_move(x, y);
                break;
            case MotionEvent.ACTION_UP:
                if (x == sX && y == sY) {
                    drawDot(x, y);
                }
                touch_up();
                break;
        }
        invalidate();
        return true;
    }
}

Когда я поворачиваю телефон, это происходит, и

  @Override
  protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);
        mCanvas = new Canvas(mBitmap);
        mCanvas.drawColor(Color.WHITE);   
  }

и мой ящик очищается

это весь мой класс:

открытый класс SignatureActivity расширяет Activity, реализует Handler.Callback {

File mCurrentPhotoPath;
private FrameLayout drawerBox;
private Button save, clear;
private DrawerView mv;
private Paint mPaint;
private boolean existingSign;
private Intent intent;
private String signature;
private File imagesDir;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.drawer_act_lay);
    existingSign = getIntent().hasExtra(getPackageName() + "_signaturePath");
    initializeView();
    setListeners();
    Intent iin = getIntent();
    Bundle b = iin.getExtras();
    if (b != null) {
        signature = (String) b.get("signaturePath");
    }

}

@Override
protected void onResume() {
    super.onResume();
}

@Override
protected void onDestroy() {
    super.onDestroy();
}

@Override
public void onBackPressed() {
    setResult(RESULT_CANCELED);
    finish();
}

private void initializeView() {
    drawerBox = this.findViewById(R.id.drawerContainer);
    save = findViewById(R.id.saveBtn);
    clear = findViewById(R.id.clearBtn);
    if (existingSign) {
        mv = new DrawerView(this, BitmapFactory.decodeFile(getIntent()
                .getStringExtra(getPackageName() + "_signaturePath")));
    } else {
        mv = new DrawerView(this);
    }
    mv.setDrawingCacheEnabled(false);
    mv.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT));
    drawerBox.addView(mv);
    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setDither(true);
    mPaint.setColor(Color.BLACK);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(3);
    mv.setDrawingCacheEnabled(true);
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {

    mCurrentPhotoPath = (File) savedInstanceState.getSerializable(MY_CURRENT_PHOTO_PATH_KEY);
    super.onRestoreInstanceState(savedInstanceState);
}

@Override
protected void onSaveInstanceState(Bundle outState) {

    outState.putSerializable(MY_CURRENT_PHOTO_PATH_KEY, mCurrentPhotoPath);
    super.onSaveInstanceState(outState);
}

private void setListeners() {
    save.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {

            if (!mv.isSigned()) {
                Toast.makeText(SignatureActivity.this, R.string.empty_sign, Toast.LENGTH_SHORT).show();
            } else {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss", Locale.US);
                String currentDateandTime = sdf.format(new Date());
                String name = "sign_" + currentDateandTime;
                Bitmap bitmap = mv.getDrawingCache();
                File imagesFolder = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
                imagesFolder.mkdirs();
                File file = new File(imagesFolder, name + ".jpg");
                try {
                    if (!file.exists()) {
                        file.createNewFile();
                    }
                    FileOutputStream ostream = new FileOutputStream(file);
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 80, ostream);
                    ostream.close();
                    mv.invalidate();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    mv.setDrawingCacheEnabled(true);
                }
                Intent data = new Intent();
                data.putExtra(getPackageName() + "_signaturePath", file.getPath());
                setResult(RESULT_OK, data);

                finishWithResult(file.getPath());
                if (signature != null) {
                    File file1 = new File(signature);
                    file1.delete();
                }
            }
        }
    });
    clear.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            mv.clear();
            mv.setIsSigned(false);
        }
    });

}

private void finishWithResult(String path) {
    Intent intent = new Intent();
    setResult(RESULT_OK, intent);
    intent.putExtra("path", path);
    finish();
}


@Override
public boolean handleMessage(Message msg) {
    return false;
}


public class DrawerView extends View {
    private Bitmap mBitmap;
    private Canvas mCanvas;
    private Path mPath;
    private Paint mBitmapPaint;
    private float mX, mY, sX, sY;
    private boolean isSigned = false;

    public DrawerView(Context c) {
        super(c);
        mPath = new Path();
        mBitmapPaint = new Paint(Paint.DITHER_FLAG);
        mBitmapPaint.setColor(Color.WHITE);
    }

    public DrawerView(Context c, Bitmap bitmap) {
        super(c);
        mPath = new Path();
        mBitmapPaint = new Paint(Paint.DITHER_FLAG);
        mBitmapPaint.setColor(Color.WHITE);
        mBitmap = bitmap;
    }

    public void setIsSigned(boolean isSigned) {
        this.isSigned = isSigned;
    }

    public boolean isSigned() {
        return isSigned;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);
        mCanvas = new Canvas(mBitmap);
        mCanvas.drawColor(Color.WHITE);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
        canvas.drawPath(mPath, mPaint);
    }

    public void clear() {
        setDrawingCacheEnabled(true);
        mCanvas.drawColor(Color.WHITE);
        invalidate();
    }

    private void drawDot(float x, float y) {
        mCanvas.drawCircle(x, y, 2.0f, mPaint);
    }

    private void touch_start(float x, float y) {
        mPath.reset();
        mPath.moveTo(x, y);
        mX = x;
        mY = y;
        sX = x;
        sY = y;
    }

    private void touch_move(float x, float y) {
        mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
        mX = x;
        mY = y;
        mCanvas.drawPath(mPath, mPaint);
    }

    private void touch_up() {
        mPath.lineTo(mX, mY);
        mCanvas.drawPath(mPath, mPaint);
        mPath.reset();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        this.isSigned = true;
        float x = event.getX();
        float y = event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                touch_start(x, y);
                break;
            case MotionEvent.ACTION_MOVE:
                touch_move(x, y);
                break;
            case MotionEvent.ACTION_UP:
                if (x == sX && y == sY) {
                    drawDot(x, y);
                }
                touch_up();
                break;
        }
        invalidate();
        return true;
    }
}
* *} Тысяча двадцать-один

1 Ответ

0 голосов
/ 16 января 2019

Вы можете сохранить сенсорные события в каком-либо списке и затем воссоздать их после изменений конфигурации. Это уже объяснено здесь.

Ваш класс должен выглядеть следующим образом

public class DrawerView extends View {
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
private float mX, mY, sX, sY;
private boolean isSigned = false;

private static final String EXTRA_STATE = "exta_state";
private static final String EXTRA_EVENT_LIST = "exta_event_list";


private ArrayList<MotionEvent> motionEvents = new ArrayList<>();
private ArrayList<MotionEvent> auxMotionEvents = new ArrayList<>();

public DrawerView(Context c) {
    super(c);
    mPath = new Path();
    mBitmapPaint = new Paint(Paint.DITHER_FLAG);
    mBitmapPaint.setColor(Color.WHITE);
    setSaveEnabled(true);
}

public DrawerView(Context c, AttributeSet attributeSet) {
    super(c, attributeSet);
    mPath = new Path();
    mBitmapPaint = new Paint(Paint.DITHER_FLAG);
    mBitmapPaint.setColor(Color.WHITE);
    setSaveEnabled(true);
}

public DrawerView(Context c, Bitmap bitmap) {
    super(c);
    mPath = new Path();
    mBitmapPaint = new Paint(Paint.DITHER_FLAG);
    mBitmapPaint.setColor(Color.WHITE);
    mBitmap = bitmap;
    setSaveEnabled(true);
}

@Override
public Parcelable onSaveInstanceState() {



    Bundle bundle = new Bundle();
    bundle.putParcelable(EXTRA_STATE, super.onSaveInstanceState());
    bundle.putParcelableArrayList(EXTRA_EVENT_LIST, motionEvents);

    return bundle;
}

@Override
public void onRestoreInstanceState(Parcelable state) {
    if (state instanceof Bundle) {

        auxMotionEvents = new ArrayList<>();
        motionEvents = new ArrayList<>();

        Bundle bundle = (Bundle) state;
        super.onRestoreInstanceState(bundle.getParcelable(EXTRA_STATE));
        auxMotionEvents = bundle.getParcelableArrayList(EXTRA_EVENT_LIST);
        if (auxMotionEvents == null) {
            auxMotionEvents = new ArrayList<>();
        }

        return;
    }
    super.onRestoreInstanceState(state);
}

private void performTouch(MotionEvent event) {
    this.isSigned = true;
    float x = event.getX();
    float y = event.getY();
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            touch_start(x, y);
            break;
        case MotionEvent.ACTION_MOVE:
            touch_move(x, y);
            break;
        case MotionEvent.ACTION_UP:
            if (x == sX && y == sY) {
                drawDot(x, y);
            }
            touch_up();
            break;
    }
    invalidate();
    motionEvents.add(MotionEvent.obtain(event));
}




public void setIsSigned(boolean isSigned) {
    this.isSigned = isSigned;
}

public boolean isSigned() {
    return isSigned;
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);
    mCanvas = new Canvas(mBitmap);
    mCanvas.drawColor(Color.WHITE);

    if (auxMotionEvents != null) {
        for (MotionEvent motionEvent : auxMotionEvents) {
            performTouch(motionEvent);
        }
    }

}


@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
    canvas.drawPath(mPath, mBitmapPaint);
}

public void clear() {
    setDrawingCacheEnabled(true);
    mCanvas.drawColor(Color.WHITE);
    invalidate();
}

private void drawDot(float x, float y) {
    mCanvas.drawCircle(x, y, 2.0f, mBitmapPaint);
}

private void touch_start(float x, float y) {
    mPath.reset();
    mPath.moveTo(x, y);
    mX = x;
    mY = y;
    sX = x;
    sY = y;
}

private void touch_move(float x, float y) {
    mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
    mX = x;
    mY = y;
    mCanvas.drawPath(mPath, mBitmapPaint);
}

private void touch_up() {
    mPath.lineTo(mX, mY);
    mCanvas.drawPath(mPath, mBitmapPaint);
    mPath.reset();
}

@Override
public boolean onTouchEvent(MotionEvent event) {

    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
        case MotionEvent.ACTION_MOVE:
        case MotionEvent.ACTION_UP:
            performTouch(event);
    }

    return true;
}

}

Не забудьте удалить android: configChanges = "keyboardHidden | Ориентация | screenSize" из вашего manisfest и дать ID представления, чтобы его можно было воссоздать.

Чтобы установить идентификатор для вашего представления, используйте setId () после создания экземпляра DrawerView в вашем initializeView (). Это должно выглядеть примерно так

private void initializeView() {
drawerBox = this.findViewById(R.id.drawerContainer);
save = findViewById(R.id.saveBtn);
clear = findViewById(R.id.clearBtn);
if (existingSign) {
    mv = new DrawerView(this, BitmapFactory.decodeFile(getIntent()
            .getStringExtra(getPackageName() + "_signaturePath")));
} else {
    mv = new DrawerView(this);
}

mv.setId(View.generateViewId());

mv.setDrawingCacheEnabled(false);
mv.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
        ViewGroup.LayoutParams.MATCH_PARENT));
drawerBox.addView(mv);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(3);
mv.setDrawingCacheEnabled(true);

}

...