컴파일이란?

컴파일 과정

소스파일 + 헤더파일 -> 중간파일(전처리) -> 오브젝트파일(컴파일) -> 실행파일(링킹)

컴파일 옵션

  • I : 헤더파일 위치 지정 옵션, 표준 디렉토리(/usr/include)외에 있는 헤더파일의 디렉토리 경로 지정

  • Dname : name에 지정된 심볼을 1로 정의

  • ON : 컴파일된 코드를 최적화 시키는 옵션

  • L : 라이브러리 파일 이 존재하는 디렉토리 경로 지정

  • l string : 옵션 뒤에 지정한 라이브러리 파일을 지정하여 컴파일 시 링크(단 파일명은 libstring.a 또는 libstring.so)

  • c : 컴파일 단계까지만 수행하고 링크 수행 x 하여 오브젝트파일을 생성

  • g : 실행파일에 표준 디버깅 정보 포함하여 gdb, DDD 등 디비거 이용시 옵션 사용

  • Wall : gcc가 제공하는 모든 경고를 알 수 있다. 시스템 혹은 커널 프로그램 작성 시 이 옵션을 함께 넣어 컴파일 하는 것이 적절.

컴파일 옵션을 이용하여 라이브러리 파일을 링크

#include <stdio.h>
#include <math.h>
 
int main() {
  double dnum = 100.0;
 
  printf("%lf", sqrt(dnum));
 
  return 0;
}

위 코드의 sqrt는 표준 C 라이브러리가 아니라 별도의 math 라이브러리 파일에 들어가 있기 때문에 컴파일 시 함께 링크될 수 있도록 옵션을 추가 해야 한다.

수학 함수 이용시

라이브러리 파일명파일 위치컴파일 시 필요 옵션
libm.a 또는 libm.so/usr/lib 와 /lib-lm
gcc -o test test.c -lm

라이브러리 생성

라이브러리 생성을 하게 되면 동일 기능이 여러 군데 중복되지 않아 효율적인 프로그램 작성을 할 수 있다.

생성 형태

C 컴파일러는 컴파일 시 기본적으로 /usr/lib에 있는 디렉토리에서 라이브러리 함수를 찾아 링크한다.

만약 없다면 -l 혹은 -L 옵션을 이용하여 다른 디렉토리에 있는 라이브러리도 이용 가능하다.

라이브러리의 이름은 lib로 시작하여 .a 나 .so 의 확장자로 구성된다.

정적 라이브러리

프로그램 오브젝트 파일 + 미리 생성한 라이브러리 함수 오브젝트 코드 = 실행 파일

정적 라이브러리 함수를 사용하게 되면 코드 중복을 막을수는 있지만 메모리에 동일한 코드가 존재하게 되어 메모리, 디스크 등이 자원을 효율적으로 사용하지 못하는 단점이 있다.

라이브러리 생성 방법

  1. 소스 파일 생성 vi static.c

  2. 오브젝트 파일 생성(static.o) gcc -c static.c

  3. 라이브러리 파일 생성 ar rv libstatic.a static.o -> ar 도구를 이용하여 static.o 오브젝트를 libstatic.a 라는 정적 라이브러리 파일로 생성

공유 라이브러리

프로그램 오브젝트 코드 + 라이브러리 함수 정보 = 실행 파일

라이브러리 생성 방법

  1. 소스 파일 생성 vi shared.c

  2. 오브젝트 파일 생성 gcc -c -fPIC shared.c -> -c 옵션과 -fPIC 옵션을 이용하여 재배치 가능한 오브젝트 파일 생성

  3. 라이브러리 파일 생성 ld -shared -o libshared.so shared.o -> ld 도구를 이용하여 shared.o 오브젝트를 libshared.so 공유 라이브러리 파일로 생성

라이브러리 작성 예시

//static.c
#include <stdio.h>
 
void static_function(int num) {
    printf("this is static function : %d\n", num);
}
//shared.c
#include <stdio.h>
 
