2010/04/30

Ubuntu 10.04 LTS Released!!



우분투 리눅스가 10.04 LTS (Long Time Support) 버전이 공개 되었다.

MS의 IE 종속적인 대한민국 인터넷 환경에서는 크게 어필할 수 없겠지만 그래도 상당히 매력적인 운영체제 인 것 같다.


Ubuntu Homepage

Ubuntu 10.04 LTS Features<

Original Post : http://neodreamer-dev.tistory.com/429

2010/04/29

[Android Dev.] ProgressDialog 사용하기



Android 에서 기본적으로 제공하는 ProgressDialog 를 생성하는 것은 간단하다. 아래의 코드만으로 ProgressDialog 가 생성이 된다.

progDialog1 = new ProgressDialog( this );
progDialog1.setProgressStyle( ProgressDialog.STYLE_HORIZONTAL );
progDialog1.setMessage( "Test" );
progDialog1.setCancelable( true );





하지만 이 ProgressDialog 의 진행상황을 반영하기 위해서는 Thread 를 구현해야 한다. 아직은 java의 Thread를 이해하지 못해서 i티거 님의 블로그에 있는 Android Thread 강좌에서 발췌하여 실행시켜 보았다.

static final int MY_PROGRESS1 = 7;

ProgressDialog progDialog1;

:
:

case R.id.BtnProgress1:
{
showDialog( MY_PROGRESS1 );

new Thread(new Runnable()
{
int nProgress;
@Override
public void run()
{
for(nProgress = 0; nProgress <= 100; ++nProgress )
{
runOnUiThread( new Runnable()
{
public void run()
{
progDialog1.setProgress(nProgress);
}
});

SystemClock.sleep(100);
}

dismissDialog( MY_PROGRESS1 );
}
}).start();
}
break;




Thread 에 대해서는 좀 더 공부를 해 봐야 겠다.<

Original Post : http://neodreamer-dev.tistory.com/428

2010/04/28

[Android Dev.] Custom Dialog 생성하기

