안드로이드 개발 질문/답변
(글 수 45,052)
// View를 그림파일의 형태로 폰 내부에 저장
View sigView = (View)findViewById(R.id.signatureview);
// sigView가 널이라서 여기서 널포인터 익셉션이 발생
sigView.setDrawingCacheEnabled(true);
sigView.buildDrawingCache();
Bitmap bSigView = sigView.getDrawingCache();
String path = "/sdcard/imgtest.jpg";
File file = new File(path);
try{
FileOutputStream fos = new FileOutputStream(file);
bSigView.compress(CompressFormat.JPEG, 0, fos);
fos.flush();
fos.close();
} catch(Exception e) {
Toast.makeText(Main.this, "파일 저장 중 에러 발생 : " +
e.getMessage(), 0).show();
return;
}
일단 문제가 되는 부분은 주석에 달았다시피 sigView에 제가 만든 View를 레이아웃에서 찾아서 넣어주도록 만들었는데,
sigView = null 이렇게 되어서,
그 다음코드인 sigView.setDrawingCacheEnabled(true); 여기부터 버그가 발생하고 있습니다.
왜 터치를 입력받아서 그림이 그려진 뷰가 sigView로 저장이 안되고
null값이 뜨는지 그걸 해결해 주어야 할 것 같은데, 잘 모르겠네요... ㅠ
일단 레이아웃을 정의한 XML 파일은 이런 식입니다. (특별한 건 없습니다.)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<exam.PTProject.SessionChk.SignatureView
android:id="@+id/signatureview"
android:layout_width="600px"
android:layout_height="400px"
/>
</LinearLayout>
이 XML은 대화상자의 레이아웃을 정의한 파일입니다. (오류랑은 별로 상관 없을 듯 하네요...)
그리고 SignatureView.java 파일에 SignatureView 클래스만이 구현되어 있습니다.
사용자의 터치입력을 받아 뷰에 그리는 기능의 클래스인데 기능 자체는 구현이 잘 되고 있습니다.
그것을 레이아웃으로 가져온 것이구요. 혹시 볼 필요가 있으실까봐 그 코드도 올려보겠습니다.
public class SignatureView extends View{
Paint mPaint;
ArrayList<Vertex> arVertex;
// 정점 하나에 대한 정보를 가지는 클래스
public class Vertex{
Vertex(float ax, float ay, boolean ad){
x = ax;
y = ay;
Draw = ad;
}
float x;
float y;
boolean Draw;
}
public SignatureView(Context context){
super(context);
init();
}
public SignatureView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public SignatureView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init(){
// Paint 객체 미리 초기화
mPaint = new Paint();
mPaint.setColor(Color.BLACK);
mPaint.setStrokeWidth(3);
mPaint.setAntiAlias(true);
arVertex = new ArrayList<Vertex>();
}
public void onDraw(Canvas canvas){
canvas.drawColor(0xffe0e0e0);
// 정점을 순회하면서 선분으로 잇는다.
for(int i = 0; i < arVertex.size(); i++){
if(arVertex.get(i).Draw){
canvas.drawLine(arVertex.get(i-1).x, arVertex.get(i-1).y,
arVertex.get(i).x, arVertex.get(i).y, mPaint);
} // End of if statement
} // End Of for loop
} // End Of onDraw()
// 터치 이동시마다 정점들을 추가한다.
public boolean onTouchEvent(MotionEvent event){
if(event.getAction() == MotionEvent.ACTION_DOWN){
arVertex.add(new Vertex(event.getX(), event.getY(), false));
return true;
}
if(event.getAction() == MotionEvent.ACTION_MOVE){
arVertex.add(new Vertex(event.getX(), event.getY(), true));
invalidate();
return true;
}
return false;
} // End Of onTouchEvent()
}