2017년 11월 30일 목요일

Git



git status
git add .
git commit -m "내용" (status 로 확인)
git log

[branch 생성 및 checkout]
git branch xxx
git checkout xxx
(git check -b xxx : 2명령어를 한번에.)

원격 브치가 이미 존재 할 경우 원격 브랜치를 기준으로 로컬 브랜치를 만드는 방법
git checkout -b dev origin/dev

이미 존재하는 브랜치를 바로 가져오기
git bash 를 관리자 권한으로 실행 - 폴더 이동
git clone -b dev(브랜치명) http://xxx/xxx.git xxx_dev(폴더명 지정)

[work 브랜치에서 작업]
git add .
git commit -m "xxx"
git push origin work (work push)

[리모트 서버로부터 동기화]
git fetch origin

[work branch master merge & push]
git branch (현재 위치 확인)
git checkout master (master 로 변경)
git merge xxx (merge 할 브랜치 이름)
git push origin master (master push)

[remote branch push commit 삭제]
git reset --hard commit_id (id push 이전의 id, 내가 올리기전 마지막 id)
git push -f origin master (reset 이후 강제 push)

[add 취소]
git reset HEAD 파일명 (파일명 입력하지 않으면 모두 취소)

[commit 취소]
[방법 1] commit을 취소하고 해당 파일들은 staged 상태로 워킹 디렉터리에 보존
$ git reset --soft HEAD^
[방법 2] commit을 취소하고 해당 파일들은 unstaged 상태로 워킹 디렉터리에 보존
$ git reset --mixed HEAD^ // 기본 옵션
$ git reset HEAD^ // 위와 동일
$ git reset HEAD~2 // 마지막 2개의 commit을 취소
[방법 3] commit을 취소하고 해당 파일들은 unstaged 상태로 워킹 디렉터리에서 삭제
$ git reset --hard HEAD^

[push 취소]
가장 최근의 commit을 취소 (기본 옵션: --mixed)
$ git reset HEAD^

Reflog(브랜치와 HEAD가 지난 몇 달 동안에 가리켰었던 커밋) 목록 확인
$ git reflog 또는 $ git log -g
 
원하는 시점으로 워킹 디렉터리를 되돌린다.
$ git reset HEAD@{number} 또는 $ git reset [commit id]

commit message 수정
$ git commit -m "Write commit messages"

push
$ git push origin [branch name] -f 또는 $ git push origin +[branch name]


[충돌시]
Android Studio 이용시 unlink 에러는 read-only 이거나 write 가 안되는 상황 (다른 프로세스에서 잡고 있는 경우)
error: Your local changes to the following files would be overwritten by checkout:
Please commit your changes or stash them before you switch branches.


[Option]
git add -A : stages All
git add .  : stages new and modified, without deleted
git add -u  : stages modified and deleted, without new
//git remote add origin <원격서버주소>

git show <tag명>  : 태그정보와 해당 태그의 commit 정보를 확인한다.
ex : git show v1.4

git tag
git tag -l 'v.1.4.*' : Tag 목록조회 [v1.4 버전들의 목록만 조회]
git tag -a <tag명> -m '[tag message]' : 태그 추가
ex>git tag -a v1.0 -m 'add first release tag'
git push origin v1.4 : 태그 반영

git remote [-v] // 원격 저장소 정보 확인
git remote show <remote명> //리모트 저장소 살펴보기

comment message 수정
git commit --amend -> 내용 수정
git commit --amend -m "New commit message"

git pull

소스 수정사항 원복시키기(서버 상태 동기화?)
git fetch origin
git reset --hard origin/master

git config --global --list
현재 설정정보 조회할 수 있습니다. --global옵션은 전역설정에 대한 옵션이며 현재 프로젝트에만 적용할때는 주지 않습니다.
git config --global user.name "사용자명"
사용자명을 등록합니다 (필수)
git config --global user.email "이메일주소"
이메일 주소를 등록합니다. (필수)
git config --global color.ui “auto”
터미널에 표시되는 메시지에 칼라를 표시해줌


git에 대해서 사전에 알아야 될 부분은 아래와 같습니다.

git의 저장소는 3가지 단계로 나누어 집니다. 커밋한 소스가 보관되는 저장소와 현재 프로젝트 파일들이 있는 작업트리, 저장소와 작업트리사이의 버퍼영역으로 커밋될 대상이 저장되는 스테이징 영역입니다.
    git은 빈 디렉토리는 추적하지 않습니다.
    형상관리를 하지 않을 파일은 .gitignore 파일에 추가합니다.
    HEAD는 현재 브랜치의 가장 최신커밋을 의미한다.
    기본원격 저장소를 origin이라고 부릅니다.