Custom Dialog 를 만들어보기위해 Android Developer 사이트의 예제(http://developer.android.com/guide/topics/ui/dialogs.html#CustomDialog)를 사용해 보았는데 에러가 발생하였다.

// Custom Dialog 생성 예제
Context mContext = getApplicationContext();
Dialog dialog = new Dialog( mContext );

dialog.setContentView(R.layout.custom_dialog);
dialog.setTitle("Custom Dialog");

TextView text = (TextView) dialog.findViewById(R.id.text);
text.setText("Hello, this is a custom dialog!");
ImageView image = (ImageView) dialog.findViewById(R.id.image);
image.setImageResource( R.drawable.icon );



에러 발생 화면

에러 발생 화면



이 문제가 발생한 것은 Dialog 생성시 생성자에 Context 를 넘겨 주도록 되어 있는데 예제에서는 getApplicationContext() 를 호출하여 Context를 가져와서 넘겨 주었는데 이 부분에 문제가 있어 보인다. Dialog 생성자 호출 부분을 this 로 넘겨주면 에러가 발생하지 않고 Dialog가 생성이 되었다.



Custom Dialog 생성에 사용한 xml layout 리소스

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Button
android:text="@+id/Button01"
android:id="@+id/Button01"
android:layout_height="wrap_content"
android:layout_width="fill_parent"/>
<TextView
android:text="@+id/TextView01"
android:id="@+id/TextView01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<EditText
android:text="@+id/EditText01"
android:id="@+id/EditText01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>



//Context mContext = getApplicationContext();
Dialog dialog = new Dialog( this );

dialog.setContentView( R.layout.mydialog );
dialog.setTitle( "MyDialog 1" );

Button btnMyDlg = (Button)dialog.findViewById( R.id.Button01 );
btnMyDlg.setText( "My Button on Custom Dialog" );

dialog.show();





Android 의 Dialog 는 Title 영역과 View 영역으로 나뉘어 지며 Title 영역은 Title 을 지정하지 않아도 사라지지 않고 자리를 차지 한다. 따라서 Titlte 을 지정하지 않을 경우 아래와 같이 아무것도 표시되지 않은 영역이 남아있다.

Title 을 지정하지 않는 Dialog

Title 을 지정하지 않는 Dialog



Title 이 필요없는 경우에는 AlertDialog 를 이용하여 Dialog 를 생성하는 것도 하나의 방법이다.<

Original Post : http://neodreamer-dev.tistory.com/427

2010/04/27

[Android Dev.] 날짜/시각 선택 대화상자 사용하기

Android 에서 기본으로 제공하는 날짜와 시각을 선택하는 대화상자를 사용하는 예이다.



날짜선택 대화상자(DatePickerDialog)와 시각선택 대화상자(TimePickerDialog) 는 해당 다이얼로그 생성해서 보여주기만 하면 되는데 이때 사용자가 설정한 날짜나 시각을 반영하기 위해서는 약간의 작업이 필요하다.



두 대화상자의 호출은 크게 차이가 없다. 차이가 있다면 다루는 데이터가 차이가 있어 나타나는 것이다. 대화상자를 생성할 때 사용자가 Set 버튼을 누를때 발생할 이벤트를 처리할 Callback 함수를 지정하여 처리하면 된다.


날짜 및 시각 선택 대화상자 호출 버튼

날짜 및 시각 선택 대화상자 호출 버튼

날짜 선택 대화상자

날짜 선택 대화상자

날짜 선택 대화상자

선택된 날짜 처리 화면




DatePickerDialog 생성자


public  DatePickerDialog  (Context  context,



DatePickerDialog.OnDateSetListener  callBack,


int year, int monthOfYear, int dayOfMonth)







Parameter



context : 선택 대화상자가 실행 될 Context (보통 Activity)



callBack : 사용자가 Set 버튼을 선택 했을 때 처리할 Callback 함수



year : 초기 년도



monthOfYear : 초기 월



dayOfMonth : 초기 날짜





DatePickerDialog 대화 상자를 생성할 때 넘겨주는 Callback 함수는 DatePickerDialog.OnDateSetListener 로 아래와 같은 형태를 하고 있다.



public abstract void  onDateSet  (DatePicker  view,



int year, int monthOfYear, int dayOfMonth)







Parameters



view : The view associated with this listener.



year : 선택된 년도.



monthOfYear : 선택된 월 (0-11)



dayOfMonth : 선택 한 날짜






날짜 및 시각 선택 대화상자 호출 버튼

날짜 및 시각 선택 대화상자 호출 버튼

시각 선택 대화상자

시각 선택 대화상자

시각 선택 대화상자

선택된 시각 설정 화면




TimePickerDialog 생성자



public  TimePickerDialog  (Context  context,



TimePickerDialog.OnTimeSetListener  callBack,
int hourOfDay, int minute, boolean is24HourView)







Parameters



context : 선택 대화상자가 실행 될 Context (보통 Activity)


callBack : 사용자가 Set 버튼을 선택 했을 때 처리할 Callback 함수



hourOfDay : 초기 시간



minute : 초기 분



is24HourView : 24시간 사용 여부





TimePickerDialog 대화 상자를 생성할 때 넘겨주는 Callback 함수는TimePickerDialog.OnTimeSetListener 로 아래와 같은 형태를 하고 있다.



public abstract void  onTimeSet  (TimePicker  view, int hourOfDay, int minute)







Parameters



view : The view associated with this listener.



hourOfDay : 선택 된 시각의 시



minute : 선택 된 시각의 분






TextView tvDate;
Button btnDate;
TextView tvTime;
Button btnTime;

Calendar calDateTime = Calendar.getInstance();

// Date Set Listener
DatePickerDialog.OnDateSetListener dateSetListener =
new DatePickerDialog.OnDateSetListener()
{
@Override
public void onDateSet( DatePicker view, int year, int monthOfYear,
int dayOfMonth )
{
calDateTime.set( Calendar.YEAR, year );
calDateTime.set( Calendar.MONTH, monthOfYear );
calDateTime.set( Calendar.DAY_OF_MONTH, dayOfMonth );

String strDate;
strDate =
Integer.toString( year ) + "/" +
Integer.toString( monthOfYear ) + "/" +
Integer.toString( dayOfMonth );
tvDate.setText( strDate );
}
};

// Time Set Listener
TimePickerDialog.OnTimeSetListener timeSetListener =
new TimePickerDialog.OnTimeSetListener()
{
@Override
public void onTimeSet( TimePicker view, int hourOfDay, int minute )
{
calDateTime.set( Calendar.HOUR_OF_DAY, hourOfDay );
calDateTime.set( Calendar.MINUTE, minute );

String strTime;
strTime =
Integer.toString( hourOfDay ) + ":" +
Integer.toString( minute );
tvTime.setText( strTime );
}
};

:
tvDate = (TextView)findViewById( R.id.TVDate );
btnDate = (Button)findViewById( R.id.BtnDate );
btnDate.setOnClickListener( this );
tvTime = (TextView)findViewById( R.id.TVTime );
btnTime = (Button)findViewById( R.id.BtnTime );
btnTime.setOnClickListener( this );
:
case R.id.BtnDate:
{
// Call Date Picker
new DatePickerDialog(
MyDialog.this,
dateSetListener,
calDateTime.get( Calendar.YEAR ),
calDateTime.get( Calendar.MONTH ),
calDateTime.get( Calendar.DAY_OF_MONTH )
).show();
}
break;

case R.id.BtnTime:
{
// Call Time Picker
new TimePickerDialog(
MyDialog.this,
timeSetListener,
calDateTime.get( Calendar.HOUR ),
calDateTime.get( Calendar.MINUTE ),
true
).show();
}
break;
}
:

Original Post : http://neodreamer-dev.tistory.com/426

VisualSVN 2.0.1 / VisualSVN Server 2.1.2 Released

VisualSVN 과 VisualSVN Server 이 업그레이드 되었다.


VisualSVN 2.0.1



VisualSVN 2.0.1