void shared_function(int num1, num2) {
  printf("this is shared function : %d %d\n", num1, num2);
}
//static.h
void static_function(int);
//shared.h
void shared_function(int, int);
//main.c
#include <stdio.h>
#include "static.h"
#include "shared.h"
 
int main() {
    printf("main start.\n");
    static_function(100);
    shared_function(200, 300);
    printf("main end.\n");
    return 0;
}

필요한 파일들을 작성합니다.

$ gcc -c static.c
$ ar rv libstatic.a static.o

정적 라이브러리 파일을 생성합니다.

$ gcc -c -fPIC shared.c
$ ld -shared -o libshared.so shared.o

동적 라이브러리 파일을 생성합니다.

 
$ gcc -o main main.c -L. -lstatic -lshared
 

gcc 옵션을 통해 현재 디렉토리 경로를 지정하고 해당 라이브러리 파일들을 지정합니다.

 
$ ./main
 

실행파일 실행 시 공유 라이브러리를 찾을 수 없다는 오류가 뜨게 됩니다.

 
$ export LD_LIBRARY_PATH = $LD_LIBRARY_PATH:.
 
$ ./main


'Operator System > Linux' 카테고리의 다른 글

쉘 프로그래밍 간단한 문법  (0) 2017.10.26
프로세스와 생성방법  (0) 2017.10.26
Make  (0) 2017.10.26
파일  (0) 2017.10.26
환경변수  (0) 2017.10.26

환경변수

환경변수는 쉘 스크립트나 프로그램 실행을 제어, 실행환경 설정하는데 사용된다.

지역 환경 변수

현재 쉘에만 적용되는 변수, 환경변수명 = 변수

전역 환경 변수

현재 쉘과 자식 쉘에 같이 적용되는 변수, exports 환경변수명 = 변수

환경 변수 해제

unset

환경 변수 확인법

echo, set, env

환경 변수 파일 적용

$ source test_sh_var

대표적인 환경변수로 아래와 같다.

  • HOME : 사용자 홈 디렉토리

  • PATH : 실행파일 탐색 경로

  • LANG : 기본 언어

  • PWD : 사용자 현재 작업 디렉토리

  • TERM : 터미널 타입

  • SHELL : 로그인 쉘

  • BASH : bash 쉘 경로

  • PS1, PS2 : shell prompt 변수

대표적인 환경 변수

환경변수설명
HOME,PATH홈, 경로
$PS1command prompt
$PS2추가적인 입력을 받을 때 사용하는 prompt
$IFSinput field seperator.
$#쉘 스크립트에 전달되는 파라미터 수
$0쉘 스크립트 이름
1,2, $3첫번째, 두번째, 세번째 파라미터
$$쉘 스크립트의 Process Id
$*스크립트의 모든 파라미터를 1개 변수로 표현
$@IFS를 사용하지 않고 $*로 출력한 것
$ IFS=''
$ set foo bar bam
$ echo "$@"
foo bar bam
$ echo "$*"
foobarbam
$ unset IFS
$ echo "$*"
foo bar bam

IFS를 활용한 예제이다.

getenv(), putenv(), environ 변수

#include <stdlib.h>
 
char * getenv(const char * name);
int putenv(const char * string);
 
#include <stdlib.h>
extern char ** environ;

getenv는 환경변수에 설정된 값을 반환한다.

putenv는 "변수명=변수값" 형태의 문자열을 받아 생성한다.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main(int argc, int * argv[]) {
  char * var, * value;
 
  if(argc == 1 || argc > 3) {
    fprintf(stderr, "usage: environ var [value]\n");
    exit(1);
  }
 
  var = argv[1];
  value = getenv(argv[1]);
 
  if(value) {
    printf("Variable %s has value %s\n", var, value);
  }
 
  if(argc == 3) {
    char * string;
    value = argv[2];
    string = malloc(strlen(var) + strlen(value) + 2);
 
    if(!string) {
      fprintf(stderr, "out of memory\n"); exit(1);
    }
 
    strcpy(string, var);
    strcat(string, "=");
    strcat(string, value);
 
    printf("Calling putenv with : %s\n", string);
    if(putenv(string) != 0) {
      fprintf(stderr, "put env failed\n"); free(string); exit(1);
    }
    value = getenv(var);
    if(value) printf("New value of %s is %s\n", var, value);
  }
 
  exit(0);
}

