Android # java file에서 layout 생성
안드로이드/Android-Dev

Android # java file에서 layout 생성

java source 코드로 layout 생성

화면에 보이는 레이아웃 소스 코드와 자바 소스 코드는 서로 분리되어 있어 화면 구성을 바꿀 때 자바 소스 코드는 그대로 두고 레이아웃 소스 코드만 수정하면 된다.

그러나 화면 레이아웃을 미리 만들 수 없는 경우 또는 필요할 때마다 바로바로 레이아웃을 만들어야 하는 경우에는 자바 소스코드에서 화면 레이아웃을 구성해야 할 수도 있다. 예를 들어, 사용자가 입력한 데이터나 파일에서 읽어 들인 데이터 또는 네트워킹을 통해 서버에서 받아온 데이터의 유형에 따라 화면의 구성을 바꾸고 싶다면 XML로 정의하는 것보다 자바 코드에서 화면을 구성하는 것이 훨씬 더 효율적이다.

간단한 예제로 살펴보겠다.

 

[LayoutcodeActivity.java]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package org.techtown.layoutexercise;
 
import android.os.Bundle;
import android.widget.Button;
import android.widget.LinearLayout;
 
import androidx.appcompat.app.AppCompatActivity;
 
public class LayoutCodeActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
 
        // new 연산자로 리니어 레이아웃을 만들고, 방향 설정
        LinearLayout mainLayout = new LinearLayout(this);
        mainLayout.setOrientation(LinearLayout.VERTICAL);
 
        // new 연산자로 레이아웃 안에 추가될 뷰들에 설정할 파라미터 생성
        LinearLayout.LayoutParams params =
                new LinearLayout.LayoutParams(
                        LinearLayout.LayoutParams.MATCH_PARENT,
                        LinearLayout.LayoutParams.WRAP_CONTENT
                );
 
        Button button1 = new Button((this));
        button1.setText("Button1");
        button1.setLayoutParams(params);
        mainLayout.addView(button1);
 
 
        setContentView(mainLayout);
    }
}
 
cs

위 코드는 연결되어있는 XML이 없지만, java 파일에서 layout을 생성하고 그것을 등록시키는 코드이다.
예제를 확인하려면(LayoutCodeActivity.java를 실행시키기 위해, 초기 설정값인 MainActivity.java로 설정되어 있으니까),
AndroidManifest.xml에서 android:name 부분을 수정해준다.

 

[AndroidManifest.xml]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.techtown.layoutexercise">
 
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".LayoutCodeActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
 
</manifest>
cs

위 레이아웃은 자바 소스 코드에서 만들어진 것이다.

화면 생성 과정 분석하기

LayoutCodeActivity.java 소스 코드를 보면 onCreate() 메서드 안에 setContentView() 메서드를 호출하는 부분이 있다.
기존에는 R.layout.acivity_main과 같이 레이아웃으로 정의된 리소스를 가리키도록 설정되어있었지만, 위에서는 자바 코드에서 만든 레이아웃 객체를 가리키도록 수정한 것이다. 이렇게 레이아웃으로 만든 객체를 setContentView() 메서드의 파라미터로 전달하면 그 레이아웃이 화면에 표시된다.

this 키워드

앞에서 입력한 코드를 보면 this라는 키워드가 눈에 띈다. 이것은 Context 객체가 전달된 것이다. new 연산자를 사용해서 뷰 객체를 코드에서 만들 때는 항상 Context 객체가 전달되어야 한다. 이 특징은 표준 자바에서는 없고 안드로이드에만 있는 특징이다. 다시 말해, 안드로이드의 모든 UI객체들은 Context객체를 전달받도록 되어 있는 것이다.
AppCompatActivity 클래스는 Context를 상속하므로 이 클래스 안에서는 this를 Context 객체로 사용할 수 있다. 만약 Context를 상속받지 않은 클래스에서 Context 객체를 전달해야 한다면 getApplicationContext라는 메서드를 호출하여 앱에서 참조 가능한 Context 객체를 사용할 수 있다.

뷰그룹에 추가하기

  1. 뷰 배치를 위한 속성을 설정할 수 있는 **LayoutParams 객체 사용.
    • 뷰의 속성 중에서 레이아웃과 관련된 속성을 담고 있음.
    • LayoutParams 객체를 새로 만들 경우에는 반드시 뷰의 가로와 세로 속성을 지정해야 함.
    • LayoutParams.MATCH_PARENT / LayoutParams.WRAP_CONTENT 의 상수를 이용하거나, 직접 숫자로 설정 가능.
  2. addView() 메서드를 사용해서, 소스코드에서 레이아웃에 뷰를 추가.