2.0 에서 바뀐 사항

  • Updated to Subversion 1.6.11. For further details please see

    http://svn.apache.org/repos/asf/subversion/tags/1.6.11/CHANGES

  • Modeling projects are supported in Visual Studio 2010.

VisualSVN




VisualSVN Server 2.1.2



2.1.1 에서 바뀐사항

  • Updated to Subversion 1.6.11. For further details please see

    http://svn.apache.org/repos/asf/subversion/tags/1.6.11/CHANGES

  • Disallow installation on servers with non-ASCII hostnames.

  • Generate Apache config in the UTF-8 encoding.


VisualSVN Server

<

Original Post : http://neodreamer-dev.tistory.com/425

2010/04/26

[Android Dev.] Tab 사용하기 - 동적으로 Tab 추가하기

아래 코드는 XML 리소스에서 탭을 구성하는 것이 아니고 필요에 따라 코드로 탭을 동적으로 추가하는 내용이다.

동적으로 Tab 을 추가 하기위해서는 TabHost.TabContentFactory() 이용해 Content를 생성한다.






main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TabHost
android:id="@+id/tabHost"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingTop="69px"
>
<LinearLayout
android:id="@+id/BtnLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<Button
android:id="@+id/BtnLinearLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Linear Layout"/>
<Button
android:id="@+id/BtnRelativeLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Relative Layout"/>
<Button
android:id="@+id/BtnTableLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Table Layout"/>
</LinearLayout>
</FrameLayout>
</TabHost>
</LinearLayout>


TabHost 생성 및 Tab 추가 코드

setContentView( R.layout.main_dynamic_tab );

// Tab Host 객체 생성 - 다른 객체의 멤버 함수에서 사용하기 위해 final 키워드 이용
final TabHost tabHost = (TabHost)findViewById( R.id.tabHost );

// TabHost 를 findViewById 로 생성한 후 Tab 추가 전에 꼭 실행해 주어야 함.
tabHost.setup();

// 새로운 Tab 을 생성하기 위한 Tab 객체 생성
TabHost.TabSpec spec;

// 첫 번째 Tab 설정 및 등록
spec = tabHost.newTabSpec( "Tab 00" ); // 새 Tab 생성
spec.setIndicator("Layouts", getResources().getDrawable(R.drawable.icon) ); // Tab 제목, 아이콘
spec.setContent(R.id.BtnLayout); // Tab 내용
tabHost.addTab( spec ); // 생성 된 Tab 등록

// 첫 번째 탭을 활성화
tabHost.setCurrentTab( 0 );

// Linear Layout
Button btnAddLinearLayout = (Button)findViewById( R.id.BtnLinearLayout );
btnAddLinearLayout.setOnClickListener( new OnClickListener()
{
@Override
public void onClick(View v)
{
for ( int view = 0; view < tabHost.getChildCount(); ++view )
{

}

TabHost.TabSpec spec = tabHost.newTabSpec( "Linear Layout" );

spec.setIndicator( "Linear" );
spec.setContent( new TabHost.TabContentFactory()
{
@Override
public View createTabContent(String tag)
{
LinearLayout linear = new LinearLayout( MyLayout.this );
linear.setOrientation( LinearLayout.VERTICAL );
linear.setId( MY_LINEARLAYOUT_VIEW );

LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT );

linear.setLayoutParams( param );

// EditText
EditText etName = new EditText( MyLayout.this );
etName.setText( "Input your name here!!" );
linear.addView( etName );

// First Button
Button btn = new Button( MyLayout.this );
btn.setText( "First Added Button" );
linear.addView( btn, param );

// Second Button
btn = new Button( MyLayout.this );
btn.setText( "Second Added Button" );
linear.addView( btn, new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT ) );

// TextView
TextView tvHello = new TextView( MyLayout.this );
tvHello.setText( "Hello! Linear layout!!" );
tvHello.setGravity( Gravity.CENTER );
linear.addView( tvHello );

// Third Button
btn = new Button( MyLayout.this );
btn.setText( "Third Added Button" );
linear.addView( btn, param );

return linear;
}
});

tabHost.addTab( spec );
}
});

<

Original Post : http://neodreamer-dev.tistory.com/424

2010/04/24

Visual Studio 를 위한 SVN Plug-in : AnkhSVN 2.1



Visual Studio 에서 SVN 관리를 도와주는 AnkhSVN 이 2.1 버전으로 업그레이드 되었다. 변경 기록을 보니 Visual Studio 2010버전을 지원하면서 부터 버전을 올린 것 같다.



AnkhSVN 홈페이지

AnkhSVN Screenshot

AnkhSVN Daily update<

Original Post : http://neodreamer-dev.tistory.com/422

2010/04/23

[Android Dev.] Tab 사용하기 - TabWidget 에 View 올리기

TabWidget 의 탭 타이틀을 설정하는 setIndicator 함수는 View 을 매개변수로 받는 함수도 존재 한다. 따라서 View 를 구성하여 Tab의 타이틀에 올릴 수 있다.



