1. 리눅스 OS 이름 확인

rpm -qa *-release

다른 방법으로는

cat /etc/*release*


2. 리눅스 OS bit 수 확인

getconf LONG_BIT


3. MAC ADDRESS 확인

ifconfig -a


4. CPU 개수 확인

grep -c processor /proc/cpuinfo


5. jdk 1.7 버전 다운로드 경로

http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase7-521261.html


HaveAGoodTime.apk


Posted by 정윤문경아빠

안녕하세요. 요새 너무 바빠서 글을 올릴 시간이 없었네요.


이번에는 jericho-android.3.1.jar 를 이용해서 유튜브 홈페이지의 재생목록을 파싱해보도록 하겠습니다.


jericho-android.3.1.jar 파일은 첨부파일에 올려놓을테니 다운받으시고 이클립스에서 Build Path에 추가해주세요.(추가하시는 방법 모르시면 댓글 달아주세요.)

jericho-android.3.1.jar



그럼 시작하겠습니다.


우선 제가 파싱하고자 하는곳을 살펴보도록 하겠습니다.


제가 만들어 놓은 재생목록 입니다. 물론 다른 사람의 재생목록도 볼 수 있습니다.




제가 올린 재생목록이 보이는데 이중에서 구름빵 2기에 들어가 보겠습니다.


구름빵 2기 들어가면 다음과 같습니다.





제목과 올린사람 ID 시간등이 보이네요.


여기를 파싱해 보도록 하겠습니다.


유튜브는 파싱을 할려면 다음 주소에 들어가야합니다.


https://gdata.youtube.com/feeds/api/users/kcizzang/playlists


위에 빨간배경 글자는 제 아이디 입니다. 저 부분만 본인 아이디 또는 다른사람 아이디를 입력하시면 됩니다. 우선 제 아이디로 들어갔을때 화면을 보도록 하겠습니다.




위 사진처럼 xml 문서가 보이게 되는데 아까 제가 구름빵 2기를 파싱한다고 했으므로 빨간 상자의 주소에 들어가도록 합니다.


주소는 다음과 같습니다 : https://gdata.youtube.com/feeds/api/playlists/PLjMAs0z8gAZjibk9-Ag9NIOOdPA03D5j-


비슷한 URL 들이 보이는데 https://gdata.youtube.com/feeds/api/playlists/재생목록리스트 <- 이러한 형식의 URL로 접속하셔야 정확한 정보가 보이게 됩니다.




정확하게 들어오셨다면 위 그림과 같은 화면이 나오게 됩니다. 여기에서 우선 저는 제목만 파싱만 해올것이라서 위에 줄친것을 보도록 합니다.


<title type="text">구름빵 2기 26화 홍시의 습관 고치기


이렇게 되어있네요. 위에 title, type, text 를 잊지말고 이제 코딩을 시작하겠습니다.



import java.net.URL;

import java.util.ArrayList;

import java.util.List;


import net.htmlparser.jericho.Element;

import net.htmlparser.jericho.HTMLElementName;

import net.htmlparser.jericho.Source;

import net.htmlparser.jericho.TextExtractor;

import android.app.Activity;

import android.os.Bundle;

import android.widget.TextView;


public class MainActivity extends Activity{


TextView textView;  // 제목을 표시해줄 텍스트뷰

private static Thread thread = null;

String parsing_url;  // 파싱해오고자 하는 URL

String get_data;  // 파싱해서 가져온 데이터를 저장할 스트링 변수

ArrayList<String> array;  // get_data 변수의 값을 순차적으로 저장할 배열

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        

        textView = (TextView)findViewById(R.id.textView1);

parsing_url = "https://gdata.youtube.com/feeds/api/playlists/PLjMAs0z8gAZjibk9-Ag9NIOOdPA03D5j-";

Runnable task = new Runnable(){

public void run(){

getData(parsing_url);

}

};

thread = new Thread(task);

thread.start();  // 반드시 쓰레드를 해줘야함 그 이유는 아래에서 설명

try{

thread.join();  // 쓰레드 작업 끝날때까지 다른 작업들은 대기

}catch(Exception e){

}

for(int i = 0; i < array.size(); i++){

textView.append(array.get(i) + "\n");  // 쓰레드 작업 끝나면 텍스트뷰에 가져온 데이터를 입력

}

}

    

    // 파싱 작업을 하는 메서드

    public ArrayList<String> getData(String strURL){

    Source source;

    get_data = "";

    array = new ArrayList();

    try{

    URL url = new URL(strURL);

    source = new Source(url);  // 쓰레드를 사용 안하면 여기에서 예외 발생함 그 이유는 아래에서 설명

    Element element = null;

   

    List<Element> list = source.getAllElements(HTMLElementName.TITLE); // title 태그의 엘리먼트 가져옴

   

    for(int i = 0; i < list.size(); i++){

    element = list.get(i);

    String attributevalue = element.getAttributeValue("type");  // title 태그의 속성값이 type을 찾는다

    if(attributevalue != null){

    if(attributevalue.equalsIgnoreCase("text")){  // type의 값이 text 이면

    TextExtractor textExtractor = element.getTextExtractor();  // 해당 문자값을 가져온다

    get_data = textExtractor.toString();  // 가져온 값을 스트링으로 변환후

    array.add(get_data);  // ArrayList에 추가한다

    }

    }

    }

    }catch(Exception e){

   

    }

    return array;  // 입력된 배열값을 리턴

    }

}

 


끝입니다. 안드로이드 공부한지 얼마안되어서 그런지 소스 정리를 잘 못하겠네요. 이해해주시구요. ㅎㅎ


그럼 실행화면을 한번 볼까요?




예~ 성공적으로 잘 가져오네요.


우선 아까 위에 주석에 보면 쓰레드를 반드시 이용해야한다고 했는데 그 이유는 예전에 안드로이드 진저브레드(2.3버전) 까지는 네트워크 작업을 메인 쓰레드에서 같이 작업이 가능했었습니다.


하지만 아이스크림(4.0버전) 이후부터는 네트워크 작업에 메인쓰레드에서 작업이 안되도록 했습니다.


그래서 반드시 쓰레드를 생성해야 한다는 것입니다.


별거 아닌 이유를 왜 지금 적느냐면 다른데서 구글링 해보면 거의 대부분이 쓰레드를 이용하라는 언급이 없어서 이렇게 저라도 글을 남기고 있습니다.


쓰레드는 여기까지 하고...다음은 처음 그림에서 title, type, text를 유심히 보라고 했었는데 소스 적어놓은데 보면 그 이유가 있습니다. 뭐...어렵지 않으니까 보시면 아~ 하실꺼에요.


혹시 이해안되시거나 궁금한거 있으시면 댓글 달아주시면 성실히 답변 드리도록 하겠습니다. ㅎ



Posted by 정윤문경아빠

구글 플레이스토어에서 앱을 다운받으면 자동으로 바탕화면에 아이콘이 생성이 됩니다.


하지만 Tstore 라던가 몇몇 스토어에서는 앱을 설치해도 바탕화면에 아이콘이 생성이 안됩니다.


아래는 바탕화면에 아이콘을 생성하는 코드입니다. 그대로 하시면 됩니다.



MainActivity.java 

public class MainActivity extends Activity{

    protected void onCreate(Bundle savedInstanceState){

        super.onCreate(savedInstanceState);


        SharedPreferences pref = getSharedPreferences("pref", MODE_PRIVATE);

        pref.getString("check", "");

        if(pref.getString("check", "").isEmpty()){

Intent shortcutIntent = new Intent(Intent.ACTION_MAIN);

shortcutIntent.addCategory(Intent.CATEGORY_LAUNCHER);

shortcutIntent.setClassName(this, getClass().getName());

shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK| 

Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);

Intent intent = new Intent();

intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);

intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, getResources().getString(R.string.app_name));

intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,

Intent.ShortcutIconResource.fromContext(this, R.drawable.ic_launcher));

intent.putExtra("duplicate", false);

intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");

        

sendBroadcast(intent);

        }

SharedPreferences.Editor editor = pref.edit();

        editor.putString("check", "exist");

        editor.commit();

    }

}




AndroidManifest.xml 

<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />  // 추가해줍니다.


정말 간단하죠?


이제 앱을 설치하면 자동으로 바탕화면에 아이콘이 추가되고 아이콘이 추가되어 있는 상태라면 설치를 안합니다.


즉 앱이 실행이 될때마다 아이콘 유무를 체크하고 아이콘이 없으면 아이콘을 설치합니다.



Posted by 정윤문경아빠

앱 사용하다가 종료를 할때 뒤로가기 버튼을 한번 더 터치하면 앱을 종료한다는거 한번 이상은 보셨을거라 생각을 합니다.


코드를 보도록 하겠습니다.



BackPressCloseHandler.java

public class BackPressCloseHandler extends Activity {

private long backKeyPressedTime = 0;

private Toast toast;

private Activity activity;

public BackPressCloseHandler(MainActivity context) {

this.activity = context;

        }

        public void onBackPressed() {

         if (System.currentTimeMillis() > backKeyPressedTime + 2000) {

         backKeyPressedTime = System.currentTimeMillis();

        showGuide();

         return;

         }

         if (System.currentTimeMillis() <= backKeyPressedTime + 2000) {

         activity.finish();

         toast.cancel();

         }

        }

        

        

        private void showGuide() {

         toast = Toast.makeText(activity, "뒤로 버튼을 한번 더 터치하시면 종료됩니다.",

         Toast.LENGTH_SHORT);

         toast.show();

        }

}




MainActivity.java 

private BackPressCloseHandler backPressCloseHandler;


@Override

protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    backPressCloseHandler = new BackPressCloseHandler(this);

}


public void onBackPressed() {

    backPressCloseHandler.onBackPressed();

}


크게 어려운건 없지 싶습니다.


궁금하신거는 댓글 달아주세요


Posted by 정윤문경아빠


Thread 는 잘 사용하면 참으로 좋은 유틸리티이지만 잘못 사용하면 에러를 뚜구구궁 띄웁니다.

Thread는 역할을 다하면 자동으로 종료가 되지만 간혹 자동으로 종료가 안되는 경우도 있기 때문에 Thread 종료 시점에는 강제로 종료를 시켜주는것이 좋습니다.

그리고 안드로이드경우는 Thread가 동작중일때 휴대폰에 전화가 온다거나 바깥화면으로 나가게 되어도 Thread는 계속 동작하고 있기 때문에 반드시 onPause 또는 onDestory 메서드에 Thread를 강제종료 또는 멈춤 기능 코드를 넣어야 합니다.

아래는 제가 만든 서바이벌야구게임 앱에서의 일부 코드입니다.


int count;  // 카운트다운 시간 선언

ProgressBar prog= null;  // 프로그래스바 선언

Timer timer = null;  // 타이머 선언

TimerTask timerTask = null;  // TimerTask 선언


//프로그래스bar를 초기화하는 함수

public void initProg(){

prog.setMax(countdown);  // 프로그래스바 시간 최대값 설정

prog.setProgress(countdown); // 현재 프로그래스바 시간 설정  

}

 

public void startTimerThread(){

timerTask = new TimerTask(){ //timerTask는 timer가 일할 내용을 기록하는 객체    

@Override

public void run() {

decreaseBar(); //timer가 동작할 내용을 갖는 함수 호출

            }


};

timer = new Timer(); //timer생성

timer.schedule(timerTask, 0,1000); //timerTask라는 일을 갖는 timer를 0초딜레이로 1000ms마다 실행 즉,                             1000 = 1초

}


public void decreaseBar(){

runOnUiThread( //progressBar는 ui에 해당하므로 runOnUiThread로 컨트롤해야한다

new Runnable() { //thread구동과 마찬가지로 Runnable을 써주고


@Override

public void run() { //run을 해준다. 그러나 일반 thread처럼 .start()를 해줄 필요는 없다 

countdown = prog.getProgress();

if(countdown > 0){

countdown = countdown - 1;

}else if(countdown == 0){

timer.cancel();

Thread.interrupted();  // Thread 강제 종료

}

prog.setProgress(countdown);

}

}

);



Posted by 정윤문경아빠

일반적인 프로그래밍 언어에서 화면에 컨트롤을 배치할 때 제공하는 정렬 기능을 안드로이드에서도 그대로 사용할 수 있습니다. 이 때 사용하는 용어가 안드로이드에서는 조금 다른 것을 볼 수 있는데 일반적인 정렬(align)은 순서대로 놓여 지다는 의미로 이해할 수 있으며, 안드로이드에서 사용하는 배치(gravity)는 어느 쪽에 무게 중심을 놓은 것인가의 의미로 이해할 수 있습니다. 하지만 똑같이 생각해도 상관없습니다. 레이아웃에서 정렬 기능이 필요한 경우는 다음과 같이 두 가지로 나눌 수 있습니다.



정렬 속성 

설명 

 layout_gravity

부모 컨테이너의 여유 공간에 뷰가 모두 채워지지 않아 여유 공간 안에서 뷰를 정렬할 때 

 gravity

뷰에서 화면에 표시하는 내용물을 정렬할 때(텍스트뷰의 경우, 내용물은 글자가 되고 이미지뷰의 경우 내용물은 이미지가 됨) 


먼저 부모 컨테이너의 여유 공간에 뷰가 모두 채워지지 않을 경우에 사용하는 layout_gravity는 뷰의 layout_width 나 layout_height 속성을 wrap_content로 할 경우에 같이 사용할 수 있습니다. 예를 들어, 세로 방향으로 설정된 리니어 레이아웃에 추가된 버튼들의 layout_width 속성을 wrap_content로 하게 되면 각각의 버튼들은 한 줄에 한 개씩 추가되면서 글자가 보이는 만큼의 크기로만 보이므로 나머지 가로 공간은 여유 공간으로 남게 됩니다. 안드로이드는 이렇게 여유 공간이 있을 경우 디폴트로 왼쪽 정렬을 하게되는데 layout_gravity 속성을 직접 설정하게 되면 중앙 또는 오른쪽 정렬을 할 수 있습니다.


예제를 보도록 하겠습니다.



gravity.xml 

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

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

    android:orientation="vertical"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context=".MainActivity" >


    <Button

        android:id="@+id/button01"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_gravity="left"

        android:text="버튼1" />

    

    <Button

        android:id="@+id/button02"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_gravity="center"

        android:text="버튼2" />

    

    <Button

        android:id="@+id/button03"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_gravity="right"

        android:text="버튼3" />


</LinearLayout>



실행을 해보면 결과는 다음과 같습니다.





뷰에 보이는 내용물을 정렬하는 경우에는 gravity 속성을 사용합니다. gravity 속성은 뷰가 화면에서 차지하는 영역이 충분히 큰 경우에 생기는 여유 공간 안에서 어떻게 정렬할 것인지를 결정합니다. gravity가 적용될 수 있는 대표적인 내용물로는 텍스트뷰 안에 표시되는 텍스트나 이미지뷰에 표시되는 이미지를 들 수 있습니다. gravity 속성에 넣을 수 있는 값들은 layout_gravity와 같으며, 필요한 경우에는 '|' 연산자를 이용해 여러 개의 값을 같이 설정할 수도 있습니다. 이 때 주의할 점은 '|' 연산자 양쪽에 공백이 없어야 한다는 점입니다.


다음은 하나의 텍스트뷰를 화면 전체에 채운 후 그 안에 표시되는 텍스트를 왼쪽 상단, 중앙, 그리고 오른쪽 하단에 표시할 경우에 사용되는 XML 레이아웃으로 각각 'left|top', 'center', 'right|bottom' 값이 설정되었습니다. 예제를 보도록 하겠습니다.



<TextView

        android:id="@+id/button01"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:gravity="left|top"

        android:text="left|top" /> 

 




 <TextView

        android:id="@+id/button02"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:gravity="center_horizontal|center_vertical"

        android:text="center" />

 





<TextView

        android:id="@+id/button03"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:gravity="right|bottom"

        android:text="right|bottom" /> 

 



gravity 속성으로 지정할 수 있는 값으로는 위와 같이 대표적인 경우 이외에도 여러 가지가 있으며 각각의 값에 대한 설명은 다음과 같습니다.


정렬 속성값 

설 명 

 top

 대상 객체를 위쪽 끝에 배치하기 

 bottom

대상 객체를 아래쪽 끝에 배치하기하기 

 left

대상 객체를 왼쪽 끝에 배치하기 

 right

대상 객체를 오른쪽 끝에 배치하기 

 center_vertical

대상 객체를 수직 방향의 중앙에 배치하기 

 center_horizontal

대상 객체를 수평 방향의 중앙에 배치하기 

 fill_vertical

대상 객체를 수직 방향으로 여유 공간만큼 확대하여 채우기 

 fill_horizontal

대상 객체를 수평 방향으로 여유 공간만큼 확대하여 채우기 

 center

대상 객체를 수직 방향과 수평 방향의 중앙아 배치하기 

 fill

대상 객체를 수직 방향과 수평 방향으로 여유 공간만큼 확대하여 채우기 

 clip_vertical

-대상 객체의 상하 길이가 여유 공간보다 클 경우에 남는 부분을 잘라내기

-top|clip_vertical 로 설정한 경우 아래쪽에 남는 부분 잘라내기

-bottom|clip_vertical 로 설정한 경우 위쪽에 남는 부분 잘라내기

-center_vertical|clip_vertical로 설정한 경우 위쪽과 아래쪽에 남는 부분 잘라내기 

 clip_horizontal

-대상 객체의 좌우 길이가 여유 공간보다 클 경우에 남는 부분을 잘라내기

-right|clip_horizontal 로 설정한 경우 왼쪽에 남는 부분 잘라내기

-left|clip_horizontal 로 설정한 경우 오른쪽에 남는 부분 잘라내기

-center_horizontal|clip_horizontal로 설정한 경우 왼쪽과 오른쪽에 남는 부분 잘라내기 


이것으로 gravity, layout_gravity 설명을 마치도록 하겠습니다.


도움이 되셨다면 손가락 한번 꾸~욱 눌러주시면 감사하겠습니다.^^


Posted by 정윤문경아빠

앞전에는 리니어 레이아웃과 그 안에 들어 있는 세 개 버튼은 XML로 정의한 후 이 XML 리소스 파일의 위치를 액티비티에서 사용된 setContentView() 메소드의 파라미터로 전달하여 화면에 보여주었습니다. 이렇게 화면에 보이는 레이아웃을 XML로 정의하게 되면 나중에 화면 구성을 바꿀 때도 간단하게 XML만 수정하면 되므로 훨씬 이해하기 쉽고 모듈화된 구성이라고 할 수 있습니다. 그러나 종종 코드 상에서 화면을 구성해야 하는 경우가 생기게 됩니다. 예를 들어 사용자가 입력한 데이터, 파일에서 읽어 들인 데이터 또는 네트워킹을 통해 서버에서 받아온 데이터의 유형에 따라 화면의 구성을 바꾸고 싶다면 XML로 정의하는 것보다 자바 코드에서 화면을 구성하는 것이 훨씬더 효율적인 방법입니다. 예제를 보도록 하겠습니다.



MainActivity.java 

package com.example.example;


import android.app.Activity;

import android.os.Bundle;

import android.widget.Button;

import android.widget.LinearLayout;


public class MainActivity extends Activity {


@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 button01 = new Button(this);

button01.setText("버튼1");

button01.setLayoutParams(params);

mainLayout.addView(button01);

                // 새로 만든 레이아웃을 화면에 설정

setContentView(mainLayout);

}


}



위 코드를 실행을 시키면 다음과 같은 결과가 나오게 됩니다.




프로젝트를 처음 만들었을 때 볼 수 있었던 자바 코드에는 onCreate() 메소드 안에 setContentView() 메소드가 사용되었는데, 그것과 앞에서 살펴본 코드의 다른 점은 setContentView() 메소드 안에 들어가는 파라미터가 R.layout.main과 같이 XML 레이아웃으로 정의된 리소스가 아니라 자바 코드에서 만든 뷰그룹 객체라는 것입니다. 리니어 레이아웃으로 만든 객체를 setContentView() 메소드의 파라미터로 전달하면 리니어 레이아웃 안에 추가된 뷰들을 배치한 화면을 볼 수 있습니다. 안드로이드는 XML 레이아웃에서 정의할 수 있는 대부분의 속성들을 자바 코드에서 객체를 만들거나 객체의 메소드를 호출하여 설정할 수 있도록 지원하는데 리니어 레이아웃의 방향 속성도 마찬가지입니다. new LinearLayout()을 통해 만들어진 리니어 레이아웃 객체에는 setOrientation() 메소드를 사용할 수 있으며, setOrientation(LinearLayout, VERTICAL)과 같이 방향 속성을 정의한 상수를 파라미터로 전달하면 세로 방향 또는 가로 방향으로 뷰를 추가할 수 있습니다. 뷰 객체를 코드에서 만들 때 뷰의 생성자에는 항상 Context 객체가 전달되어야 하는데 액티비티는 컨텍스트(Context)를 상속하므로 액티비티 클래스 안에서는 this를 Context 객체로 사용할 수 있습니다.

자바 코드 상에서 뷰를 만들어 뷰그룹에 추가할 때는 뷰의 배치를 위한 속성을 설정할 수 있는 LayoutParams 객체를 사용합니다. LayoutParams 객체를 새로 만들 경우에는 반드시 뷰가 추가될 영역에 대한 기본 채우기(fill) 속성을 지정해야 하며, 이 때 사용하는 두 가지 상수인 LayoutParams.MATCH_PARENT 와 LayoutParams.WRAP_CONTENT 중 하나가 사용됩니다. 필요한 경우에는 이 두 가지 상수가 아닌 가로와 세로의 크기값을 직접 설정할 수도 있습니다.

뷰그룹에 뷰를 추가하기 위해서는 addView() 메소드를 사용합니다. addView() 메소드에는 추가할 뷰를 파라미터로 전달할 수 있으며, 필요한 경우 부모 컨테이너에서 사용할 레이아웃 파라미터인 LayoutParams 객체를 같이 전달할 수도 있습니다. 앞서 살펴보았던 코드에서는 addView() 메소드를 호출할 때 LayoutParams 객체를 전달하지 않고 버튼 객체의 setLayoutParams() 메소드를 이용해 레이아웃 파라미터를 먼저 설정한 후 addView() 메소드에는 버튼 객체만을 전달하는 방법을 사용했습니다.


다음 포스팅에서는 정렬 방향 설정하는 속성인 gravity에 대해서 알아보도록 하겠습니다.



Posted by 정윤문경아빠

이번에는 리니어 레이아웃에 대해서 알아보겠습니다. 리니어 레이아웃을 보통 가장 많이 사용하며 이 레이아웃으로만으로도 웬만한 앱은 만들 수 있습니다. 리니어 레이아웃에서 빠질 수 없는게 방향 설정하기 입니다. 방향 설정은 리니어 레이아웃에서 꼭 필요한 속성으로, 뷰를 차례대로 추가할 때 가로 방향으로 할 것인지 또는 세로 방향으로 할 것인지를 지정할 수 있습니다. 리니어 레이아웃을 처음 추가했을 때는 기본 값이 세로방향으로 되어 있습니다. 리니어 레이아웃 안에 세 개의 버튼을 순서대로 추가할 경우에 XMl과 자바 코드를 구성하는 방법은 다음과 같습니다.



LinearLayout_vertical.xml 

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

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

    android:orientation="vertical"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context=".MainActivity" >


    <Button

        android:id="@+id/button01"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="버튼1" />

    

    <Button

        android:id="@+id/button02"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="버튼2" />

    

    <Button

        android:id="@+id/button03"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:text="버튼3" />


</LinearLayout>



위 속성에 보면 android:orientation="vertical" 보이시나요? vertical 은 수직방향으로 레이아웃을 구성하겠다는 의미입니다.


프로젝트를 실행하면 다음의 그림과 같이 나오게 됩니다.





버튼이 세로(수직) 방향으로 내려오네요. 그렇다면 가로 방향은 어떻게 하면 될까요? 단순히 리니어 레이아웃의 orientation 속성 값만 'horizontal'로 바꾸면 됩니다. 속성을 바꾼 후에 실행해 보면 다음과 같은 화면을 볼 수 있습니다.





그런데 에뮬레이터에 보이는 화면을 보면 세 개의 버튼 중에 첫번째 버튼만 보이는 것을 알 수 있습니다. 왜 그럴까요? 그 이유는 버튼들 가로 속성을 match_parent를 했기 때문입니다. 그러므로 리니어 레이아웃을 세로 방향으로 했을때는 정상적으로 보이지만 가로방향을 했을때에는 버튼 2, 3이 버튼1에 가려지게 되는것입니다. 이걸 정상적으로 볼려면 버튼들 속성을 바꿔주면 됩니다. 버튼들의 각각 속성인 android:layout_width="match_parent" 를 android:layout_width="wrap_content"로 바꿔 보겠습니다.



네...이제 화면이 정확하게 나오네요.


다음 포스팅에서는 리니어 레이아웃을 자바코드로 만드는 방법을 알아보도록 하겠습니다.


Posted by 정윤문경아빠

안녕하세요. 이번에는 안드로이드 레이아웃에 대해서 알아보겠습니다.


안드로이드에서 제공하는 기본 레이아웃은 다음과 같이 크게 다섯 가지로 나눌 수 있습니다.



레이아웃 이름 

설 명 

 리니어 레이아웃(LinearLayout)

- 박스(Box) 모델

- 사각형 영역들을 이용해 화면을 구성하는 방법

- 표준 자바의 BoxLayout과 유사 

 상대 레이아웃(RelativeLayout)

- 규칙(Rule) 기반 모델

- 부모 컨테이너나 다른 뷰와의 상대적 위치를 이용해 화면을 구성하는 방법 

 프레임 레이아웃(FrameLayout)

- 기본 단위 모델

- 하나의 뷰만 보여주는 방법

- 가장 단순하지만 여러 개의 뷰를 추가하는 경우 중첩시킬 수 있으므로 뷰를 중첩한 후 각 뷰를 전환하여 보여주는 방식으로 사용할 때 유용함 

 테이블 레이아웃(TableLayout)

- 격자(Grid) 모델

- 격자 모양의 배열을 이용하여 화면을 구성하는 방법

- HTML 에서 많이 사용하는 정렬 방식과 유사하여 실용적임 

 스크롤 뷰(ScrollView)

- 스크롤이 가능한 컨테이너

- 뷰 또는 뷰그룹이 들어갈 수 있으며 화면 영역을 넘어갈때 스크롤 기능 제공


추가로 절대 레이아웃(AbsoluteLayout) 이라는것이 있기는 한데 안드로이드 단말은 해상도나 화면 크기가 모두 달라 절대 좌표를 사용하는 경우에는 단말마다 다른 해상도를 맞추기 어렵기 때문에 더이상 지원하지 않게 되었습니다. 그냥 예전에 단말의 종류가 몇개 없을때 잠깐 사용된 적이 있다는것 정도로만 아시면 되겠습니다.


안드로이드에서 기본적으로 제공하는 레이아웃들을 사용할 때는 항상 android:layout_width와 android:layout_height 속성이 들어가야 합니다. 그 외의 다른 속성들도 필요 없으면 넣지 않을 수 있지만 위의 두 가지 속성을 넣지 않으면 오류가 발생하게 됩니다. 


다음 포스팅에서는 리니어 레이아웃에 대해서 알아보도록 하겠습니다.


Posted by 정윤문경아빠
IT 프로그래밍/JSP2014. 2. 1. 16:56

자바는 다양한 기능의 클래스를 제공하고 있으며, 이 클래스들을 사용해서 프로그래밍을 하게 됩니다. JSP 페이지 역시 자바를 기반으로 하고 있기 때문에, 자바 언어가 제공하는 클래스들을 사용할 수 있습니다. JSP 페이지에서 자바의 클래스를 사용하기 위해서는 어떤 자바 클래스를 사용할 것인지 미리 지정해 주어야 하는데, 이럴 때 사용하는 것이 바로 page 디렉티브의 import 속성입니다. import 속성은 다음과 같이 사용됩니다.



<%@ page import = "java.util.Calendar" %>

<%@ page import = "java.util.Date" %> 


위 코드는 JSP 페이지에서 java.util.Calendar 클래스와 java.util.Date 클래스를 사용할 것이라고 지정하고 있습니다. 위 코드에서는 한 줄에 하나씩 지정했는데, 다음과 같이 한줄에 여러 개를 콤마로 구분하여 함께 표시할 수 있습니다.



<%@ page import = "java.util.Calendar, java.util.Date" %> 


위 코드는 java.util 패키지에 있는 두 클래스인 Calendar와 Date를 사용한다고 명시한 것인데, 다수의 클래스를 사용해야 할 경우 위 코드와 같이 일일이 입력해 주는 것은 성가실것입니다. 이 경우 다음과 같이 '*' 를 사용하여 간단하게 특정 패키지에 속해 있는 모든 클래스를 사용할 수 있습니다.



<%@ page import = "java.util.*" %> 


위 예제처럼 표현하면 util 패키지의 모든 클래스를 사용한다는것을 간결하게 표현할 수 있지만 왠만하면 모든 클래스를 사용하는 경우는 없기때문에 가급적이면 제일 첫번째 예제처럼 사용하고자 하는 클래스를 일일이 지정하는것을 권장합니다. 왜냐하면 사용안하는 클래스까지 import 해버리면 메모리 낭비 및 속도저하를 일으킬 수 있기 때문입니다. 간단한 프로그램에서는 크게 영향을 미치지 않겠지만 복잡하고 큰 프로젝트에서는 분명한 차이가 있기 때문에 사용하고자 하는 클래스만 지정해서 사용하시기를 권장합니다.


page 디렉티브의 import 속성을 사용해서 사용할 패키지를 지정하게 되면 JSP 페이지에서 해당 클래스를 사용할 수 있게 됩니다. 예제를 통해 선언하는 방법과 사용법을 보도록 하겠습니다.




<%@ page contentType = "text/html; charset=euc-kr" %>

<%@ page import = "java.util.Calendar" %>  // import 속성을 사용하여 java.util.Calendar 클래스를 사용한다고 지정

<html>

<head><title>Calendar 클래스 사용방법</title></head>

<body>

<%

    Calendar cal = Calendar.getInstance();  // 현재 날짜 및 시간 정보를 갖고 있는 Calendar 클래스의 인스턴스를 생성

%>

오늘은

    <%= cal.get(Calendar.YEAR) %>년

    <%= cal.get(Calendar.MONTH)  +1 %> 월  // Calendar.MONTH 의 리턴값은 0부터 시작하기 때문에 반드시 +1 을 해줘야 제대로 표현됨

    <%= cal.get(Calendar.DATE) %> 일

입니다.

</body>

</html>


실행을 해보면 현재 사용하시는 컴퓨터의 날짜가 나오게 될것입니다.


지금까지 page 디렉티브에 대해서 알아보았습니다.


이해가 안되시거나 궁금하신점은 댓글 남겨주시기 바랍니다.^^



Posted by 정윤문경아빠