[멀티 계정 사용시]
나의 경우 github(개인), bitbucket(회사) 2개를 동시에 사용하고자 할 경우
1. 각 계정별 ssh key 생성 및 등록
git bash home 에서 .ssh 폴더로 이동하여 생성
ssh-keygen -t rsa -b 4096 -C "abc@xxx.com"
ssh-add ~/.ssh/id_rsa_xxx
clip < ~/.ssh/id_rsa.pub (클립보드 복사)
각 사이트에 ssh key 붙여넣기

2. git config 에 각 계정 등록 (이 부분이 실제로 필요한지 확인이 안됨)
touch config
아래 내용 작성
# seesky89
Host seesky89
HostName github.com
User seesky89
IdentityFile ~/.ssh/id_rsa_seesky89

# aaa
Host aaa
HostName abc.com (포트 특정시 abc.com:7990)
User aaa
IdentityFile ~/.ssh/id_rsa_aaa

3. 그 이후에는 사용하던대로 하면 된다.
(대부분 해당 툴에서 계정 연동 팝업이 뜬다.)
bash 환경에서 할 경우 아래처럼 설정해줘도 된다.
git config --local user.name "aaa"
git config --local user.email "bbb@ccc.com"



[기본적인 명령어]
git --version
현재 git의 버전을 확인합니다.

git init
현재 디렉토리에 git 저장소를 생성합니다.

git add 파일명
git add는 2가지를 하는데 untracked files의 파일들을 git가 추적하도록 하거나 파일은 수정했지만 아직 스테이징 영역에 올라가지 않은(Changed but not updated) 파일들을 스테이징 영역에 올립니다. -i 옵션을 주면 대화형모드가 시작되며 파일의 일부분만 선택해서 스테이징하는 것이 가능합니다. -p 옵션을 사용하면 -i 대화형모드없이 바로 패치모드를 사용할 수 있습니다.

git commit -m "커밋메시지"
스테이징 영역에 올라가 있는 파일들을 커밋합니다. -m 은 커밋메시지를 주는 옵션으로 여러 줄의 커밋메시지를 쓸 경우 -m 을 여러개 사용할 수 있습니다. -a 옵션을 사용하면 스테이징에 올리는 작업과 커밋을 동시에 할 수 있습니다.(추적되지 않는 파일은 추가하지 않습니다.) -m을 사용하지 않을때 -v옵션을 사용하면 편집기에 커밋하려는 변경사항의 다른점을 보여줍니다. 특정파일만 커밋하려면 마지막에 파일명을 추가해주면 됩니다.

git commit -C HEAD -a --amend
지정한 커밋의 로그메시지를 다시 사용하여 기존커밋을 수정합니다. -c를 사용하면 기존메시지를 수정할 수 있는 편집기를 실행해 줍니다.

git status
커밋되지 않은 변경사항을 조회합니다.

git diff
스테이징영역과 현재 작업트리의 차이점을 보여줍니다. --cached 옵션을 추가하면 스테이징영역과 저장소의 차이점을 볼 수 있다. git diff HEAD를 입력하면 저장소, 스테이징영역, 작업트리의 차이점을 모두 볼 수 있다. 파라미터로 log와 동일하게 범위를 지정할 수 있으며 --stat를 추가하면 변경사항에 대한 통계를 볼 수 있습니다.

git mv 파일명 새파일명
기존에 존재하는 파일을 새파일로 이동합니다. 변경이력은 그대로 유지합니다.

git checkout -- 파일명
아직 스테이징이나 커밋을 하지 않은 파일의 변경내용을 취소하고 이전 커밋상태로 돌립니다. svn에서 revert와 동일합니다.



Branch와 Tag
git branch
현재 존재하는 브랜치를 조회합니다. -r 옵션을 사용하면 원격저장소의 브랜치를 확인할 수 있습니다.

git branch 브랜치명B 브랜치명A
브랜치명A에서 새로운 브랜치 브랜치명B를 만듭니다. (git에서 기본 브랜치는 master라는 이름을 사용합니다.)

git branch 브랜치명
브랜치명의 새로운 브랜치를 만듭니다.(체크아웃은 하지 않습니다.)