putenv를 활용하기 위해 배열에 "변수명=변수값" 형식으로 저장함을 확인할 수 있다.

#include <stdio.h>
#include <stdlib.h>
 
int main() {
  char * homedir, filename[80];
  FILE * fp;
 
  homedir = getenv("HOME");
  strcpy(filename, homedir);
  strcat(filename, "/test.log");
 
  if((fp = fopen(filename, "w")) == NULL) {
    perror("fopen");
    exit(1);
  }
 
  fwrite("getenv test\n", 12, 1, fp);
  fclose(fp);
 
  return 0;
}

위 예제는 getenv를 통해 HOME 환경변수에 대한 정보를 얻어 경로 조작 후 파일을 생성하는 예제이다.

#include <stdlib.h>
#include <stdio.h>
 
extern char ** environ;
 
int main() {
  char ** env = environ;
 
  while(*env) {
    printf("%s\n", *env);
    env++;
  }
 
  exit(0);
}

environ 변수를 사용해 환경변수와 그 설정값들을 ""변수=값" 형태의 문자열로 저장된 문자열 배열을 가져온다. extern을 사용해 외부 파일에서 참조가 가능하게 해줘야 한다. 실행 결과는 env 명령어를 준 결과와 동일하게 나타난다.

'Operator System > Linux' 카테고리의 다른 글

쉘 프로그래밍 간단한 문법  (0) 2017.10.26
프로세스와 생성방법  (0) 2017.10.26
Make  (0) 2017.10.26
파일  (0) 2017.10.26
Compile과 라이브러리  (0) 2017.10.26

Popup menu

특정 뷰에 고정된 모달 메뉴이다.

@Override
    public void onClick(View view) {
        PopupMenu popup = new PopupMenu(this, view);
 
        MenuInflater inflater = popup.getMenuInflater();
        inflater.inflate(R.menu.actions, popup.getMenu());
 
        popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                if(item.getItemId()==R.id.apple) {
 
                } else if(item.getItemId()==R.id.grape) {
 
                }
                return false;
            }
        });
        popup.show();
    }

해당 위젯 클릭시 PopupMenu 를 생성한다.

'IT > Android' 카테고리의 다른 글

리스트 뷰  (0) 2017.10.31
AlertDialog를 이용하여 RatingBar 띄우기  (0) 2017.10.23
Intent  (0) 2017.10.23
Action Bar  (0) 2017.10.23
Dialog  (0) 2017.10.23

AlertDialog를 이용하여 RatingBar 띄우기

class MyOnLongClickListener implements View.OnLongClickListener {
    @Override
    public boolean onLongClick(View view) {
        if(view.getId()==R.id.button3) {
            showDialog();
            return true;
        }
        return false;
    }
}

LongClick 후에 RatingBar를 띄우기 위해 다음과 리스너를 생성한다.

public void showDialog() {
        final AlertDialog.Builder popDialog = new AlertDialog.Builder(this);
        final RatingBar ratingBar = new RatingBar(this);
        ratingBar.setMax(5);
 
        popDialog.setTitle("RatingBar");
        popDialog.setView(ratingBar);
 
        popDialog.setPositiveButton(android.R.string.ok,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        dialogInterface.dismiss();
                    }
                })
                .setNegativeButton("Cancel",
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                dialogInterface.cancel();
                            }
                        });
 
        popDialog.create();
        popDialog.show();
    }

AlertDialog.Builder에는 AlertDialog에 생성에 필요한 API를 제공하고 있다. setPositiveButton과 setNegativeButton을 이용하여 OK/Cancle 버튼을 버튼을 만든다.

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.actions, menu);
        return true;
    }