TabWidget 에 올려질 View 를 구성한 XML 리소스

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/IVIcon"
android:src="@drawable/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
/>
<TextView
android:id="@+id/TVCaption"
android:text="Caption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
/>
</LinearLayout>




TabWidget 에 View 를 올리는 소스

TabHost tabHost = (TabHost)findViewById( R.id.tabHost );

// TabHost 를 findViewById 로 생성한 후 Tab 추가 전에 꼭 실행해 주어야 함.
tabHost.setup();

// 새로운 Tab 을 생성하기 위한 Tab 객체 생성
TabHost.TabSpec spec;

// Custom View for TabWidget
LayoutInflater layout = getLayoutInflater();

// 첫 번째 Tab 설정 및 등록
spec = tabHost.newTabSpec( "Tab 00" ); // 새 Tab 생성
View vTab1 = layout.inflate( R.layout.mytabwidget, null );
TextView tvCaption = (TextView)vTab1.findViewById( R.id.TVCaption );
tvCaption.setText( "Custom Tab 1" );
spec.setIndicator( vTab1 ); // Tab 제목
spec.setContent(R.id.layout); // Tab 내용
tabHost.addTab( spec ); // 생성 된 Tab 등록

// 두 번째 Tab 설정 및 등록
spec = tabHost.newTabSpec( "Tab 01" ); // 새 Tab 생성
View vTab2 = layout.inflate( R.layout.mytabwidget, null );
tvCaption = (TextView)vTab2.findViewById( R.id.TVCaption );
tvCaption.setText( "Custom Tab 2" );
spec.setIndicator( vTab2 ); // Tab 제목
spec.setContent( R.id.btnClickme ); // Tab 내용
tabHost.addTab( spec ); // 생성 된 Tab 등록

// 첫 번째 탭을 활성화
tabHost.setCurrentTab( 0 );




Custom View 를 올릴 경우 선택된 탭과 선택되지 않는 탭의 구분이 모호해 지는 경우가 있는데 이 부분에 대한 처리는 좀더 공부를 해 봐야 겠다.<

Original Post : http://neodreamer-dev.tistory.com/421

[Android Dev.] Tab 사용하기 - TabWidget 높이

Tab을 구성하는 TabWidget 의 높이를 설정하기 위해서는 XML 리소스의 TabWidget 의 android:layout_height 속성에 높이를 지정을 하면 된다. 하지만 이 속성에 값을 부여하는 것 만으로 원하는 결과를 얻을 수 없었다.

<!-- TabWidget 의 높이는 40px 로 설정한 경우 -->
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="40px"
/>

<!-- TabWidget 의 높이는 100px 로 설정한 경우 -->
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="100px"
/>




android:layout_height=

android:layout_height="40px"

android:layout_height=

android:layout_height="100px"




높이를 69px 보다 작게하면 텍스트 영역이 사라지고 크게 하면 텍스트 아래쪽에 잉여 영역이 생기게 된다.



그래서 알아 본 정보로는 코드로 높이를 제어하는 방법이다. 아래 코드는 TabWidget 의 구성 탭을 탐색해서 높이를 바꾸는 코드이다.

for ( int tab = 0; tab < tabHost.getTabWidget().getChildCount(); ++tab )
{
tabHost.getTabWidget().getChildAt(tab).getLayoutParams().height = 100;
}



height = 40 인 경우

height = 40 인 경우

height = 100 인 경우

height = 100 인 경우



코드로 제어를 할 경우 잘리거나 잉여 영역이 생성되는 걸 피할 수 있다.

<

Original Post : http://neodreamer-dev.tistory.com/420

2010/04/22

[Android Dev.] Tab 사용하기 - TabActivity

Tab 을 구성하기위해 TabActivity를 상속받아 Tab을 구성 하였다.





main.xml

<?xml version="1.0" encoding="utf-8"?> 
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:id="@+id/TabView1"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
</LinearLayout>
<LinearLayout
android:id="@+id/TabView2"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
</LinearLayout>
<TextView
android:id="@+id/TabView3"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="TabView3"
/>
</FrameLayout>
</LinearLayout>
</TabHost>




java 소스

package com.neodreamer.MyTab;

import android.app.TabActivity;
import android.os.Bundle;
import android.widget.TabHost;

public class MyTab extends TabActivity
{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

TabHost tabHost = getTabHost();

TabHost.TabSpec spec;

// 첫 번째 탭
spec = tabHost.newTabSpec( "Tab 01" );
spec.setIndicator( "Tab 01",
getResources().getDrawable( R.drawable.icon ) );
spec.setContent( R.id.TabView1 );
tabHost.addTab( spec );

// 두 번째 탭
spec = tabHost.newTabSpec( "Tab 02" );
spec.setIndicator( "Tab 02" );
spec.setContent( R.id.TabView2 );
tabHost.addTab( spec );

// 세 번째 탭
spec = tabHost.newTabSpec( "Tab 03" );
spec.setIndicator( "Tab 03" );
spec.setContent( R.id.TabView3 );
tabHost.addTab( spec );

tabHost.setCurrentTab( 0 );
}
}
<

