[PAAD] 4장 커스텀 뷰 만들기
1. 기존 뷰 수정하기
// ** Listing 4-5: Extending TextView (Extended)
public class MyTextView extends TextView {
public MyTextView (Context context, AttributeSet ats, int defStyle) {
super(context, ats, defStyle);
}
public MyTextView (Context context) {
super(context);
}
public MyTextView (Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void onDraw(Canvas canvas) {
[ ... Draw things on the canvas under the text ... ]
// Render the text as usual using the TextView base class.
super.onDraw(canvas);
[ ... Draw things on the canvas over the text ... ]
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent keyEvent) {
[ ... Perform some special processing ... ]
[ ... based on a particular key press ... ]
// Use the existing functionality implemented by
// the base class to respond to a key press event.
return super.onKeyDown(keyCode, keyEvent);
}
}
ⓐ 기존뷰를 상속한다
ⓑ 생성자와 OnDraw()를 구현한다
ⓒ 리소스 id를 사용하기위해 xml을 만든다"<com.paad.todolist.TodoListItemView>"와같이 풀패키지 이름으로
2. 복합 컨트롤 만들기
ⓐ xml로 레이아웃을 만들고
ⓑ 레이아웃을 상속하여 xml 컨포넌트들을 인플레이트 시켜 행동을 구현한다
3. 커스텀 뷰 만들기
ⓐ onMeasure 오버라이딩: 자신이 차지할 폭과 높이를 계산
ⓑ OnDraw: 캔버스에 그린다
// *******************************************************************
// ** Listing 4-10: Creating a new View class
public class MyView extends View {
// Constructor required for in-code creation
public MyView(Context context) {
super(context);
}
// Constructor required for inflation from resource file
public MyView (Context context, AttributeSet ats, int defaultStyle) {
super(context, ats, defaultStyle );
}
//Constructor required for inflation from resource file
public MyView (Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int wMeasureSpec, int hMeasureSpec) {
int measuredHeight = measureHeight(hMeasureSpec);
int measuredWidth = measureWidth(wMeasureSpec);
// MUST make this call to setMeasuredDimension
// or you will cause a runtime exception when
// the control is laid out.
setMeasuredDimension(measuredHeight, measuredWidth);
}
private int measureHeight(int measureSpec) {
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
[ ... Calculate the view height ... ]
return specSize;
}
private int measureWidth(int measureSpec) {
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
[ ... Calculate the view width ... ]
return specSize;
}
@Override
protected void onDraw(Canvas canvas) {
[ ... Draw your visual interface ... ]
}
}
// ** Listing 4-13: A typical View measurement implementation
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int measuredHeight = measureHeight(heightMeasureSpec);
int measuredWidth = measureWidth(widthMeasureSpec);
setMeasuredDimension(measuredHeight, measuredWidth);
}
private int measureHeight(int measureSpec) {
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
// Default size if no limits are specified.
int result = 500;
if (specMode == MeasureSpec.AT_MOST) {
// Calculate the ideal size of your
// control within this maximum size.
// If your control fills the available
// space return the outer bound.
result = specSize;
} else if (specMode == MeasureSpec.EXACTLY) {
// If your control can fit within these bounds return that value.
result = specSize;
}
return result;
}
private int measureWidth(int measureSpec) {
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
// Default size if no limits are specified.
int result = 500;
if (specMode == MeasureSpec.AT_MOST) {
// Calculate the ideal size of your control
// within this maximum size.
// If your control fills the available space
// return the outer bound.
result = specSize;
} else if (specMode == MeasureSpec.EXACTLY) {
// If your control can fit within these bounds return that value.
result = specSize;
}
return result;
}