onCreateOptionsMenu 함수를 이용하게 되면 코드로 옵션 메뉴를 생성할 수 있다. 하지만 먼저 menu 리소스가 필요하다.

'IT > Android' 카테고리의 다른 글

리스트 뷰  (0) 2017.10.31
Popup Menu 생성  (0) 2017.10.23
Intent  (0) 2017.10.23
Action Bar  (0) 2017.10.23
Dialog  (0) 2017.10.23

Intent

다른 apllication component가 어떤 action을 수행하도록 요청하기 위해 사용되는 메시징 객체.

대표적인 use cases - Activity를 시작 - Service를 시작 - Broadcast를 전달

명시적 인텐트

실행하고자 하는 component의 이름을 명시적으로 지정하여 호출한다. > 같은 앱 내의 다른 액티비티에 접근하고 할 때 명시적 인텐트를 사용한다.

//MainActivity.java
 
Intent intent = new Intent(this, SubActivity.class);
startActivity(intent);

Intent 객체 선언 후 startActivity를 통해 Intent에 명시된 액티비티를 시작한다. 위의 코드에서는 호출한 액티비티로부터 반환값을 받지 않는다.

//MainActivity.java
 
Intent in = new Intent(MainActivity.this, SubActivity.class);
startActivityForResult(in, GET_STRING);

startActivityForResult를 사용하게 되면 호출한 액티비티로부터 반환 값을 받을 수 있다.

//SubActivity.java
 
Intent intent = new Intent();
 
intent.putExtra("key", "value");
 
setResult(RESULT_CANCELED);

호출된 액티비티에서 인텐트에 데이터를 담아 setResult함수를 통해 반환값을 보낼 수 있다.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(requestCode == GET_STRING) {
        if(resultCode == RESULT_OK) {
            text.setText(data.getStringExtra("INPUT_TEXT"));
        } else if(resultCode == RESULT_CANCELED) {
            //
        }
    } else if(requestCode == GET_NUMBER) {
        //
    }
}

onActivityResult를 통해 반환 값을 받을 수 있다.

namevalue
requestCodestartActivityForResult가 호출할 때 넘겨준 코드
resultCode실행이 되어진 액티비티에서 setResult 메소드를 통해 반환되는 코드
data엑스트라 데이터를 담는 Intent 객체

암시적 인텐트

자신이 작성한 어플리케이션이 아닌 다른 어플리케이션의 component를 구동하는데 사용된다.

각 component는 자신이 처리할 수 있는 인텐트의 종류를 인텐트 필터 를 사용하여 안드로이드 운영체제에 알려줘야 한다. > 어떤 앱에서 액티비티나 서비스 등의 component를 외부에 공개하고자 할 때 인텐트 필터를 지정한다. 그렇지 않은 경우에는 인텐트 필터를 지정하지 않으면 된다.(암시적 인텐트 허용 않음)

Intent(String action, Uri uri)
intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://wwww.google.com"));

위와 같이 액션 수행시 필요한 데이터를 Uri 클래스의 객체로 제공한다. > Uri란 어떤 자원에 접근하기 위한 유일한 식별자를 의미. 일반적으로 URL과 URN을 포괄하는 개념으로 URL을 통해 프토토콜, 도메일, 자원의 위치정보를 얻고 URN을 통해 자원의 위치와 무관한 영속적인 유일환 자원의 정보를 얻는다.

if(intent != null) {
  if(intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); }
}

startActivity(intent) 로 암시적 인텐트를 시작한다.  intent.resolveActivity()의 의미는 null이 아닌 경우 처리할 앱이 최소한 하나가 있다는 의미이다.

  • 인텐트 액션 종류