Original Post : http://neodreamer-dev.tistory.com/419

[Android Dev.] Tab 사용하기 - TabWidget 과 FrameLayout 구성

TabHost 에 포함되는 TabWidget 와 FrameLayout 은 TabHost 컨테이너에 포함되는 구성 요소이지만 그려지는 원점이 서로 같아서 항상 TabWidget 의 높이를 FrameLayout의 paddingTop 으로 설정을 해 주야 한다.

FrameLayout 의 paddingTop 이 설정되지 않은 경우

FrameLayout 의 paddingTop 이 설정되지 않은 경우



하지만 이러한 과정은 항상 TabWidget 의 높이를 확인해서 FrameLayout 의 paddingTop을 설정해 주어야 하기에 불편함이 있다. 이를 쉽게 해소하기 위해서는 TabHost 안에 구성되는 TabWidget 와 FrameLayout 을 LinearLayout 컨테이너에 포함시켜 구성하면 쉽게 해결할 수 있다.

LinearLayout 컨테이너에 TabWidget 과 FrameLayout 을 담은 경우

LinearLayout 컨테이너에 TabWidget 과 FrameLayout 을 담은 경우



TabWidget 와 FrameLayout을 padding 으로 구성하는 경우

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TabHost
android:id="@+id/tabHost"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout
android:id="@+id/layout"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<AnalogClock
android:id="@+id/clockAnalog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
/>
<DigitalClock
android:id="@+id/clockDigital"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
/>
</LinearLayout>
<Button
android:id="@+id/btnClickme"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="The Button.\nClick me!"
/>
</FrameLayout>
</TabHost>
</LinearLayout>





TabWidget 와 FrameLayout을 으로 LinearLayout 으로 구성하는 경우

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TabHost
android:id="@+id/tabHost"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout
android:id="@+id/layout"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<AnalogClock
android:id="@+id/clockAnalog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
/>
<DigitalClock
android:id="@+id/clockDigital"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
/>
</LinearLayout>
<Button
android:id="@+id/btnClickme"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="The Button.\nClick me!"
/>
</FrameLayout>
</LinearLayout>
</TabHost>
</LinearLayout>

Original Post : http://neodreamer-dev.tistory.com/418

[Android Dev.] Tab 사용하기

Tab 의 구성

Tab 의 구성

Android 의 Tab 은 3가지 요소로 구성되어 있다.


  • Tab Host : 전체 Tab 을 구성하는 Tab Widget 와 FrameLayout 을 포함 하는 컨테이너


  • Tab Widget : Tab 버튼을 담고 있는 컨테이너


  • FrameLayout : Tab 버튼에 따라 보여질 내용을 담고 있는 컨테이너



TabActivity상속 받아 Activity를 구현 할 때(Tab 자체가 Activity의 main 화면일 때) TabHost의 id는 항상 "@android:id/tabhost"로 설정 하여야 한다.



Tab Widget 는 아이콘과 텍스트로 구성이 되는데 ID는 항상 "@android:id/tabs" 이어야 하며 텍스트만으로 구성이 되더라도 최소 높이가 62px 이다.

Tab Widget

Tab Widget



FrameLayout 은 TabHost 에 포함되는 컨테이너로 TabHost 내의 좌상단(0,0)에서 그려지게 되는데 TabHost 의 상단에는 Tab Widget가 표현되고 있어 Tab Widget을 가리게 된다. 따라서 가려지는 일을 피하려면 Tab Widget 높이 만큼 FrameLayout 의 padding-top 을 설정해 주어야 한다.

FrameLayout 의 padding-top 이 0px 인 경우

FrameLayout 의 padding-top 이 0px 인 경우



탭 생성하는 절차


  • findViewById 로 xml 리소스에서 Tab 가져오기

  • setup() 함수 호출

  • TabHost.TabSpec 객체를 활용하여 탭을 구성하고 추가하기

  • 활성화할 Tab 인데스 지정






main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TabHost
android:id="@+id/tabHost"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingTop="0px"
>
<LinearLayout
android:id="@+id/layout"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<AnalogClock
android:id="@+id/clockAnalog"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
/>
<DigitalClock
android:id="@+id/clockDigital"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
/>
</LinearLayout>
<Button
android:id="@+id/btnClickme"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="The Button.\nClick me!"
/>
</FrameLayout>
</TabHost>
</LinearLayout>





java source

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.main);

TabHost tabHost = (TabHost)findViewById( R.id.tabHost );

// TabHost 를 findViewById 로 생성한 후 Tab 추가 전에 꼭 실행해 주어야 함.
tabHost.setup();

// 새로운 Tab 을 생성하기 위한 Tab 객체 생성
TabHost.TabSpec spec;

// 첫 번째 Tab 설정 및 등록
spec = tabHost.newTabSpec( "Tab 00" ); // 새 Tab 생성
spec.setIndicator("Clock"); // Tab 제목
spec.setContent(R.id.layout); // Tab 내용
tabHost.addTab( spec ); // 생성 된 Tab 등록

