2011년 8월 1일 월요일

Android - Custom View 에 xml 로 속성 부여하기, CUSTOM BUTTON

목적
사용자가 정의한 cutom view를 layout xml에서 정의해서 사용할 경우
사용자가 정의한 custom view의 속성에 값을 layout xml 파일에서 설정 할 수 있다.
(음.. 설명이 어렵군..)

예)
ImageButton이 맘에 들지 않아 ImageView를 상속받은 custom button을 만들려고 한다.


다른부분은 별다른 수정없이 사용 가능하지만


ACTION_DOWN, ACTION_UP 시 이미지를 변화시키는 로직을 custom button 안에 구현하고 싶다.


그러기 위해서 custom view 클래스는 평상시 icon과 눌려졌을때(ACTION_DOWN) icon 에 대한 속성값을 가지고 있어야 하고


이 속성들을 이용해서 onTouchListener를 구성해주면 된다.


위에서 언급한 icon들을 class 파일에서 설정해 줄 수 있지만


왠지 코드가 지저분해지는거 같아 layout xml파일에서 해당 속성을 입력해주고싶다.


뭐 이런 상황에서 사용하는 방법이다.

간단하게 설명하면,

추가할 속성값들을 새로운 xml 파일로 정의하고, 정의된 xml 파일을 layout의 namespace에 추가해서 사용하는 형태인데

이것도 말로 하면 복잡하니까 예를 들어 설명하면


1. res/values/attr.xml - 신규작성 : 신규 속성을 정의할 xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="CustomImageButton">
    <attr name="icon" format="integer" />
        <attr name="icon_selected" format="integer" />
    </declare-styleable>
</resources>



2. CustomImageButton.java - custom button 클래스


package jh;

import jh.R;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;

public class CustomImageButton extends ImageView{

private Drawable icon;
private Drawable iconSelected;

public CustomImageButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setTouchEvent();
setIcons(context, attrs);
// TODO Auto-generated constructor stub
}

public CustomImageButton(Context context, AttributeSet attrs) {
super(context, attrs);
setTouchEvent();
setIcons(context, attrs);
// TODO Auto-generated constructor stub
}

public CustomImageButton(Context context) {
super(context);
setTouchEvent();

// TODO Auto-generated constructor stub
}


private void setIcons(Context context, AttributeSet attrs){
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomImageButton);


icon = a.getDrawable(R.styleable.CustomImageButton_icon);
iconSelected = a.getDrawable(R.styleable.CustomImageButton_icon_selected);
}

private void setIconNormal(){
if (icon != null) {
this.setImageDrawable(icon);
}
}

private void setIconSelected(){
if (iconSelected != null) {
this.setImageDrawable(iconSelected);
}
}

private void setTouchEvent(){
this.setOnTouchListener(new OnTouchListener() {

@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
if (event.getAction() == MotionEvent.ACTION_DOWN){
setIconSelected();
}else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_OUTSIDE){
setIconNormal();
}

return false;
}
});
}

}




3. res/layout/subject.xml - layout 파일

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/jh"
android:layout_width="fill_parent"
    android:layout_height="fill_parent" android:background="#fffbfbfb">
 
    <LinearLayout
    android:id="@+id/contentLayout"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
     >
     
        <LinearLayout android:layout_height="wrap_content" android:id="@+id/linearLayout2" android:layout_width="match_parent">
            <Spinner android:layout_height="wrap_content" android:id="@+id/spinner1" android:layout_weight="1" android:layout_width="wrap_content"></Spinner>
         
            <jh.project.whomli.school.custom.CustomImageButton app:icon="@drawable/utilicon_add" app:icon_selected="@drawable/utilicon_add_selected" android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/subjectBtnAdd" android:src="@drawable/utilicon_add" android:layout_weight="0" android:clickable="true"></jh.project.whomli.school.custom.CustomImageButton>
        </LinearLayout>

    </LinearLayout>

</RelativeLayout>




뭐 이런식으로 사용하면 된다.

뭔가 단순하면서도 유용할듯하다.