namevalue
ACTION_VIEW데이터를 사용자에게 표시
ACTION_EDIT사용자가 편집할 수 있는 데이터를 표시
ACTION_MAIN태스크의 초기 액티비티로 설정
ACTION_CALL전화 통화 시작
ACTION_SYNC모바일 장치의 데이터를 서버 상의 데이터와 일치시킨다
ACTION_DIAL전화 번호를 누르는 화면을 표시
ACTION_SENDTO이메일 발송
//AndroidManifest.xml
 
<application
     android:allowBackup="true"
     android:icon="@mipmap/ic_launcher"
     android:label="@string/app_name"
     android:supportsRtl="true"
     android:theme="@style/AppTheme">
     <activity android:name=".MainActivity">
         <intent-filter>
             <action android:name="android.intent.action.MAIN" />
 
             <category android:name="android.intent.category.LAUNCHER" />
         </intent-filter>
     </activity>
 
     <activity
        android:name=".SecondActivity"
        android:label="@string/app_name_second">
 
        <intent-filter>
            <action android:name="android.intent.action.SEND"/>
            <category android:name="android.intent.category.DEFAULT"/>
            <data android:mimeType="image/*"
        </intent-filter>
     </activity>
</application>

위의 MainActivity에 설정된 intent-filter는 실행시키는 앱의 메인 시작점이기 때문에 action.MAIN과 category.LAUNCHER가 기본적으로 설정된다.

추가한 SecondActivity를 살펴보자.

기본적으로 인텐트 필터 매칭은 액션 / 카테고리 / 데이터 비교로 이루어진다.

  1. 액션

    • 인텐트 객체에 설정된 액션은 인텐트 필터에 나열된 액션 중 하나와 반드시 일치해야 한다.

  2. 카테고리

    • 인텐트 객체에 포함된 모든 카테고리가 인테트 필터에 나열되어 있어야 한다.

    • startActivity, startActivityForResult 로 전달되는 모든 암시적 인텐트는 android.intent.category.DEFAULT 카테고리에 속하는 것으로 자동 설정한다. -> 암시적 인테트를 받고자 하는 액티비티는 반드시 default category를 포함해야 한다.

  3. 데이터

    • 데이터 타입이나 URI가 지정한 대로 똑같이 매칭이 된 경우에만 통과된다.


'IT > Android' 카테고리의 다른 글

Popup Menu 생성  (0) 2017.10.23
AlertDialog를 이용하여 RatingBar 띄우기  (0) 2017.10.23
Action Bar  (0) 2017.10.23
Dialog  (0) 2017.10.23
context menu  (0) 2017.10.23

Action bar

안드로이드 상단에 출력되는 디자인 요소