// 두 번째 Tab 설정 및 등록
spec = tabHost.newTabSpec( "Tab 01" ); // 새 Tab 생성
spec.setIndicator( "Button", getResources().getDrawable(R.drawable.icon) ); // Tab 제목
spec.setContent( R.id.btnClickme ); // Tab 내용
tabHost.addTab( spec ); // 생성 된 Tab 등록

// 첫 번째 탭을 활성화
tabHost.setCurrentTab( 0 );
}
<

Original Post : http://neodreamer-dev.tistory.com/417

안드로이드 운영체제 새버전 Android OS 2.2 (Froyo) 테스트 시작!!



5월 공개로 알려져 있던 Android 의 새 버전이 버전 넘버를 2.2로 달고 테스트 시작되었다고 한다.



이번 버전에서 추가된 사항


  • JIT compiler

  • Free additional RAM

  • OpenGL ES 2.0 enhancements

  • Flash 10.1 support

  • Activation of Color Trackball

  • Enable FM radio


요즘 문제시 되고 있는 내부 메모리의 프로그램 설치 공간 문제에 대한 해결에 대한 내용을 언급 되지 않은 것 같다. 새 버전에서는 Android 의 Core 를 제외한 부가 프로그램이 Market 에 올려져 사용자에 따라 설치할 수 있어 공간이 다소 확보 되었다고는 하지만 그래도 내부 메모리가 몇 백MB 밖에 되지 않을 경우에는 프로그램 설치에 문제가 있을 수 도 있겠다. 루머에 의하면 5월 19일에 공개가 된다고 한다.


Google Begins Testing Android OS 2.2<

Original Post : http://neodreamer-dev.tistory.com/416

2010/04/21

[Android Dev.] Eclipse SVN!! R.java는 안되겠니?

Eclipse 의 Team 메뉴에 있는 Share Project를 이용해서 Project 를 SVN에 업로드를 하면 gen 폴더의 R.java 파일이 SVN 서버에 올라가지 않는다.


R.java는 Android Project 에서 xml 파일을 분석해서 자동으로 생성되는 파일로 프로젝트에 이 파일이 없으면 에러가 난다.


R.java 파일이 SVN서버에 등록이 되지 않는 이유에 대해서 원인을 찾아 보았지만 찾을 수 없었다. (물론 탐색기에서 TortoiseSVN을 이용하면 SVN에 등록이 된다.)


Android Project 에서 R.java 파일은 다른 리소스(.xml) 파일이 있으면 자동으로 생성이 되기 때문에 SVN에 등록이 되지 않는 것 같은데 그러면 bin 폴더 또한 기본적으로 등록이 되지 않아야 할 것 같은데 bin 폴더는 기본적으로 등록이 된다.


여러가지로 이에 대한 문제를 찾아 보았지만 원인을 찾을 수 없었다.


Eclipse 에서 Android Project를 SVN 서버로 등록을 할 때에는 gen 폴더가 등록이 되지 않는 것은 사실이고 여타 다른 설정에서 이러한 사항을 바꿀 수는 없었다. 그래서 우회책을 찾아 보았다.


SVN 에서 프로젝트를 새로 받으면 R.java가 포함되어 있는 gen 폴더가 존재 하지 않아 에러가 발생한다.





이때, Project 메뉴의 Clearn... 명령을 수행하게 되면 프로젝트으 에러가 해소 된다.






SVN을 개인 적인 목적으로 사용하기 때문에 이러한 사항을 안다면 큰 불편함을 모르겠지만 참여하지 않는 프로젝트의 다운로드나 협업에서 프로젝트를 다운받을 경우 항상 Clearn... 명령을 사용해야 하는 것이 불편한 일 일 것이다. 기본적으로 업로드에서 제한 했더라도 사용자가 올릴 수 있는 선택권은 주어져야 하는게 아닌가 하는 생각이 든다.<

Original Post : http://neodreamer-dev.tistory.com/414

2010/04/20

VisualSVN 2.0 Released

Visual Studio 를 위한 SubVersion plug-in 인 VisualSVN 이 2.0으로 업그레이드 되었다. 이번 버전에서 크게 바뀐 점은 Visual Studio 2010 버전을 지원 하는 것과 2003 버전에 대해서는 더이상 지원을 하지 않게 되었다.


2.0 버전에서 바뀐점

  • Support for Visual Studio 2010.

  • Significant overall performance improvements.

  • Alternative shortcuts for navigation between QuickDiff markers: 'Alt+[' and 'Alt+]'

  • Updated to Subversion 1.6.9. For further details please see

    http://svn.apache.org/repos/asf/subversion/tags/1.6.9/CHANGES

  • Updated to Neon 0.29.3.

  • F# projects are supported in Visual Studio 2008.

  • Exe projects are supported.

  • Azure projects are supported.

  • Support for Visual Studio 2003 removed.

  • Support for BerkeleyDB repositories removed.



Visual SVN website<

Original Post : http://neodreamer-dev.tistory.com/413