git branch -d 브랜치명
브랜치를 삭제합니다.

git branch -m 존재하는브랜치명 새로운브랜치명
존재하는 브랜치를 새로운브랜치로 변경합니다. 이미 존재하는 브랜치명이 있을 경우에는 에러가 나는데 -M 옵션을 사용하면 이미 있는 브랜치의 경우에도 덮어씁니다.

git tag 태그명 브랜치명
브랜치명의 현재시점에 태그명으로 된 태그를 붙힙니다. git tag만 입력하면 현재 존재하는 태그 목록을 볼 수 있습니다.

git checkout 브랜치명/태그명
해당 브랜치나 태그로 작업트리를 변경합니다.

git checkout -b 브랜치명B 브랜치명A
브랜치명A에서 브랜치명B라는 새로운 브랜치를 만들면서 체크아웃을 합니다.

git rebase 브랜치명
브랜치명의 변경사항을 현재 브랜치에 적용합니다.

git merge 브랜치명
브랜치명의 브랜치를 현재 브랜치로 합칩니다. --squash 옵션을 주면 브랜치명의 모든 커밋을 하나의 커밋으로 만듭니다.

git cherry-pick 커밋명
커밋명의 특정 커밋만을 선택해서 현재 브랜치에 커밋으로 만듭니다. -n 옵션을 주면 작업트리에 합치지만 커밋은 하지 않기 때문에 여러개의 커밋을 합쳐서 커밋할 수 있습니다.



로그 관리
git log
커밋로그들을 볼 수 있으면 -1나 -2같은 옵션을 주어 출력할 커밋로그의 갯수를 지정할 수 있습니다. --pretty=oneline 옵션을 주면 한줄로 간단히 보여주고 --pretty=format:"%h %s"처럼 형식을 정해줄 수 있습니다. -p 옵션을 사용하면 변경된 내용을 같이 보여줍니다. --since="5 hours" 이나 --before="5 hours"같은 옵션도 사용가능합니다. --graph 옵션을 주면 브랜치 트리를 볼 수 있습니다.

git log 커밋명
해당 커밋명의 로그를 볼 수 있습니다. 커밋명A..커밋명B (마침표2개)와 같이 입력하면 커밋명A이후부터 커밋명B까지의 로그를 볼 수 있습니다. ^은 -1과 동일해서 HEAD^라고 하면 최신바로 이전 커밋이고 HEAD^^^와 같이 쓸 수 있으며 HEAD~3을 하면 HEAD의 3개 이전의 커밋을 뜻합니다.

git blame 파일명
갈 줄 앞에 커밋명과 커밋한 사람등의 정보를 볼 수 있습니다.

git blame -L 10,15 파일명
-L 옵션을 사용하면 10줄부터 15줄로 범위를 지정해서 볼수 있고 15대신 +5와 같이 사용할 수 있습니다. 숫자의 범위 대신 정규식도 사용이 가능합니다.

git blame -M 파일명
-M 옵션을 사용하면 반복되는 패턴을 찾아서 복사하거나 이동된 내용을 찾아줍니다.  -C -C 옵션을 사용하면 파일간의 복사한 경우를 찾아줍니다. -C -C는 git log에서도 사용가능하며 내용의 복사를 찾을때는 git log에서 -p옵션을 사용합니다.

git revert 커밋명
기존의 커밋에서 변경한 내용을 취소해서 새로운 커밋을 만듭니다. -n옵션을 사용하면 바로 커밋하지 않기 때문에 revert를 여러번한 다음에 커밋할 수 있습니다.(항상 최신의 커밋부터 revert해야 합니다.)

git reset 커밋명
이전 커밋을 수정하기 위해서 사용합니다. --soft 옵션을 사용하면 이전 커밋을 스테이징하고 커밋은 하지 않으며 --hard옵션은 저장소와 작업트리에서 커밋을 제거합니다. git reset HEAD^와 같이 입력하면 최근 1개의 커밋을 취소할 수 있습니다.

git rebase -i 커밋범위
-i옵션으로 대화형모드로 커밋 순서를 변경하거나 합치는 등의 작업을 할 수 있습니다.



원격저장소
git clone 저장소주소 폴더명
원격저장소를 복제하여 저장소를 생성합니다. 폴더명을 생략가능합니다.

git fetch
원격저장소의 변경사항 가져와서 원격브랜치를 갱신합니다.

