안드로이드 컴스텀뷰만들 때 생성자 질문드립니다.
조회수 4513회
Custom뷰를 만들때 다른 레이아웃을 상속받게되면 아래 생성자를 구현해야 하는 걸로 알고있는데요 이중 defStyleAttr와 defStyleRes 파라메터가 왜 필요하고 어떤 곳에 사용이 되는지 궁금합니다.~ 가능하시다면 사용법도 알려주시면 감사합니다!
public MyView(Context context) {
super(context);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public MyView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
-
(•́ ✖ •̀)
알 수 없는 사용자
1 답변
-
defStyleAttr은 뷰의 기본적인 속성들을 지정하기 위한 파라미터입니다. EditText의 생성자 코드를 보면 다음과 같이 정의되는 것을 알 수 있는데요.
public class EditText extends TextView { public EditText(Context context) { this(context, null); } public EditText(Context context, AttributeSet attrs) { this(context, attrs, com.android.internal.R.attr.editTextStyle); } public EditText(Context context, AttributeSet attrs, int defStyleAttr) { this(context, attrs, defStyleAttr, 0); } public EditText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } ... }
두번째 생성자를 보면 this()를 통해 세번째 생성자를 호출하는 것을 확인할 수 있습니다. defStyleAttr로 넘겨지는 com.android.internal.R.attr.editTextStyle에 정의되어 있는 속성은 다음과 같이 부여되어 있는 것을 알 수 있습니다.
<style name="Widget.EditText"> <item name="focusable">true</item> <item name="focusableInTouchMode">true</item> <item name="clickable">true</item> <item name="background">?attr/editTextBackground</item> <item name="textAppearance">?attr/textAppearanceMediumInverse</item> <item name="textColor">?attr/editTextColor</item> <item name="gravity">center_vertical</item> <item name="breakStrategy">simple</item> <item name="hyphenationFrequency">normal</item> </style>
EditText가 TextView를 상속받고 있지만 EditText 고유의 속성을 defStyleAttr을 통해 View 생성 시점에 설정한다고 이해하면 쉬울 것 같고요. defStyleAttr과 defStyleRes 차이는 R.attr.XXX와 R.style.XXX을 넘기느냐의 차이입니다.
관련 예제는 아래 링크를 참고하세요.
-
(•́ ✖ •̀)
알 수 없는 사용자 -
(•́ ✖ •̀)
알 수 없는 사용자 - 〉
- 답변감사합니다. 궁금한점이 하나 더 있는데요 거의 대부분의 커스텀뷰가 아래 3개의 파라메터를 가지고있는 생성자를 정의하고 있던데 public MyView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } 왜 만들어주어야 하며 호출되는 시점이 궁금합니다. 테스트해본 결과 매개변수 1개 짜리는 매번 호출이 되었고 매개변수 2개 짜리는 Xml 문서상에 커스텀으로만든 뷰의 태그가 있으면 호출되더라구요 그렇다면 매개변수 3개짜리는 언제 호출이 되는 건가요? 2016.5.23 17:35
- 세번째와 네번째 생성자는 Optional입니다. 즉, 커스텀뷰를 만들 때 반드시 오버라이드 해야하는 것은 아니고요. 다만 많은 코드에서 세번째 생성자를 -필요없는 상황에서도 굳이- 오버라이드하는 이유는 관습적인 코드로 보셔도 될 것 같습니다. 그리고 첫번째 생성자는 View를 코드에서 생성할 때, 두번째 생성자는 XML을 통해 View를 inflating할 때 호출됩니다. 그리고 세번째 생성자는 두번째 생성자, 즉, XML에서 View가 inflating될 때 this(context attrs, R.attr.XXX)를 통해서 호출하는 것이 일반적인 패턴입니다. 안드로이드에서 제공하는 Button, GuidedActionEditText, CheckedTextView, AutoCompleteTextView등의 코드를 보시면 세번째 생성자가 호출되는 예를 살펴볼 수 있습니다. 관련 링크를 첨부했으니 생성자 쪽을 살펴보시기 바랍니다. https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/widget/Button.java https://github.com/android/platform_frameworks_support/blob/master/v17/leanback/src/android/support/v17/leanback/widget/GuidedActionEditText.java https://android.googlesource.com/platform/frameworks/base/+/b023a58/core/java/android/widget/CheckedTextView.java https://android.googlesource.com/platform/frameworks/base/+/41ec65355bd6ded652769725b276d47c54a0d913/core/java/android/widget/AutoCompleteTextView.java 2016.5.23 18:59
-
댓글 입력