2010/04/18

TortoiseSVN 1.6.8 released

윈도우즈용 SVN 클라이언트인 TortoiseSVN 이 1.6.8 버전을 공개 하였다.


TortoiseSVN 1.6.8 has been released.


This is a bugfix release/maintenance release, linked with Subversion 1.6.11.

This release also contains several adjustments to make TortoiseSVN work better on Windows 7.




TortoiseSVN Hmepage

TortoiseSVN Download Page<

Original Post : http://neodreamer-dev.tistory.com/412

2010/04/15

[Android Dev.]AlertDialog 활용하기

AlertDialog 는 사용자에게 메세지나 경고를 알리기 위한 기능으로 Android 에서 지원하는 Dialog 이다. Toast 와는 다르게 Dialog 라서 Activity의 Focus를 가져간다.



대부분의 Dialog 는 Activity의 onCreateDialog() 함수에서 생성하는 것을 권장하고 있다. onCreateDialog() 에서 생성된 Dialog 는 Activity 에서 관장하고 있으며 Activity 객체들()을 상속 받는다.

showDialog() 가 호출되면 생성되지 않은 Dialog의 경우 onCreateDialog() 함수에서 생성이 되고 이후에 호출이 되어질 때에는 새로 생성하지 않고 기존 인스턴스를 그대로 이용한다. 다이얼로그가 호출되기 전에 Dialog 에 변화를 주려면 onPrepareDialog() 함수에서 처리 한다. onCreateDialog 에서 생성한 Dialog는 Activity 에서 항상 갖고 있는 객체로 더이상 필요가 없을 경우에는 시스템 시소스 확보를 위해 removeDialog() 를 호출하여 제거해 주는 것이 좋다.



간단하게 사용자에게 경고를 하기 위한 Dialog 라면 시스템이 관리하지 않고 그냥 간단하게 사용하는 것이 리소스 관리 측면에서 더 유용해 보인다.



AlertDialog 는 사용자에게 아주 간단하고 쉽게 경고 메세지를 보여 줄 수 있는 Dialog 이다. 하지만 Custom View 까지 지원하여 아주 많은 것을 표현해 줄 수 있다.



AlertDialog 는 아래의 요소를 갖을 수 있다.


  • Icon

  • Title

  • Message or ListView (두가지를 함께 지원하지 않음)


  • Custom View

  • Button (최대 3개)




Message 를 갖는 AlertDialog

Message 를 갖는 AlertDialog

ListView 를 갖는 AlertDialog

ListView 를 갖는 AlertDialog




AlertDialog 가 갖을 수 있는 모든 요소는 필요 요소가 없다. 모든 요소를 제거하고 AlertDialog 를 호출하면 Activity의 Focus를 가져오고 화면에는 아무것도 표시가 되지 않는다.



AlertDialog 를 생성하는 방법은 AlertDialog.Builder 클래스를 이용하면 된다.



아주 간단한 AlertDialog 생성하기

간단한 AlertDialog

간단한 AlertDialog



AlertDialog alert = new AlertDialog.Builder( this )
.setIcon( R.drawable.icon )
.setTitle( "AlertTitle" )
.setMessage( "AlertMessage" )
.setPositiveButton( "OK", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
}
})
.show();





구성 요소중 Icon 과 Title 을 없애면 두 영역이 사라지지만 Icon 없이 Title 을 지정하면 기본 Icon 이 표시된다.


Icon과 Title을 제거한 AlertDialog

Icon과 Title을 제거한 AlertDialog

Icon 없이 Title 만 지정한 AlertDialog

Icon 없이 Title 만 지정한 AlertDialog






AlertDialog 에서 제공하는 ListView 활용하기

AlertDialog.Builder 에 있는 setSingleChoiceItems 함수를 이용하며 AlertDialog 에서 제공하는 ListView 를 사용할 수 있다.

ListView를 갖는 AlertDialog

ListView를 갖는 AlertDialog



String[] strItems = { "Alert Item 1", "Alert Item 2", "Alert Item 3" };

AlertDialog alert = new AlertDialog.Builder( this )
.setIcon( R.drawable.icon )
.setTitle( "AlertTitle" )
.setPositiveButton( "OK", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
}
})
.setNeutralButton( "Neutral", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{

}
})
.setNegativeButton( "Cancel", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{

}
})
.setSingleChoiceItems(strItems, -1, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
String msg = "";
switch ( which )
{
case 0: msg = "Item 1 Selected"; break;
case 1: msg = "Item 2 Selected"; break;
case 2: msg = "Item 3 Selected"; break;
}
Toast.makeText( MyDialog.this, msg, Toast.LENGTH_SHORT ).show();
}
})
.show();







Custom View 를 얹은 AlertDialog

Custom View 를 얹은 AlertDialog

Custom View 를 얹은 AlertDialog



Custom View XML

<?xml version="1.0" encoding="utf-8"?>
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">

<TableRow>
<ImageView
android:id="@+id/IVIcon1"
android:src="@drawable/icon"
/>
<TextView
android:id="@+id/TVAndroid1"
android:text="Android 1"
/>
</TableRow>