git pull
git fetch에서 하는 원격저장소의 변경사항을 가져와서 지역브랙치에 합치는 작업을 한꺼번에 합니다. 파라미터로 풀링할 원격저장소와 반영할 지역브랜치를 줄 수 있습니다.

git push
파라미터를 주지 않으면 origin 저장소에 푸싱하며 현재 지역브랜치와 같은 이름의 브랜치에 푸싱합니다. --dry-run 옵션을 사용하면 푸싱된 변경사항을 확인할 수 있습니다. 로컬에서 tag를 달았을 경우에 기본적으로 푸싱하지 않기 때문에 git push origin 태그명이나 모든 태그를 올리기 위해서 git push origin --tags를 사용해야 합니다.

git remote add 이름 저장소주소
새로운 원격 저장소를 추가합니다.

git remote
추가한 원격저장소의 목록을 확인할 수 있습니다.

git remote show 이름
해당 원격저장소의 정보를 볼 수 있습니다.

git remote rm 이름
원격저장소를 제거합니다.



서브모듈
git submodule
연관된 하위모듈을 확인할 수 있습니다.

git submodule add 저장소주소 서브모듈경로
새로운 하위모듈을 해당경로에 추가합니다. 추가만하고 초기화 하지는 않으며 커밋해쉬앞에 마이나스(-) 표시가 나타납니다.

git submodule init 서브모듈경로
서브모듈을 초기화 합니다.

git submodule update 서브모듈경로
서브모듈의 변경사항을 적용합니다.(저장소의 최신커밋을 추적하지 않습니다.)



기타 명령어
git archive --format=tar --prefix=폴더명/ 브랜치혹은태그 | gzip > 파일명.tar.gz
git archive --format=zip --prefix=폴더명/ 브랜치혹은태그 > 파일명.zip
해당 브랜치나 태그를 압축파일로 만듭니다. --prefix를 주면 압축하일이 해당폴더 안에 생성되도록 할 수 있습니다.

git mergetool
설정에 merge.tool의 값에 있는 머지툴을 찾아서 실행합니다.

git gc
저장소의 로그를 최적화 합니다. 로그가 변경되지는 않고 저장하는 방식만 최적화 합니다. --aggressive 옵션을 주면 더 자세하게 최적화합니다.

git rev-parse --show-toplevel
git 저장소내에서 입력하면 루트디렉토리를 알려줍니다.

2017년 5월 22일 월요일

공유기 추가 설정

IPTV 공유기를 다른방에서 사용시 와이파이 속도가 느린 감이 있어 공유기를 추가 설치
공유기 추가 방법에는 여러가지가 있을수 있겠다.

1. sub 공유기를 WDS 모드로 설정하여 사용
2. sub 공유기를 AP/스위치(허브) 형태로 연결하여 사용 (그림 1)
3. sub 공유기를 main 공유기에 연결하여 사용(?) (그림 2)
4. sub 공유기의 wifi 를 main 공유기와 동일한 이름으로 설정하기(무선 멀티브리지 기능 이용)


그림 1


그림 2

나의 경우에는 집안의 네트워크를 하나로 연결하기 위해 2번 방법으로 연결하였다.
여기서 사용된 공유기 환경은 main 공유기는 SK broadband 공유기이며, sub 공유기는 iptime 공유기이다.

SKB 공유기 초기값
웹설정 주소 : 192.168.35.1
사용자 계정 : admin
사용자암호 : XXXXXX_admin
(영문 대문자 사용, 공유기 뒷면 MAC주소 참고)

IPTIME 공유기 초기값
웹설정 주소 : 192.168.0.1

세팅
작업은 sub 공유기에서만 하면 된다.

(1) 공유기의 내부IP 주소 변경
공유기에 접속하여 [관리도구] - [고급설정] - [네트워크관리] - 
[내부네트워크 설정]을 클릭하고,
내부IP주소의 끝자리를 임의적으로 변경후 저장.
공유기 재부팅.

초기값 : 192.168.0.1 -> 변경 예 : 192.168.0.10

(2) 공유기의 DHCP 기능 중지
재부팅후, [내부네트워크 설정] 하단의 [DHCP 서버 설정]을 [중지]로 체크.
재부팅.

랜선 연결은 그림 2 처럼 연결.

참고.
1. DHCP 사용안함 선택시, sub 공유기에 접속하려면 초기화 해야한다.
(변경된 ip 로 접속안됨)
2. iptime 설정은 해당 홈페이지 참고
http://iptime.com/iptime/?page_id=67&uid=7433&mod=document

