본문 바로가기

Android/Custom Widget

Android Custom Widget example

Android 에서 커스텀 위젯을 작성할 때 다수개의 기본 위젯을 복합적으로 사용하여 마치 한개의 위젯처럼 메인 레이아웃 파일에 선언하고 사용하는 예제


간단한 로그인 박스를 커스텀 위젯으로 작성하고 사용하는 예를 들어본다


작업절차

1. 레이아웃 파일 작성 : 다수개의 위젯을 배치한 레이아웃 파일을 작성한다. 커스텀 위젯의 레이아웃 파일이다

2. 커스텀 위젯 클래스 작성 : 위에서 작성된 레이아웃 파일을 로드하여 포함하는 부모 레이아웃 클래스를 작성한다

3. 메인 레이아웃 파일 작성 : 커스텀 위젯 클래스를 메인 레이아웃 파일에 배치한다

4. 액티비티 클래스 작성 : 액티비티 클래스 내에서 메인 레이아웃 파일을 로드하고 화면에 출력한다


레이아웃 파일(loginbox.xml) 작성 : 다수개의 위젯을 포함하는 레이아웃을 작성한다. 이 레이아웃 파일은 커스텀 위젯 클래스가 로드하여 포함하게 된다

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="wrap_content" 

    android:background="#880000ff">


    <TextView

        android:id="@+id/textView1"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_alignParentLeft="true"

        android:layout_alignParentTop="true"

        android:layout_marginTop="20dp"

        android:text="아이디"

        android:textAppearance="?android:attr/textAppearanceLarge" />


    <TextView

        android:id="@+id/textView2"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_alignParentLeft="true"

        android:layout_below="@+id/textView1"

        android:layout_marginTop="16dp"

        android:text="암   호"

        android:textAppearance="?android:attr/textAppearanceLarge" />


    <EditText

        android:id="@+id/editText1"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_alignBottom="@+id/textView1"

        android:layout_alignParentRight="true"

        android:ems="10" >

        <requestFocus />

        </EditText>


    <EditText

        android:id="@+id/editText2"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_alignBottom="@+id/textView2"

        android:layout_alignLeft="@+id/editText1"

        android:ems="10" >


        

    </EditText>


    <Button

        android:id="@+id/button1"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_alignLeft="@+id/editText2"

        android:layout_below="@+id/editText2"

        android:layout_marginLeft="35dp"

        android:layout_marginTop="18dp"

        android:text="로그인" />


</RelativeLayout>



커스텀 위젯 클래스(LoginBox.java)

package com.example.androidtest;


import android.content.Context;

import android.util.*;

import android.view.*;

import android.widget.*;


/* 커스텀 위젯 클래스가 레이아웃 클래스를 상속하면 현재 클래스가 레이아웃을 로드할 때 

* 그 레이아웃을 포함하는 부모 그룹이 될 수 있기 때문에 로드한 레이아웃의 형태를 그대로 가진 

* 한개의 커스텀 뷰(커스텀 위젯) 클래스가 될 수 있다

*/

public class LoginBox extends LinearLayout {


Context context;

        /* 이 클래스를 포함하는 메인 레이아웃 파일에서 속성을 정의하지 않으면 이 생성자가 자동으로 호출됨 */

public LoginBox(Context context) {

this(context, null);

// TODO Auto-generated constructor stub

Log.d("생성자 호출", "파라미터 1 생성자");

}


        /* 이 클래스를 포함하는 메인 레이아웃 파일에서 속성을 정의한 경우에는 이 생성자가 자동으로 호출됨 */

public LoginBox(Context context, AttributeSet attrs) {

super(context, attrs);

// TODO Auto-generated constructor stub

this.context = context;

Log.d("생성자 호출", "파라미터 2 생성자");


                /* 위에서 정의한 레이아웃 파일을 로드하고 현재 클래스가 부모 그룹이 되어 로드된 레이아웃을 포함한다

                * 그러므로 현재 클래스의 모습은 레이아웃과 동일한 형태를 가진 하나의 View 가 되는 셈이고 이 클래스를

                * 다른 레이아웃에서 태그로 포함하면 화면에 배치된다

                */

LayoutInflater inflater = (LayoutInflater)

context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

inflater.inflate(R.layout.loginbox, this, true);


Button btn = (Button) findViewById(R.id.button1);

btn.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View arg0) {

// TODO Auto-generated method stub

EditText editID = (EditText) findViewById(R.id.editText1);

EditText editPWD = (EditText) findViewById(R.id.editText2);

String id = editID.getText().toString();

String pwd = editPWD.getText().toString();

Toast.makeText(LoginBox.this.context, id+":"+pwd+" 로그인", 

Toast.LENGTH_SHORT).show();

}

});

}

/*

public LoginBox(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

// TODO Auto-generated constructor stub

}

*/

}



메인 레이아웃 파일(activity_main.xml), 위에서 정의한 커스텀 위젯 클래스를 사용하는 예

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:paddingBottom="@dimen/activity_vertical_margin"

    android:paddingLeft="@dimen/activity_horizontal_margin"

    android:paddingRight="@dimen/activity_horizontal_margin"

    android:paddingTop="@dimen/activity_vertical_margin"

    tools:context=".MainActivity" >


    <com.example.androidtest.LoginBox

        android:id="@+id/loginBox1"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:layout_alignParentLeft="true"

        android:layout_alignParentTop="true" >

    </com.example.androidtest.LoginBox>


</RelativeLayout>



액티비티 클래스

package com.example.androidtest;


import android.widget.*;

import android.app.*;


public class MainActivity extends Activity {


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

}