<TableRow>
<ImageView
android:id="@+id/IVIcon1"
android:src="@drawable/icon"
/>
<TextView
android:id="@+id/TVAndroid1"
android:text="Android 1"
/>
</TableRow>
</TableLayout>



LayoutInflater layout2 = getLayoutInflater();
View v2 = layout2.inflate( R.layout.alert_custom_view, null );

AlertDialog alert = new AlertDialog.Builder( this )
.setIcon( R.drawable.icon )
.setTitle( "AlertTitle" )
.setMessage( "AlertMessage" )
.setPositiveButton( "OK", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
}
})
.setNeutralButton( "Neutral", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{

}
})
.setNegativeButton( "Cancel", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{

}
})
.setView( v2 )
.show();





<

Original Post : http://neodreamer-dev.tistory.com/411

2010/04/13

Visual Studio 2010 정식 버전 공개!!

Visual Studio 2010 Packages

Visual Studio 2010 [출처 : Microsoft]



드디어 Visual Studio 2010 버전이 공개가 되었다.

현재 영문 버전만 공개가 되었으며 한글은 6월 경에 공개가 된다고 한다.





얼마전 까지만 해도 DreamSpark 에 2010이 RC 버전이 올라와 있었는데 2010 정식 버전이 공개된 지금 다시 확인해 보니 DreamSpark 에도 정식 버전이 공개가 되었다.





Microsoft Visual Studio 2010 공식 사이트

Microsoft DreamSpark 의 Visual Studio 2010 페이지

Download Visual Studio on MSDN Subscriptions



Visual Studio 2010 공식 팀 블로그에 공개된 Visual Studio 2010 의 특징<

Original Post : http://neodreamer-dev.tistory.com/410

2010/04/12

[Android Dev.]SVN 서버에 안드로이드 프로젝트 쉽게 올리기

이전 글에서 Google Code 의 SVN Hosting 을 이용한 안드로이드 프로젝트 관리에 대한 글을 쓸 때 프로젝트를 SVN 으로 올리는 방법도 언급을 했었은데 그보다 더 쉬운 방법을 찾아서 기록해 본다.


2010/04/11 - [Dev Story/Android] - [Android Dev.]무료 SVN 호스팅 Google Code 를 이용한 코드 관리하기


안드로이드 프로젝트를 생성(TestSVN)을 하였으면 해당 프로젝트에서 마우스 오른쪽 버튼을 눌러 Team 메뉴에서  "Share Project..." 메뉴를 선택한다.

Team 메뉴의 Share Project... 메뉴

Team 메뉴의 Share Project... 메뉴



"Share Project..."를 실행하면 아래와 같이 공유 방법을 선택하는 대화상자가 나오는데 이 대화상자에서 SVN을 선택한다.

프로젝트 공유 방법 설정 대화상자

프로젝트 공유 방법 설정 대화상자



SVN을 선택하면 새로운 Repository 를 생성할 것인지 기존의 Repository 를 이용할 것인지 묻는 대화상자가 나오는데 이 창에서 기존에 등록되어 있는 Repository를 선택하고 다음 단계로 진행을 한다.

Repository 선택 대화상자

Repository 선택 대화상자



다음 단계에서는 Repository 상에서 프로젝트의 위치를 설정하는 대화상자로 간단하게 Simple Mode 에서 설정할 수 있고 확장된 모드에서 상세 설정을 할 수 있다. 간단하게 Simple Mode 에 Repository 의 하위 폴더가 프로젝트 이름(TestSVN)이 있는 것만 확인하고 다음 단계로 넘어 간다.

프로젝트 위치 설정 대화상자

프로젝트 위치 설정 대화상자



다음 단계는 commit 에 대한 comment 를 입력한다.

Commit Comment 대화상자

Commit Comment 대화상자



comment 를 입력하고 "Finish" 버튼을 누르면 SVN 서버로 올려질 프로젝트에 대한 Comment 입력과 구성 파일들이 선택할 수 있는 상태로 나열된 대화 상자가 나오는데 Comment는 생략하거나 프로젝트에 대한 간단한 설명을 입력하고 아래쪽 프로젝트 파일 리스트에서는 bin 폴더에 있는 파일들 및 bin 폴더를 제거한다. bin 폴더에 포함되어 있는 파일은 프로젝트를 Compile 할 때 자동으로 생성이 되므로 굳이 SVN 을 통해서 관리할 필요가 없다.

Comment 및 파일 선택 대화상자

Comment 및 파일 선택 대화상자



프로젝트 구성 파일을 선택하고 "OK"를 누르면 해당 프로젝트가 SVN 서버로 올라가게 된다.

프로젝트 업로드 상황창

프로젝트 업로드 상황창



"SVN Repository" 창에서 Repository 를 Refresh 하면 새로 올려진 TestSVN 프로젝트를 확인할 수
있다.

Repository 상태

Repository 상태

<

Original Post : http://neodreamer-dev.tistory.com/409