2017년 5월 10일 수요일

Annotation

Custom Annotation

선언
@Retention(용도)
@Target(범위)
public @interface XXX {
    ...
}

용도
RetentionPolicy.java (java.lang.annotation)
/**
 * @since 1.5
 */
public enum RetentionPolicy {
    /**
     * Annotations are to be discarded by the compiler.
     * 컴파일러가 사용하고 클래스 파일 안에 포함되지 않음 (단순 주석용, 컴파일러용)
     */
    SOURCE,

    /**
     * Annotations are to be recorded in the class file by the compiler
     * but need not be retained by the VM at run time.  This is the default
     * behavior.
     * 컴파일시 클래스 파일 안에 포함되나 VM에서 무시함
     */
    CLASS,

    /**
     * Annotations are to be recorded in the class file by the compiler and
     * retained by the VM at run time, so they may be read reflectively.
     * 컴파일시 포함되고 VM에서 인식함
     * @see java.lang.reflect.AnnotatedElement
     */
    RUNTIME
}

범위
ElementType.java (java.lang.annotation)
/**
 * @since 1.5
 */
public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    TYPE,

    /** Field declaration (includes enum constants) */
    FIELD,

    /** Method declaration */
    METHOD,

    /** Formal parameter declaration */
    PARAMETER,

    /** Constructor declaration */
    CONSTRUCTOR,

    /** Local variable declaration */
    LOCAL_VARIABLE,

    /** Annotation type declaration */
    ANNOTATION_TYPE,

    /** Package declaration */
    PACKAGE,

    /**
     * Type parameter declaration
     *
     * @since 1.8
     * @hide 1.8
     */
    TYPE_PARAMETER,

    /**
     * Use of a type
     *
     * @since 1.8
     * @hide 1.8
     */
    TYPE_USE
}

2017년 4월 27일 목요일

Android N - AlarmManager 사용시 PendingIntent 에 Parcelable 로 전달시 수신부에서 null 이 되는 현상

AlarmManager 사용시 PendingIntent 에 Parcelable 로 전달시 수신부에서 null 이 되는 현상

Android N 이후부터 발생(정확히 7.0 인지 7.1 인지는 모르겠다)

// send
intent.putExtra(EXTRA_DATA, xxx);
// xxx  Parcelable 구현 객체
 
// receive
final XXX xxx = bundle.getParcelable(EXTRA_DATA);
// 여기서 null 발생.

관련하여 검색을 해보면 아래 issue tracker 에도 등록이 되어 있다.

google 에서는 “Won't Fix (Intended behavior)” 로 처리.

app 에서 수정 필요.

// send
Bundle bundle = new Bundle();
bundle.putParcelable(EXTRA_DATA, xxx);
intent.putExtra(EXTRA_DATA, bundle);
 
// receive
Bundle bundle = intent.getBundleExtra(EXTRA_DATA);if (bundle != null) {
    final XXX xxx = bundle.getParcelable(EXTA_DATA);
}


참고로, 문자열이나 정수형 등은 정상적으로 전달이 된다.
only Parcelable 객체만 해당되는 것 같다.

2017년 4월 26일 수요일

Android Studio Plugin

plugin 설치는 File -> Settings -> Plugins

1. BitBucket

Android Studio + BitBucket +Git 이용한 소스 관리 참고

2. Android API Level

간단히 api level 보여주는 plugin
Browser repositories -> "api level" 로 검색하여 설치

3. IdeaVim

vim emulating plugin
Browser repositories -> "ideavim" 으로 검색하여 설치


2017년 4월 21일 금요일

Android 개발 관련

Android 개발 관련 정리 및 Tip 모음.

1. signing key 확인

signing key 파일과 apk 가 같은 key 인지 확인할때 아래 명령어 사용

1.1 signing key fingerprint 확인
keytool -list -keystore xxx.jks

1.2 apk fingerprint 확인
keytool -list -printcert -jarfile xxx.apk

위 2가지의 fingerprint 같으면 동일한 key 로 서명이 된것임.

2. Log

Log 출력시, line, method name 포함하여 보여준다.
아래와 같은 식으로, level 별로 각각 만들면 됨.
LOGV_TAG 는 기존 로그와의 호환을 위해 사용.

Log.java

public class Log {
    public final static String TAG = "InputCommonTagName";

    public static final boolean LOGV = true;
    static final boolean LOGV_TAG = true;


