빠르게 배우는 안드로이드- 자주쓰는레이아웃(LinearLayout,RelativeLayout,FrameLayout)

오늘은 위젯(Textview,button,EditText 등등)을 배치를 용이하게 해주는 Layout 위젯들에 대해서 알아보겠습니다.

Layout은 Java swing이나 AWT를 하신분들에게는 pannel 이라는 클래스라고 생각하시면 될것입니다. 이 layout 들에 위젯들을 담꺼나 아니면 layout 안에 layout을 담아서 화면 구성을 편리하게 할수있습니다.

Layout에는 FrameLayout ,LinearLayout,TableLayout,GridLayout,RelativeLayout 이 있는데요 이 중에서

LinearLayout,RelativeLayout,FrameLayout

을 알아보도록하겠습니다.

레이아웃 종류

1.LinearLayout

안드로이드에서 가장 기본적인 Layout입니다. orientation이라는 속성을 가지고 있어 가로(Horizontal),세로(Vertical) 값을 넣으시면

가로 값일 경우 위젯들이 가로로 쌓이면서 배치되고,

orientaion = horizontal

세로 값인 경우는 세로로 쌓이면서 배치됩니다.

orientaion = vertical
(안드로이드 스튜디오가 나오기전 이클립스에 안드로이드 플러그인을 설치하여 사용하던 때 xml을 생성하면 기본적으로 LinearLayout이 배치가 된상태로 있었습니다. 
2016–01–14 기준안드로이드 스튜디오에서 xml을 생성하게 되면 RelativeLayout이 기본적으로 세팅이 되어있습니다.)

1–1 Weight속성 
Weight속성은 LinearLayout에서 제가 생각했을때 가장 실무적으로 유용할수있는 속성입니다. 가중치라고 생각하시면 되는데요

예를 들어 봅시다

이러한 화면 배치를 수행했습니다. 
먼저 각 버튼들에 weight를 1로 주고 layout_width를 0dp로 주도록하겠습니다.(layout_width는 wrap_parents여도 상관없음)

다음과 같이 버튼이 LinearLayout(horizontal속성) 안에 꽉 차게 1: 1: 1의 비율로 나타난것을 볼수있습니다.

그럼 가운데 button2에 weight를 2로 바꾸어 보겠습니다.

다음과 같이 가운데 button2 의 비율이 2 나머지것이 1인 상태 즉 1:2:1의 비율로 적용되어있는것을 볼수있습니다.

이러한 weight들이 유용하게 쓰일수있는 이유는 안드로이드는 다양한 화면을 가진 디바이스들이 존재합니다. 또한 해상도가 달라서 같은 
값이라도 따라서 weight를 사용하지 않고 layout_width의 dp를 통해서 화면을 배치가 용이하지 않을수있습니다. 따라서 weight를 적절히 사용하여 비율로써 화면을 구성함으로써 이러한 문제를 조금이나마 피할수 있습니다.
dp는 density per Pixel의 약자로 안드로이드에서 pixel 대신 사용하는것이다라고 생각하시면 쉽습니다. dp 뿐만아니라 dip라는것도 존재합니다.
더 자세히 알고싶으시다면 dp나 dip를 검색해보시는것을 추천드립니다.

2.RelativeLayout

RelativeLayout 즉 상대적인 기준의 Layout이라는 이름의 레이아웃으로

어떤 위젯 왼쪽으로 배치, 오른쪽으로 배치, 상단으로 배치,하단으로 배치, 등 
위젯을 기준으로 잡고 배치할수있게 해주는 레이아웃입니다.

RelativeLayout에 위젯들을 넣고 클릭을 해보면 다음과같은 속성들이 보이는것을 볼수있습니다.

기본적으로 배치했을때(아무런 조작없이 드래그하여 놓았을때)는 왼쪽 위 상단에 위젯들이 쌓이면서 배치되게 됩니다.

properties 속성에 값을 넣어서 배치하실수도있지만 안드로이드 디바이스 그림에서 마우스로 드래그해서 배치하면 훨씬 편리하고 직관적으로 배치할수있습니다.

3.FrameLayout

FrameLayout에 위젯들을 담게되면 차곡차곡 쌓이게 됩니다.

예를 들어 맨위에 textview에 text를 1
두번째 textview에 text를 12
세번째 textview에 text를 123을 대입하였습니다.
다음과 같이 겹쳐서 보이는것을 확인할수있습니다.

그럼 FrameLayout은 언제 사용하는것일까요? 보통 로딩중을 알려주는 Progress를 위에 띄었다가 로딩이 다되면 리스트나, 컨텐츠를 보여줄때 사용하기도 합니다.

실습

그럼 위 3가지의 위젯들을 실습해보도록합시다.

우선 다음과같이 배치들을 한 상태에서 시작하겠습니다.

여기에서 중간에 들어간 progressBar는 왼쪽 pallate에서 아래의 3개중 한개를 드래그 하시면됩니다. (progressBar가 화면에 표시되지않을수도있지만 애뮬레이터에서 실행하시면 보입니다.)

우리가 해볼것은 버튼을 눌러서 해당 화면을 변경하는 예제를 해볼것입니다.

그렇다면 처음에는 첫번째 페이지만 보여지고 나머지는 보여지지 않으면 되겠죠? FrameLayout안에있는 LinearLayout과 버튼들에 id를 주도록합시다.