아래와 같은 용도로 사용된다.

  • 앱의 아이덴티티를 부여하는 공간 제공 (앱 아이콘, 로고)

  • 검색과같은중요기능을눈에띄게함

  • 앱 내에서 일관된 내비게이션과 뷰 전환을 지원함 - 탭, 드롭다운 메뉴

  • 별로 사용하지 않는 액션을 액션 오버플로우로 제공하여 산만함을 줄임

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.actions, menu);
        return super.onCreateOptionsMenu(menu);
    }
 
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch(item.getItemId()) {
            case R.id.action_refresh:
                Toast.makeText(getApplicationContext(), "refresh", Toast.LENGTH_SHORT).show();
                return true;
            case R.id.action_search:
                Toast.makeText(getApplicationContext(), "search", Toast.LENGTH_SHORT).show();
                return true;
            case R.id.action_settings:
                Toast.makeText(getApplicationContext(), "settings", Toast.LENGTH_SHORT).show();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

onOptionsItemSelected를 사용하여 각 메뉴에 대한 이벤트를 설정한다.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
 
    <item
        android:id="@+id/action_refresh"
        android:title="refresh"
        app:showAsAction="always|withText"
        />
 
    <item
        android:id="@+id/action_search"
        android:title="search"
        app:showAsAction="never"
        />
 
    <item
        android:id="@+id/action_settings"
        android:title="settings"
        app:showAsAction="always"
        />
</menu>

menu 리소스의 xml파일은 위와 같다.

app:showAsAction 옵션을 사용하기 위해 위에 보이는 xmlns:app을 선언해줘야 한다.

각 설정 타입의 내용은 아래와 같다.

name설명
ifRoom액션 아이템을 표시할 수 있는 공간이 있다면 액션 아이템을 표시합니다.
never항상 액션 아이템으로 표시하지 않습니다. (기본값)
withText메뉴 항목의 아이콘과 메뉴 항목의 텍스트를 함께 액션 아이템으로 표시합니다.
always항상 액션 아이템으로 표시합니다.

표시되지 않은 메뉴항목에 대해서는 오른쪽에 오버플로우 메뉴로 합쳐지게 된다.

참고링크 : 커니의 안도로이드 이야기

'IT > Android' 카테고리의 다른 글

Popup Menu 생성  (0) 2017.10.23
AlertDialog를 이용하여 RatingBar 띄우기  (0) 2017.10.23
Intent  (0) 2017.10.23
Dialog  (0) 2017.10.23
context menu  (0) 2017.10.23

Dialog

사용자에게 메시지를 출력하고 사용자로부터 입력을 받는 인터페이스

AlertDialog • DatePickerDialog / TimePickerDialog

AlertDialog

AlertDialog는 Activity 클래스를 이용해서 구현할 수 있다.

public class MainActivity extends AppCompatActivity {
    Button mButton1;
 
    private static final int DIALOG_YES_NO_MESSAGE = 1;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        mButton1 = (Button)findViewById(R.id.button1);
        mButton1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                showDialog(DIALOG_YES_NO_MESSAGE);
            }
        });
    }

showDialog()를 통해 대화상자를 호출한다.

    @Override
    protected Dialog onCreateDialog(int id) {
        switch(id) {
            case DIALOG_YES_NO_MESSAGE:
                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setTitle("메시지")
                        .setMessage("종료하시겠어요?")
                        .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                finish();
                            }
                        })
                        .setNegativeButton("No", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                dialogInterface.dismiss();
                            }
                        });
 
                AlertDialog alert = builder.create();
                return alert;
        }
        return null;
    }
}

onCreateDialog는 showDialog 함수 호출시 호출되는 메소드이다. AlertDialog.Builder를 통해 대화상자를 설정하고 builder.create()를 통해 설정된 값으로 대화상자를 생성한다.

DialogFragment를 이용하여 AlertDialog 구현하기

Activity 클래스를 이용하는 것 외에 DialogFragment를 이용하는 방식이 있다.

public static class ButtonDialogFragment extends DialogFragment {
        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder.setTitle("메시지")
                    .setMessage("종료하시겠어요?")
                    .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            getActivity().finish();
                        }
                    })
                    .setNegativeButton("No", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            dialogInterface.dismiss();
                        }
                    });
 
            return builder.create();
        }
    }

내부적으로 DialogFragment를 상속받는 내부 클래스를 선언하였다.

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
 
//...
 
getActivity().finish();

첫번째 방법과 다른 점은 this 부분이 getActivity()로 바꼇다는 점이다.

mButton1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                DialogFragment dialogFragment = new ButtonDialogFragment();
                dialogFragment.show(getSupportFragmentManager(), "test");
            }
        });

해당 리소스에 리스너를 등록한다. 이 때 getSupportFragmentManager()를 이용하여 FragmentManager를 가져온다.(지원 라이브러리 사용할 경우)

DatePickerDialog

DialogFragment를 이용하여 구현한다.

public static class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener {
        TextView mT;
 
        public void setEditText(TextView et) {
            mT = et;
        }
 
        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            Calendar cal = Calendar.getInstance();
 
            return new DatePickerDialog(getActivity(), this, cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DATE));
        }
 
        @Override
        public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
            mT.setText(year + "/" + (monthOfYear + 1) + "/" + dayOfMonth);
        }
    }

onCreateDialog와 onDateSet 함수를 사용한다.