    static int mLine=0;
    static String mName="";
    static String mPkg="";
    
    public static void v(String logMe) {
        if(LOGV) {
            StackTraceElement[] stack = (new Throwable()).getStackTrace();
            mLine = stack[1].getLineNumber();
            mName = stack[1].getMethodName();
            mPkg = stack[1].getFileName();
            android.util.Log.v(TAG, ""+mPkg+", "+mLine+" line, "+mName+"(), "+logMe);
        }
    }

    public static void v(String tag, String logMe) {
        if(LOGV_TAG) android.util.Log.v(tag, logMe);
    }
}


3. Live Templates 연동 (Android Studio)

File -> Settings -> Editor -> Live Templates -> AndroidLog

Add -> 적당한 이름 추가.






3-1. method 에 parameter 같이 출력하기.

3-1-1. android.util.Log 사용시

Template text :

Log.d("TAG_NAME", "$CLASS_NAME$ : $METHOD_NAME$()" : $content$);

$content$ 에 대한 Edit variables 작성 (그림 참고)

groovyScript("def params = _3.collect {it + ' = [\" + ' + it + ' + \"]'}.join(', '); return '\"' + _1 + ' : ' + _2 + '()' + (params.empty ? '' : ' : ' + params) + '\"'", className(), methodName(), methodParameters())


3-1-2. 2번의 Log 사용시

Log.d($content$);

groovyScript("def params = _1.collect {it + '=\"+'+it}.join('+ \"'); return '\"' + (params.empty ? '' : params)", methodParameters())

or

groovyScript("def params = _1.collect {it + ' = [\" + ' + it + ' + \"]'}.join(', '); return '\"' + (params.empty ? '' : params) + '\"'", methodParameters())


3-2. return value 같이 출력하기

3-2-1. android.util.Log 사용시

Template text :

Log.d("TAG_NAME", "$CLASS_NAME$ : $METHOD_NAME$() returned: " + $result$);

$content$ 에 대한 Edit variables 작성 (그림 참고)

variableOfType(methodReturnType())


3-2-2. 2번의 Log 사용시

Log.d("returned : $result$=" +  $result$);

$result$ 에 대한 Edit variables 작성
variableOfType(methodReturnType())


2017년 4월 13일 목요일

Blogger 관련 Tip

1. 소스 코드 넣기

1-1. highlightjs 를 사용한다. (아래 링크 참고)

https://highlightjs.org/download/



1-2. cdnjs 사용
테마 -> HTML 편집 -> <head> 마지막에 붙여넣는다.
css style 은 취향게 맞게 변경 가능.

<link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.10.0/styles/default.min.css" rel="stylesheet"></link>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.10.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>

1-3. 소스 코드를 html 모드로 편집
class 설정은 생략 가능. 알아서 처리됨. (ex: <code class="language-java">)

<pre><code>
// to do
</code></pre>

1-4. html 태그의 경우는 escape 시켜줘야한다.
관련 web site 는 많으니 검색해서 사용하면 된다.(html escape)

http://www.igorware.com/tools/xml-escape
http://www.blogcrowds.com/resources/parse_html.php


ps 1. 테마 변경시마다 1-2번 작업을 다시 해주어야 한다.
ps 2. 테마중 "동적 뷰" 의 경우는 동작하지 않으니 다른 방식으로 적용해야 한다.(구글링...)


2. 메뉴 넣기(상단 or 사이드)

2-1. 레이아웃 -> 전체열(가젯추가) -> 페이지 선택
2-2. 외부 링크 추가 -> 입력
  웹주소 형식은 "http://블로그주소/search/label/라벨이름(태그이름)?max-results=숫자"
  숫자는 해당 탭 선택시 보여질 페이지수. 1 권장.
  예로, 페이지 제목 : "Android",
  웹주소 : "http://seesky89.blogspot.kr/search/label/Android?max-results=1" 설정하면,
  상단에 Android 탭이 생겨 사이드바의 태그와 동일한 기능을 한다.

3. 파일 첨부 하기

구글 드라이브 이용하여 링크 걸어야 한다.



Android Jetpack viewpager2

  Android Jetpack ViewPager2 기본 개념 및 샘플 코드 오늘은 안드로이드 개발에 있어서 굉장히 유용한 컴포넌트 중 하나인 ViewPager2에 대해 이야기해볼까 합니다. ViewPager2는 사용자 인터페이스에서 여러 화면을 좌우...