2011년 8월 31일 수요일
Android - Spinner 예제
Spinner - Android 에서 사용하는 콤보 박스
사용 예는 아래와 같다.
gradeList = new ArrayList<String>();
gradeList.add("");
gradeList.add("SUN");
gradeList.add("MON");
gradeList.add("TUE");
gradeList.add("WED");
gradeList.add("THU");
gradeList.add("FRI");
gradeList.add("SAT");
ArrayAdapter<String> arrayAdapterGrade = new ArrayAdapter<String>(context, android.R.layout.simple_spinner_item, gradeList);
arrayAdapterGrade.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spnrGrade.setPromptId(R.string.grade);
spnrGrade.setAdapter(arrayAdapterGrade);
(spnrGrade : Spinner)
현재 요일을 자동으로 선택하고 싶다면 아래 코드를 추가 하면 된다.
Calendar c = Calendar.getInstance();
position = c.get(Calendar.DAY_OF_WEEK) // 일요일 - 1, 월요일 - 2, 화요일 - 3 ...
spnrGrade.setSelection(position)
위와같이 setSelection(int position) 함수를 이용하면 된다.
현재 선택된 item 을 알고 싶으면
String todayIs = gradeList.get(getSelectedItemPosition());
와 같이 getSelectedItemPosition() 함수를 이용하면 된다.
2011년 8월 26일 금요일
Android - EditText 값 입력 제어 (TextWatcher 사용)
TextWatcher
사용 목적
- EditText에 값이 입력되는 경우 입력 값의 유효성을 검증하여 입력할지 말지를 결정 한다거나.
값이 입력될때 무언가를 해주고 싶을때 사용한다.
기타 자세한 설명은...
http://developer.android.com/reference/android/text/TextWatcher.html
를 참고
설명을 보면 알겠지만 TextWatcher 는 interface로 아래 3개의 method를 가지고 있다.
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// TODO Auto-generated method stub
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
}
사용 예는 아래와 같다
EditText et = new EditText();
et.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
Log.w("onTextChanged", s.toString());
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
Log.w("onTextChanged", s.toString());
}
@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
Log.w("onTextChanged", s.toString());
}
});
위와 같이 하면 et 에 값을 입력할때마다 log가 찍힌다.
본인 같은 경우에는 월(month)를 입력받는 EditText를 만들때 사용했다.
1~12월 사이의 숫자만 입력되야 하기 때문에 아래와같이 코딩했다.
TextWatcher를 상속받은 MonthTextWatcher 를 정의하여 제어 함.
//editTextBeginMonth 는 EditText
MonthTextWatcher endWatcher = new MonthTextWatcher(editTextEndMonth);
editTextBeginMonth.addTextChangedListener(beginWatcher);
//month EditText에 12를 초과하는 값이 못들어가게 제어
private class MonthTextWatcher implements TextWatcher{
EditText et;
String beforeText;
public MonthTextWatcher(EditText et){
this.et = et;
}
@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
if(s.toString().length() > 0){
if(Integer.parseInt(s.toString()) > 12){
et.setText(beforeText);
}
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// TODO Auto-generated method stub
beforeText = s.toString();
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
}
}
사용 목적
- EditText에 값이 입력되는 경우 입력 값의 유효성을 검증하여 입력할지 말지를 결정 한다거나.
값이 입력될때 무언가를 해주고 싶을때 사용한다.
기타 자세한 설명은...
http://developer.android.com/reference/android/text/TextWatcher.html
를 참고
설명을 보면 알겠지만 TextWatcher 는 interface로 아래 3개의 method를 가지고 있다.
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// TODO Auto-generated method stub
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
}
사용 예는 아래와 같다
EditText et = new EditText();
et.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
Log.w("onTextChanged", s.toString());
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
Log.w("onTextChanged", s.toString());
}
@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
Log.w("onTextChanged", s.toString());
}
});
위와 같이 하면 et 에 값을 입력할때마다 log가 찍힌다.
본인 같은 경우에는 월(month)를 입력받는 EditText를 만들때 사용했다.
1~12월 사이의 숫자만 입력되야 하기 때문에 아래와같이 코딩했다.
TextWatcher를 상속받은 MonthTextWatcher 를 정의하여 제어 함.
//editTextBeginMonth 는 EditText
MonthTextWatcher endWatcher = new MonthTextWatcher(editTextEndMonth);
editTextBeginMonth.addTextChangedListener(beginWatcher);
//month EditText에 12를 초과하는 값이 못들어가게 제어
private class MonthTextWatcher implements TextWatcher{
EditText et;
String beforeText;
public MonthTextWatcher(EditText et){
this.et = et;
}
@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
if(s.toString().length() > 0){
if(Integer.parseInt(s.toString()) > 12){
et.setText(beforeText);
}
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// TODO Auto-generated method stub
beforeText = s.toString();
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
}
}
2011년 8월 23일 화요일
2011년 8월 22일 월요일
SQLite - ... has more than one primary key
DB Table ("T_TIMETABLE ") 생성시 에러 발생
table "T_TIMETABLE" has more than one primary key
CREATE TABLE 구문은...
CREATE TABLE IF NOT EXISTS T_TIMETABLE ( subject_id text primary key, day text primary key, begin_tm text primary key, end_tm text primary key )
SQLite 에서 1개 이상의 칼럼을 기본 키로 설정 하고 싶다면
CREATE TABLE 문을 아래와 같이 사용해야 한다.
CREATE TABLE IF NOT EXISTS T_TIMETABLE ( subject_id text, day text, begin_tm text, end_tm text, PRIMARY KEY ( subject_id, day, begin_tm, end_tm) )
table "T_TIMETABLE" has more than one primary key
CREATE TABLE 구문은...
CREATE TABLE IF NOT EXISTS T_TIMETABLE ( subject_id text primary key, day text primary key, begin_tm text primary key, end_tm text primary key )
SQLite 에서 1개 이상의 칼럼을 기본 키로 설정 하고 싶다면
CREATE TABLE 문을 아래와 같이 사용해야 한다.
CREATE TABLE IF NOT EXISTS T_TIMETABLE ( subject_id text, day text, begin_tm text, end_tm text, PRIMARY KEY ( subject_id, day, begin_tm, end_tm) )
Android - Can't upgrade read-only database from version...
아무 문제가 없을거라고 생각했던 프로그램에서 에러가 났다
내가 한거라고는 그냥 DB Table 생성하는 부분만 코딩했을 뿐인데...
에러 내용은
android.database.sqlite.SQLiteException: Can't upgrade read-only database from version 0 to 1: /data/data/....
원인은...
잘못된 CREATE 문 때문이었다.
CREATE TABLE IF NOT EXISTS T_CONFIG ( config_id text primary key, values text, description text, opt1 text, opt2 text, opt3 text )
SQLite에서 values 라는 칼럼명은 허용이 안된다는걸 알게 되었다.
ps .
아래와 같이 수정하니 에러가 사라졌다.
CREATE TABLE IF NOT EXISTS T_CONFIG ( config_id text primary key, vals text, description text, opt1 text, opt2 text, opt3 text )
내가 한거라고는 그냥 DB Table 생성하는 부분만 코딩했을 뿐인데...
에러 내용은
android.database.sqlite.SQLiteException: Can't upgrade read-only database from version 0 to 1: /data/data/....
원인은...
잘못된 CREATE 문 때문이었다.
CREATE TABLE IF NOT EXISTS T_CONFIG ( config_id text primary key, values text, description text, opt1 text, opt2 text, opt3 text )
SQLite에서 values 라는 칼럼명은 허용이 안된다는걸 알게 되었다.
ps .
아래와 같이 수정하니 에러가 사라졌다.
CREATE TABLE IF NOT EXISTS T_CONFIG ( config_id text primary key, vals text, description text, opt1 text, opt2 text, opt3 text )
2011년 8월 10일 수요일
Java - Singleton (Design Pattern)
어떤 시스템에 단 한개의 인스턴스만 존재하는경우 사용
음.... 어떤 시스템의 테마나 설정값 같은경우 서로다른 화면마다 공통된 값을 적용해야 한다.
이럴때 사용하면 좋은게 싱글톤(Singleton) 패턴 이다.
기본적인 구조는...
public class Theme{
private static Theme theme = new Theme();
public static Theme getInstance(){
return theme;
}
}
이렇게 설정 클래스 정의하고 아래와 같이 사용하면 된다.
public class Main{
public static void main(String[] args){
Theme t1 = Theme.getInstance();
Theme t2 = Theme.getInstance();
}
}
위에서의 t1, t2는 서로 동일한 객체 이다.
이와같이 Singleton을 사용하여 동일한 객체를 아무데서나 사용 할 수 있다.
불필요한 작업없이 공통적으로 사용될 설정값, 데이터set 등을 싱글톤으로 정의하고 사용하면 편할듯 하다...
2011년 8월 1일 월요일
Android - Custom View 에 xml 로 속성 부여하기, CUSTOM BUTTON
목적
사용자가 정의한 cutom view를 layout xml에서 정의해서 사용할 경우
사용자가 정의한 custom view의 속성에 값을 layout xml 파일에서 설정 할 수 있다.
(음.. 설명이 어렵군..)
예)
ImageButton이 맘에 들지 않아 ImageView를 상속받은 custom button을 만들려고 한다.
다른부분은 별다른 수정없이 사용 가능하지만
ACTION_DOWN, ACTION_UP 시 이미지를 변화시키는 로직을 custom button 안에 구현하고 싶다.
그러기 위해서 custom view 클래스는 평상시 icon과 눌려졌을때(ACTION_DOWN) icon 에 대한 속성값을 가지고 있어야 하고
이 속성들을 이용해서 onTouchListener를 구성해주면 된다.
위에서 언급한 icon들을 class 파일에서 설정해 줄 수 있지만
왠지 코드가 지저분해지는거 같아 layout xml파일에서 해당 속성을 입력해주고싶다.
뭐 이런 상황에서 사용하는 방법이다.
간단하게 설명하면,
추가할 속성값들을 새로운 xml 파일로 정의하고, 정의된 xml 파일을 layout의 namespace에 추가해서 사용하는 형태인데
이것도 말로 하면 복잡하니까 예를 들어 설명하면
1. res/values/attr.xml - 신규작성 : 신규 속성을 정의할 xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomImageButton">
<attr name="icon" format="integer" />
<attr name="icon_selected" format="integer" />
</declare-styleable>
</resources>
2. CustomImageButton.java - custom button 클래스
package jh;
import jh.R;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
public class CustomImageButton extends ImageView{
private Drawable icon;
private Drawable iconSelected;
public CustomImageButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setTouchEvent();
setIcons(context, attrs);
// TODO Auto-generated constructor stub
}
public CustomImageButton(Context context, AttributeSet attrs) {
super(context, attrs);
setTouchEvent();
setIcons(context, attrs);
// TODO Auto-generated constructor stub
}
public CustomImageButton(Context context) {
super(context);
setTouchEvent();
// TODO Auto-generated constructor stub
}
private void setIcons(Context context, AttributeSet attrs){
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomImageButton);
icon = a.getDrawable(R.styleable.CustomImageButton_icon);
iconSelected = a.getDrawable(R.styleable.CustomImageButton_icon_selected);
}
private void setIconNormal(){
if (icon != null) {
this.setImageDrawable(icon);
}
}
private void setIconSelected(){
if (iconSelected != null) {
this.setImageDrawable(iconSelected);
}
}
private void setTouchEvent(){
this.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
if (event.getAction() == MotionEvent.ACTION_DOWN){
setIconSelected();
}else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_OUTSIDE){
setIconNormal();
}
return false;
}
});
}
}
3. res/layout/subject.xml - layout 파일
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/jh"
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:background="#fffbfbfb">
<LinearLayout
android:id="@+id/contentLayout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
>
<LinearLayout android:layout_height="wrap_content" android:id="@+id/linearLayout2" android:layout_width="match_parent">
<Spinner android:layout_height="wrap_content" android:id="@+id/spinner1" android:layout_weight="1" android:layout_width="wrap_content"></Spinner>
<jh.project.whomli.school.custom.CustomImageButton app:icon="@drawable/utilicon_add" app:icon_selected="@drawable/utilicon_add_selected" android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/subjectBtnAdd" android:src="@drawable/utilicon_add" android:layout_weight="0" android:clickable="true"></jh.project.whomli.school.custom.CustomImageButton>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
뭐 이런식으로 사용하면 된다.
뭔가 단순하면서도 유용할듯하다.
사용자가 정의한 cutom view를 layout xml에서 정의해서 사용할 경우
사용자가 정의한 custom view의 속성에 값을 layout xml 파일에서 설정 할 수 있다.
(음.. 설명이 어렵군..)
예)
ImageButton이 맘에 들지 않아 ImageView를 상속받은 custom button을 만들려고 한다.
다른부분은 별다른 수정없이 사용 가능하지만
ACTION_DOWN, ACTION_UP 시 이미지를 변화시키는 로직을 custom button 안에 구현하고 싶다.
그러기 위해서 custom view 클래스는 평상시 icon과 눌려졌을때(ACTION_DOWN) icon 에 대한 속성값을 가지고 있어야 하고
이 속성들을 이용해서 onTouchListener를 구성해주면 된다.
위에서 언급한 icon들을 class 파일에서 설정해 줄 수 있지만
왠지 코드가 지저분해지는거 같아 layout xml파일에서 해당 속성을 입력해주고싶다.
뭐 이런 상황에서 사용하는 방법이다.
간단하게 설명하면,
추가할 속성값들을 새로운 xml 파일로 정의하고, 정의된 xml 파일을 layout의 namespace에 추가해서 사용하는 형태인데
이것도 말로 하면 복잡하니까 예를 들어 설명하면
1. res/values/attr.xml - 신규작성 : 신규 속성을 정의할 xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomImageButton">
<attr name="icon" format="integer" />
<attr name="icon_selected" format="integer" />
</declare-styleable>
</resources>
2. CustomImageButton.java - custom button 클래스
package jh;
import jh.R;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
public class CustomImageButton extends ImageView{
private Drawable icon;
private Drawable iconSelected;
public CustomImageButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setTouchEvent();
setIcons(context, attrs);
// TODO Auto-generated constructor stub
}
public CustomImageButton(Context context, AttributeSet attrs) {
super(context, attrs);
setTouchEvent();
setIcons(context, attrs);
// TODO Auto-generated constructor stub
}
public CustomImageButton(Context context) {
super(context);
setTouchEvent();
// TODO Auto-generated constructor stub
}
private void setIcons(Context context, AttributeSet attrs){
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomImageButton);
icon = a.getDrawable(R.styleable.CustomImageButton_icon);
iconSelected = a.getDrawable(R.styleable.CustomImageButton_icon_selected);
}
private void setIconNormal(){
if (icon != null) {
this.setImageDrawable(icon);
}
}
private void setIconSelected(){
if (iconSelected != null) {
this.setImageDrawable(iconSelected);
}
}
private void setTouchEvent(){
this.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
if (event.getAction() == MotionEvent.ACTION_DOWN){
setIconSelected();
}else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_OUTSIDE){
setIconNormal();
}
return false;
}
});
}
}
3. res/layout/subject.xml - layout 파일
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/jh"
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:background="#fffbfbfb">
<LinearLayout
android:id="@+id/contentLayout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
>
<LinearLayout android:layout_height="wrap_content" android:id="@+id/linearLayout2" android:layout_width="match_parent">
<Spinner android:layout_height="wrap_content" android:id="@+id/spinner1" android:layout_weight="1" android:layout_width="wrap_content"></Spinner>
<jh.project.whomli.school.custom.CustomImageButton app:icon="@drawable/utilicon_add" app:icon_selected="@drawable/utilicon_add_selected" android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/subjectBtnAdd" android:src="@drawable/utilicon_add" android:layout_weight="0" android:clickable="true"></jh.project.whomli.school.custom.CustomImageButton>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
뭐 이런식으로 사용하면 된다.
뭔가 단순하면서도 유용할듯하다.
피드 구독하기:
글 (Atom)