DatePickerDialog(Context context, DatePickerDialog.OnDateSetListener listener, int year, int month, int dayOfMonth)

Button bt = (Button) findViewById(R.id.button);
 
        // 버튼을 클릭했을 때 대화상자를 표시하도록 처리
        // OnClickListener를 설정(무명클래스로 이벤트 리스너 객체를 생성하는 방식)하고 onClick 메소드 구현
        bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                TextView editText = (TextView) findViewById(R.id.dateText);
 
                DatePickerFragment dpf = new DatePickerFragment();
                dpf.setEditText(editText);
                dpf.show(getFragmentManager(), "datePicker");
            }
        });


'IT > Android' 카테고리의 다른 글

Popup Menu 생성  (0) 2017.10.23
AlertDialog를 이용하여 RatingBar 띄우기  (0) 2017.10.23
Intent  (0) 2017.10.23
Action Bar  (0) 2017.10.23
context menu  (0) 2017.10.23

Context Menu

Context 메뉴란 UI에서 특정한 항목에 영향을 주는 동작을 선택할 수 있는 메뉴를 말한다.

Context 메뉴 생성방법은 크게 2가지가 있는데 floating context menu, context action menu 이다. 각 메뉴 생성방법에 대해 알아보자.

Floating Context Menu

화면을 long click 하면 나타나는 방식이다.

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        mButton1 = (Button)findViewById(R.id.button1);
 
        registerForContextMenu(mButton1);
    }

registerForContextMenu에 해당 위젯을 등록시킨다.

    //floating context menu
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
 
        menu.setHeaderTitle("Context menu");
        menu.add(0, 1, 0, "apple");
        menu.add(0, 2, 0, "grape");
    }

onCreateContextMenu는 Context 메뉴를 보여줘야 할 시점에 호출된다.

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case 1:
                return true;
            case 2:
                return true;
            default:
                return super.onContextItemSelected(item);
        }
    }

onContextItemSelected는 메뉴 이벤트 처리함수이다.

Context Action Mode

Context Action Mode를 구현하기 위해서는 View.OnLongClickListener, ActionMode.Callback 인터페이스르 구현해야 한다.

ActionMode 인터페이스를 구현하기 위해서는 아래의 4개의 메소드를 오버라이딩 해야 한다.

  ActionMode mActionMode;
 
    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        MenuInflater inflater = mode.getMenuInflater();
 
        inflater.inflate(R.menu.actions, menu);
 
        return true;
    }

onCreateActionMode는 startActivity가 호출될 때 호출되는 콜백 메소드

    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
        return false;
    }

onPrepareActionMode는 액션모드를 refresh하는 목적으로 아무것도 하지 않으면 false, 액션 메뉴가 업데이트되면 true 반환

    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        switch(item.getItemId()) {
            case R.id.apple:
                mode.finish();
                return true;
            case R.id.grape:
                mode.finish();
                return true;
            default:
                return false;
        }
    }

onActionItemClicked는 사용자가 액션 메뉴의 항목을 클릭했을 때 호출

    @Override
    public void onDestroyActionMode(ActionMode mode) {
        mActionMode = null;
    }

onDestroyActionMode는 액션 모드를 종료시켰을 때 호출

@Override
public boolean onLongClick(View view) {
    if(mActionMode!=null) {
        return false;
    }
 
    mActionMode = this.startSupportActionMode(this);
    view.setSelected(true);
    return true;
}

리스너를 등록한 위젯에서 LongClick시 ActionMode를 실행시키기 위해 startSupportActionMode를 사용하여 컨텍스트의 액션 모드를 실행한다.

'IT > Android' 카테고리의 다른 글

Popup Menu 생성  (0) 2017.10.23
AlertDialog를 이용하여 RatingBar 띄우기  (0) 2017.10.23
Intent  (0) 2017.10.23
Action Bar  (0) 2017.10.23
Dialog  (0) 2017.10.23

+ Recent posts