다음과 같이 id를 주었습니다.

button -> linear_screenbtn, relative_screenbtn,progress_screenbtn

프로그래스바가 들어있는 linearlayout은 progress_screen
1페이지글자가 들어있는 (textview2)가 들어있는 LinearLayout은 screen1

2페이지글자가 들어있는 (textview3)가 들어있는 Relativealyout은 screen2

이렇게 id를 변경하였습니다.

이제 첫페이지만 보여져야되므로 screen1만 visibility 속성은 visible로 하고 나머지는 invisible 이나 gone 으로 설정하겠습니다.

invisible은 화면에서 보이지만 않게하는것이고 GONE은 자체를 없앤다고 생각하시면되는데 GONE으로 설정했을때

다음과같이 자리 잡고있는 부분이 조그만 점으로 바뀌는것을 알수있습니다.

이제 코드부분으로 가서 클릭을 통해서 스크린을 제어하도록합시다.

import android.os.Bundle;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

public class MainActivity extends AppCompatActivity {
Button linear_screenbtn;
Button relative_screenbtn;
Button progress_screenbtn;

LinearLayout screen1_linearlayout;
RelativeLayout screen2_relativelayout;
LinearLayout progress_linearlayout;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);


linear_screenbtn = (Button)findViewById(R.id.linear_screenbtn);
relative_screenbtn = (Button)findViewById(R.id.relative_screenbtn);
progress_screenbtn = (Button)findViewById(R.id.progress_screenbtn);

screen1_linearlayout = (LinearLayout)findViewById(R.id.screen1);
screen2_relativelayout = (RelativeLayout)findViewById(R.id.screen2);
progress_linearlayout = (LinearLayout)findViewById(R.id.progress_screen);


}


}

이 코드 상태에서 시작하도록 하겠습니다. 
버튼을 클릭했을떄 레이아웃이 visible 되야하므로 onclickListener를 사용하여 클릭이벤트를 만들어줍니다.



import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

public class MainActivity extends AppCompatActivity {
Button linear_screenbtn;
Button relative_screenbtn;
Button progress_screenbtn;

LinearLayout screen1_linearlayout;
RelativeLayout screen2_relativelayout;
LinearLayout progress_linearlayout;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);


linear_screenbtn = (Button)findViewById(R.id.linear_screenbtn);
relative_screenbtn = (Button)findViewById(R.id.relative_screenbtn);
progress_screenbtn = (Button)findViewById(R.id.progress_screenbtn);

//클릭이벤트 추가
linear_screenbtn.setOnClickListener(mOnClickListener);
relative_screenbtn.setOnClickListener(mOnClickListener);
progress_screenbtn.setOnClickListener(mOnClickListener);
//클릭이벤트 추가
screen1_linearlayout = (LinearLayout)findViewById(R.id.screen1);
screen2_relativelayout = (RelativeLayout)findViewById(R.id.screen2);
progress_linearlayout = (LinearLayout)findViewById(R.id.progress_screen);


}
//클릭이벤트 추가
View.OnClickListener mOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()){

case R.id.linear_screenbtn :

break;

case R.id.relative_screenbtn :

break;


case R.id.progress_screenbtn :

break;




}
}
};


}

이제 버튼을 클릭하였을때 해당 스크린을 키고 나머지 스크린을 꺼야합니다.

그렇다면 버튼을 클릭하면 우선 모든 스크린을 invisible시키고 해당 screen을 visible하면 되겠죠?



import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

public class MainActivity extends AppCompatActivity {
Button linear_screenbtn;
Button relative_screenbtn;
Button progress_screenbtn;

LinearLayout screen1_linearlayout;
RelativeLayout screen2_relativelayout;
LinearLayout progress_linearlayout;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);


linear_screenbtn = (Button)findViewById(R.id.linear_screenbtn);
relative_screenbtn = (Button)findViewById(R.id.relative_screenbtn);
progress_screenbtn = (Button)findViewById(R.id.progress_screenbtn);

//클릭이벤트 추가
linear_screenbtn.setOnClickListener(mOnClickListener);
relative_screenbtn.setOnClickListener(mOnClickListener);
progress_screenbtn.setOnClickListener(mOnClickListener);
//클릭이벤트 추가
screen1_linearlayout = (LinearLayout)findViewById(R.id.screen1);
screen2_relativelayout = (RelativeLayout)findViewById(R.id.screen2);
progress_linearlayout = (LinearLayout)findViewById(R.id.progress_screen);


}
//클릭이벤트 추가
View.OnClickListener mOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {

screen1_linearlayout.setVisibility(View.INVISIBLE);
screen2_relativelayout.setVisibility(View.INVISIBLE);
progress_linearlayout.setVisibility(View.INVISIBLE);


switch (v.getId()){

case R.id.linear_screenbtn :
screen1_linearlayout.setVisibility(View.VISIBLE);
break;

case R.id.relative_screenbtn :
screen2_relativelayout.setVisibility(View.VISIBLE);
break;


case R.id.progress_screenbtn :
progress_linearlayout.setVisibility(View.VISIBLE);
break;




}
}
};


}

다음과 같이 코드를 추가해주면 완성입니다.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.