728x90
728x90

참고 : 유투브 — 센치한 개발자

목표 : Handler 와 Runnable 를 이용하여 카운트 다운을 만들어 보자.

  • xml 파일에는 id 만 추가해주자.

  • 1에서 5까지 1초마다 한 번씩 카운트가 증가한다.
  • line 19 : count 가 int 형이므로 count 뒤에 [+ “” ] 를 덧붙여주었다.
  • line 36에서 post() 를 하면 line17 이 실행된다. 처음 count 변수를 0으로 초기화했으므로 run() 이 실행되면 1이 되면서 count가 5가 될 때까지 1초에 1씩 증가한다.

빌드를 해 보면 1에서 5까지 증가하고 멈춘 것을 확인할 수 있다.

 

 

참고)

<Process>

: 실행중인 프로그램의 객체. Android에서 앱을 실행하면 하나의 Process가 실행되고 MainActivity의 코드와 데이터를 메모리에 올린다.

<Thread>

: Process 안에서 코드를 실행시키는 객체. 하나의 Process 안에 여러개의 Thread가 있을 수 있다. (Multi Thread => 효율성 향상)

Process가 처음 시작되고 Thread를 처음 가지게 되는데, 이를 MainThread(UI Thread) 라고 한다. 이 위에서 작업량이 많아지면 ANR(Application Not Responding) 에러가 발생한다. 이를 위해 Worker Thread를 사용해야 한다.(멀티 스레드)

<Runnable>
: Thread 가 실행(run)해야하는 코드

<Handler>

: Worker Thread 에서 Main Thread 로 메세지를 전달하는 역할. post 를 통해 전달된 runnable 객체는 해당 handler 가 연결된 Thread 에서 실행된다.

참고 — https://brunch.co.kr/@mystoryg/84 , https://developer88.tistory.com/72

728x90
728x90

참고 : 유투브 — 센치한 개발자

  • Firebase : 클라우드. 웹과 모바일 개발에 필요한 기능을 제공해주는 BaaS(Backend as a Service).

[1. Firebase 셋팅하기]

  • 콘솔로 이동 > 프로젝트 생성

  • 안드로보이 클릭

  • 패키지 이름은 아래 화면과 같이 AndroidManifest.xml에서 가져온다. (line 3)

  • 다운 받은 파일을 지정된 위치에 복사+붙여넣기 한다.

  • 앱 수준의 bundle gradle — 위 쪽 파일 / 프로젝트 수준의 bundle gradle — 아래 쪽 파일

classpath 'com.google.gms:google-services:4.3.3'

를 종속성에 추가한다. (line 12)

  • line 47, 52,53 을 추가하고 Sync Now 를 클릭한다.

  • line 49~52 추가

  • line 26~28 추가
  • Sync Now 클릭

  • real time mode -> 셀카 촬영 모드에서 바로(실시간으로) 얼굴을 인식할 때 쓰면 좋을것이다.
  • 우리는 사진으로 얼굴을 인식할 예정이므로 위의 ‘high accuracy’ 를 쓸것이다.

 

 

[2. Face Detector 구성]

액티비티 파일을 생성하고 이와 연결할 xml 파일도 생성한다.

  • 예제 코드를 복사하여 사용할 클래스(액티비티) 를 새로 생성한다.

  • 액티비티와 연결할 xml 파일도 하나 생성한다.

  • scaleType : 이미지가 정해진 레이어보다 커서 넘쳤을 때 어떻게 해결할건지를 정의한다.
  • adjustViewBounds : 이미지의 종횡비가 깨지는 것을 허용할 것인지 아닌지 정한다. 값이 true 이면 허용하지 않을 것이라는 의미이다. (비율을 유지할 것)
  • 기본 이미지 위에 다른 이미지들을 겹쳐서 올리는 것이므로 RelativeLayout 을 사용한다.

  • 코드를 긁어서 붙여넣기한 후 class 를 import 한다. (alt + enter)

 

 

[3. Face Detector 실행]

머신러닝을 실행하려면 fire base 에게 Image 를 던져줘야한다.

참고 : https://firebase.google.com/docs/ml-kit/android/detect-faces

  • line 34 : FirebaseVisionImage 객체를 만든다.
  • line 36,37 : FirebaseVisionFaceDetector의 인스턴스를 가져온다.
  • line 39~56 : 이미지를 detectInImage 메소드에 전달한다.

[4. 감지된 얼굴에서 데이터 정보 얻기]

  • line 51~81 : 에 복사한 코드를 추가해준다.

 

 

[5. 이미지 리소스 파일을 코드로 가져오기]

  • line 31~36 : fire base 설정한 부분. 이 fire base 에게 bit map 사진을 던져주면 분석을 한다.
  • bitmap 사진을 던져보자. => 어디에?

  • res 아래에 drawable-xxhdpi 디렉토리를 새로 만들어서 다운받은 이미지 파일 네개를 넣어준다.
  • Context : 앱의 기능들을 자유롭게 사용하기 위한 매개체. 전역 변수로 선언해준다.
  • faces 인 이유 : 이미지에 얼굴이 여러개인 경우 For 문을 돌면서 찾기 위해 => 그 찾는 정보를 보기 위해 Log 를 찍어보자. => json 에 얼굴 정보들이 들어있다.
  • Landmark — 얼굴의 눈,코,입,볼 등의 정보
  • 이렇게 얻어온 Landmark 의 좌표에 멍 사진과 고양이 수염 사진을 넣으면 된다.

위치 정보 빼오기

  • png 파일을 ImageView 로 직접 가져와서 써도 되지만 이러면 사진을 추가할 때마다 xml 파일을 변경해야하는 불편함이 있다. 또한 멍 사진과 고양이 수염 사진 뿐 아니라 추후에 더 많은 사진들을 추가할 것을 대비하여 이미지 뷰를 가상으로 만들어 이용하는 방법으로 코딩해보자.
  • line 5 : 스티커(이미지)는 사진 위에 겹치게 보일 예정이므로 부모인 RelativeLayout에 이름을 지정하여 붙일 예정이다.

  • line 13 : RelativeLayout 위에 스티커를 붙일 것이므로 findViewById로 가져온다. (final 로 선언 한 이유 : 본인은 오류가 final 을 안 붙여도 오류가 나지 않았으나 강의에서는 범위로 인해(중괄호 바깥에 선언을 해서) 오류가 발생했음. 이를 해결하기 위해 값이 변하지 않고 그대로라는 뜻의 final 을 써줘야함.)
  • line 39 : 초기화
  • line 81,85,89 : 가상이미지를 통해 스티커를 붙였다. (imageCL 은 imageLC로 고쳐야함. 오타임.) => 이제 붙인 스티커를 위에서 getPosition으로 받은 좌표 위로 옮기면 된다.
  • 디스플레이 사이즈와 불러온 이미지 사이즈의 포인트 위치가 안드로이드 해상도 문제로 인해 조금씩 틀어진다. => 계산식이 필요하다.

  • 위에서 말했다시피, 스크린상의 좌표 (실제 좌표) 와 getPosition() 으로 얻어온 좌표와 사진 위치(R.drawable.sentilab) 사이의 계산식이 필요하다.
  • 필요한 계산 식 : point * 랜드마크 좌표 / 비트맵(얼굴 사진)

  • line 98 : imageLE의 크기를 바꾸자 => imageLE 가 속해있는 부모를 써야하므로 RelativeLayout 을 쓴 것이다.
  • -100 이유 : x,y에 face detector가 알려주는 점이랑 이미지랑 위치가 안 맞다.

 

 

최종 결과

 

728x90
728x90

 

참고 : 유투브 — 센치한 개발자

참고 : 아래 사이트

firebase.google.com/docs/database

 

  • NoSQL 은 json 형태를 기반으로 한다.

 

[1. 기본 설정하기]

implementation 'com.google.firebase:firebase-database:19.1.0'

를 앱 수준의 build.gradle 에 종속성을 추가한다.

  • 콘솔로 이동한 후 좌측의 Database 를 클릭한다.
  • 베타 버전인 Cloud Firestore 대신 Realtime database 만들기를 클릭한다.

  • read, write 를 모두 true 로 하고 사용설정을 클릭한다.

  • 안드로이드에서 저 프로젝트에 접근해서 json 데이터를 쌓을 것이며 이 데이터가 채팅 내용이다.

 

 

[2. 액티비티, xml 파일 생성]

  • Empty Activity 를 생성하면 xml 파일도 동시에 생성된다.

  • xml 파일을 위와 같이 수정해준다.

  • AndroidManifest.xml 파일도 수정해준다. (이전 액티비티 삭제)

 

 

[3. 데이터 베이스에 쓰기]

  • line 18~20을 복사 붙여넣기 한다.
  • 위 링크 하단의 다음 단계>데이터 읽기 및 쓰기를 클릭한다. (링크 — https://firebase.google.com/docs/database/android/read-and-write)
  • line 18 : 데이터 베이스를 선언하고 할당(생성)했다.
  • line 19 : ny-face 데이터 베이스 밑에 “message” 가 없으니 “message”를 만든다.
  • line 21 : message 밑에 “Hello World” 라는 내용이 들어간다.

  • message 가 올라간 것을 확인할 수 있다.

 

 

[4. DTO 생성]

채팅 데이터를 주고 받는 DTO(Data Transfer Object) 부터 만들어보자.

  • ChatData 을 생성한다.

 

 

[5. 어댑터 생성]

이제 ChatData 를 가져다가 값을 셋팅하는 Recycler의 어댑터가 필요하다.

  • 위와 같이 코드를 타이핑한다.

 

 

[6. xml 파일 생성]

  • 루트 LinearLayout이 vertical이므로 그 아래 weight 를 1로 다 가져간 RecyclerView의 height 는 0dp 이고, 그 아래 LinearLayout은 horizontal 이므로 weight를 1로 다 가져간 EditText의 width는 0dp 이다.
  • onBindViewHodler에서 받아온 닉네임을 비교하여 메세지를 정렬한다. (상대 방의 메세지는 왼쪽에 나의 메세지는 오른쪽에)

 

[7. add 함수 생성]

  • line 104 : 뉴스 앱을 만들 때에는 매번 실행할 때마다 새로운 데이터로 갱신됐는데, 채팅 앱은 메세지가 1건씩 추가될 때마다 뒤에 덧붙여야 하므로 add 하는 로직이 필요하다.
  • line 105 : 데이터가 삽입되는 것의 변화를 위해 notifyItemInserted를 사용해야 한다.
  • line 105 : add 를 하면 채팅 데이터 배열의 크기가 늘어나므로 그 사이즈를 활용해야 한다.

 

[8. 채팅 정보 셋팅]

  • setValue를 하여 데이터를 넣을 때 ChatData Class 자체를 넣을 예정이다.
  • line 47~50 : 이렇게 클래스를 넣기 시작하면 주의해야할 점이 있다. 우리가 처음에 “Hello World” 라는 스트링형을 데이터 베이스에 넣었기 때문에 에러가 난다. 그러므로 클래스를 넣기 전에 이미 올라가 있는 스트링 데이터를 지워야한다.

이제 리사이클러뷰의 어댑터에 가져온 채팅 데이터를 셋팅해야한다.

  • line 51 : dataSnapshot = 채팅 데이터를 담고 있는 변수
  • line 52 : 우리는 두번째 getValue() 를 쓸 것이고 괄호 안에 들어갈 클래스는 ChatData 클래스 이다.
  • getValue(ChatData.class) : 또 다른 형태의 클래스를 넣은 적이 있다면 이때 오류가 난다.

  • line 57 : 클래스 형 변환 필수!

 

 

[9. 전송 버튼 눌렀을 때 전송되게 하기]

  • 채팅 내용을 입력한 후 전송 버튼을 눌렀을 때에 서버로 채팅 내용을 보내야 한다.
  • line 32,33 : 변수 선언
  • line 43,44 : xml 컴포넌트와 매칭
  • line 46 : 버튼을 눌렀을 때 Button_send, EditText_chat 의 정보를 읽어서 서버로 보내야하므로 클릭 리스너 생성
  • line 51 : 빈 칸은 서버로 보내지 않도록 null check.

 

[10. 중간 점검 & 오류 해결]

  • line60~63 : 리사이클러 뷰 셋팅
  • line 64 : 리스트 선언
  • line 66~67 : 어댑터 셋팅
  • line 69,70 : 데이터 베이스 접속 후 데이터 정보 가져옴
  • line 72~75 : 채팅 데이터에 최초 데이터를 넣음

  • line 76~80 : 내가 보낸 메세지면 오른쪽에(END), 상대방이 보낸 메세지면 왼쪽에(START) 배치한다.

그러나 이렇게 실행을 하면 오류가 발생한다.

  • 데이터는 들어갔으나 앱은 실행되지 않았다.

로그화면

  • 이유 : 데이터가 정상처럼 보이지만 구조가 맞지 않았다.

에러를 해결해보자.

  • 초기 데이터 문제일 수도 있으므로 line 72~75를 주석처리했다.

  • 데이터도 삭제하고 다시 빌드해보았다.

그러나 앱은 실행되지 않았다.

로그를 살펴보자.

오브젝트를 변환할 수 없다고 뜬다.

  • line 71의 path 를 지우고 line 84,85를 주석처리 한 다음 Line 82와 같이 로그를 찍어보자.

  • 들어간 데이터가 한 묶음이 아닌 따로 들어가서 (두 줄로 나옴) 오류가 나는 것으로 예상한다.

다시 해결해보자.

  • Serialzable 을 지우고, setValue() 전에 push()를 해준다.

  • 값이 정상적으로 짝을 이루어 들어간 것을 확인할 수 있다.

  • 로그 값도 짝이 지어져 있는 것을 볼 수 있다.

  • 주석 처리한 것을 풀고 다시 확인해보자.
  • 추가로 nick1 에 대해서 닉네임과 채팅 내용을 모두 오른쪽 정렬 해 주자.

  • line 78,82 를 추가해준다.

결과

 

 

 

 

 

[11. 새로운 단말기 빌드]

두번째 채팅방 접속자를 만들기 위해 새로운 단말기로 빌드해보자.

성공

 

 

 

추가)

  • 지금 만든 앱은 새로운 접속자가 있을 때 마다 nick1,nick2,,, 이런 식으로 직접 바꿔줘야한다.
  • 그러나 랜덤 채팅 혹은 정해진 사용자만을 원할 때는 저번에 배운 로그인 화면을 이용한다던가 firebase의 authentication 의 로그인 기능을 이용할 수도 있다.
  • 현재는 가장 처음에 read, write 를 true 로 해주어 아무나 접속이 가능하지만, 이를 false 로 바꾸면 그게 불가능하다.

 

 

 

728x90
728x90

참고 : 유투브 — 센치한 개발자

<기본 설정 및 기초 이해하기>

[1. 라이브러리 다운]

[2. RecyclerView 컴포넌트 붙이기]

  • activity_news.xml 파일에 layout을 추가한다.
  • 이곳에 뉴스 앱 화면을 보여줄 것이다.

[3. 액티비티 클래스에 내용 구현하기]

  • NewsActivity.java : activity_news.xml 와 매칭 될 액티비티를 새로 만든다.

[4. 리스트에 사용할 어댑터(리스트의 항목들 제어) 붙이기]

  • MyAdapter.java 를 새로 작성한다. 어댑터를 구현하는 클래스이며 어떠한 리스트들을 보여줄지 상세한 내용을 담는다.

  • 빨간줄이 뜨는 것에 대해 alt+Enter 로 class 를 import 해준다.
  • line 37 의 빨간줄이 없어지지 않는 이유 : RecyclerView를 보여주는 액티비티 xml과 각 줄별로 내용을 보여주는 레이아웃 xml 이 필요한데, 아직 후자의 xml 파일이 없기 때문이다.

[5. row_news.xml 작성]

  • 그림 2와 같이 만들어보자.

  • 그림 2에 들어갈 레이아웃을 위해 row_news.xml 파일을 새로 만들어 코드를 작성한다.
  • ImageView와 TextView 를 이용한다.
  • line 27 : 색상값 총 8자리 중 맨 앞자리 2자리는 투명도(16진수) 값이다.
  • line 43 : ellipsize는 텍스트 내용이 많아서 정해진 칸을 넘어갈 때 “…” 을 사용함으로써 내용이 더 있다는 것을 나타내고자 할때 쓴다.

  • line 37 : 레이아웃을 연결해준다. 위와 같이 row_news 로 수정하면 오류가 사라진다.
  • line33~40 : row 한 줄에 해당하는 파일(row_news.xml) 을 연결시켰다.
  • line 17~24 : 그 한 row 에 들어가는 요소(Text,Image..) 를 정의하는 것이다.
  • MyViewHolder 클래스에서 findViewById() (하위 컴포넌트를 연결하기 위해 찾아가는 함수) 를 통해 하위 컴포넌트를 연결한다.

정리 : row_news.xml 이라는 전체 파일은 line 33–40의 onCreateViewHolder() 에서, 한개의 row 안에 들어가는 텍스트와 이미지는 line 20의 MyViewHolder() 에서 정의한다.

  • line 45 : row_news.xml 의 최상위 뷰가 LinearLayout 이므로 수정
  • line 46 — inflate : 특정한 컴포넌트(여기서는 리사이클러 뷰)의 특정 항목의 레이아웃을 바꾼다. (여기서는 액티비티에서 갖고 오는 뷰가 아님)

  • 한 row 안의 요소들을 다루기 위해 변수 선언.
  • findViewById 앞에 v. 을 붙인 이유는? => 부모 xml 뷰가 누군지 알 수 없으므로 명확하게 row_news.xml이 부모라고 지정한 것이다.
  • line 26 : 뷰홀더 클래스가 받는 값을 TextView 에서 View 로 수정해준다.

참고 : 나중에 발견한 사실인데, 파일 명에 저렇게 빨간줄이 많이 뜨는 이유는 위 화면의 line 12 때문이다. line 12를 지우면 오류가 해결된다.

참고 : 뷰홀더 클래스는 메모리 관리와 성능 향상을 위해 안드로이드가 제공하는 클래스이다. (재활용 가능)

  • line 25,26 : 리사이클러 뷰를 액티비티에서 불러서 activity_news 라는 액티비티를 만들었다. 거기에 리사이클러뷰를 연결했다.
  • line 30 : 하나의 row 사이즈를 맞췄다.
  • line 33,34 : manager을 달아줌.
  • line 37 오류 해결 방법 : 아래와 같이 line 21에 코드 한 줄을 추가 해준다.

  • line 39,40 : 아래 화면의 생성자로 값을 넘겨주는 역할을 한다. NewsActivity.java 를 계속 참조하면 메모리를 낭비할 수도 있고 화면이 사라질 수도 있기 때문에 아예 값을 넘겨 받아 이런 위험을 방지한다.

MyAdapter.java 파일 안의 생성자

  • MyViewHolder 클래스는 mDataset의 크기(mDataset.length)만큼 반복을 하는데, 매 반복마다 mDataset에서 값을 꺼내어 매칭을 시켜준다. (by v.findViewById())
  • 반복한 홀더를 바인딩 즉, 데이터를 셋팅하는 곳이 위 화면의 line 54 이다.
  • row_news.xml 에 표시되는 내용들은 어디서 가져와야 하는 것일까? => Adapter 를 처음 설정 할 때 mDataset 변수에 값을 넣어줘야 여기서 가져올 수 있다. (mDataset 변수 : 각 row 마다 보여줄 값을 들고 있는 원본 데이터 변수)

  • 그 값들을 여기에 넣어주면 화면상으로는 row_news.xml 에 나타나게 된다.

[중간 점검]

  • line 12를 MainActivity 에서 NewsActivity로 바꾼 후 실행해보자.
  • Sample1 이 튕겨서 종료되는 오류가 발생한다.

  • activity_news.xml 파일의 line 8을 위와 같이 수정한 후 빌드해보자.

  • mDataset을 {“1”, “2”} 로 두 개를 넘겨줬는데 1만 뜨는 오류가 발생했다.

  • row_news.xml 파일의 line 4를 match_parent 에서 wrap_content 로 변경해주면 정상적으로 실행됨을 확인할 수 있다.
728x90
728x90

참고 : 유투브 — 센치한 개발자

[목표 : 위의 로그인 화면을 디자인 해보자.]

[1. 레이아웃을 그릴 xml 파일 생성]

  • 왼쪽의 res 폴더 안의 layout 폴더에 ‘activity-login.xml’ 파일을 만든다.

  • ‘MainActivity.java’ 파일과 위에서 새로 만든 ‘activity_login.xml’ 파일 매칭을 위해 line 12 를 위와 같이 수정해준다.

[2. TextView로 LOGIN 글자 삽입]

[3. ImageView로 이미지 삽입]

  • 프로젝트를 만들면 들어있는 기본 앱 아이콘 이미지를 쓴다.
  • background로 넣거나 src로 넣는 방법이 있다.
  • background로 넣으면 이미지가 깨지므로 src를 이용한다.

  • 이미지가 삽입된 것을 확인할 수 있다.
  • width 는 “match_parent”로 height는 “wrap_content”로 설정한다.
  • 그런데 여기서 이미지가 가로 사이즈에 맞춰서 늘어나지 않은 것을 확인할 수 있는데, 이는 src 방법으로 이미지를 삽입했기 때문이다.

  • background를 이용하여 이미지를 삽입하면 위와 같이 이미지가 깨져서 삽입된다.
  • background는 이미지를 너비와 높이에 무조건 꽉 채운다. 그러나 width 설정을 “wrap_content” 로 한 후 중앙으로 보내는 설정을 해 주면 된다. (복잡하니 그냥 src를 이용하여 이미지를 삽입하도록 한다.)

[4. EditText로 이메일과 패스워드 입력 창 생성]

[5. Button 생성]

[6. 가로로 TextView 두 개 삽입]

  • weightSum을 이용하여 절반씩 text를 배치한다.

[7. Text Color , Size 바꾸기]

  • line 13, 84 : 글씨 색을 바꾼다.
  • line 14,73,84 : 글씨 크기를 바꾼다.

[8. Button Color를 바꾸기 위해 색깔 따오기]

nanyoungkim.tistory.com/13

 

Pixlr Editor로 색상코드(HEX) 알아내기

안드로이드 스튜디오에서 로그인 화면을 만드는 도중에, 버튼 색을 지정하기 위해 주어진 버튼 색의 핵사값을 알아내야 했다. Pixlr Editor 로 임의의 색깔의 핵사값을 알아내보자. Step 1)부터 하면

nanyoungkim.tistory.com

위의 링크에서 먼저 버튼 색의 HEX 값을 알아오자.

 

 

 

 

 

  • 안드로이드에서 제공하는 머터리얼 디자인을 사용하기 위해 ‘Gradle Scripts — build.gradle’ 에 line 30을 추가한다. 그 후 오른쪽 상단의 Sync Now 를 클릭하여 관련 소스들을 다운로드한다.
  • 주의 : 버전이 바뀌면서 에러가 발생한다. 해결을 위해 유투브 강의 댓글을 서치한 결과 문제를 해결할 수 있었다.

 

  • line 30과 같이 implementation ‘com.google.android.material:material:1.0.0-rc01’ 라고 타이핑한다.
  • 그 후 Sync Now 를 클릭하면 싱크가 잘 맞는것을 확인할 수 있다.

 

 

 

[9. 상업용 이미지 파일 다운]

  • present 를 검색한 후, PRICE는 ‘Free’로, LICENSE TYPE은 ‘For commercial use’로 선택한다.

  • 원하는 사진을 다운로드 한다.
  • Size는 128px, 64px, 48px 세 종류를 다운한다.
  • 참고 : 더 심플한 이미지를 원하면 https://material.io/resources/icons/?style=baseline 에서 다운로드가 가능하다. (google에 ‘material icon’ 검색)

 

[10. 다운로드 한 이미지 파일 프로젝트에 넣기]

  • 왼쪽 상단의 Android를 Project로 바꾼다.

  • app — src — main — res — drawable 폴더안에 다운로드 한 이미지 파일을 ctrl +v 하여 복사한다.
  • 이때, 이미지 파일은 소문자와 언더바를 이용하여 간단하게 작성하도록 한다.

  • line 21을 수정했더니 안드로이드 기본 아이콘에서 icon_present.png 파일로 바뀐 것을 확인할 수 있다.
  • line 19를 수정하여 아이콘 크기를 조금 줄여보았다.
  • 참고 : 원래는 원하는 화면 사이즈에 맞는 폴더 명을 지정한 후 이미지를 적절하게 넣어주어야 한다.

  • 사이즈를 보는 방법: Pixel(Device for Preview) 클릭 — Add Device Definition 클릭 — 오른쪽 연필 모양의 Edit this AVD 클릭 — ‘5.96 1440x2560 560dpi’ 확인 가능.

그러나 여기 기초 강의에서는 그냥 drawable 폴더에 이미지를 넣는다.

[11. Hint 이용하여 텍스트 넣기]

  • line 29, 35를 추가한다.

[11. 버튼 라운딩 처리 하기]

  • 우리가 원하는 버튼 디자인은 타원형이나, 기존의 Button 은 네 모서리를 둥글게 하는 기능이 없다. 이를 해결해보자.

  • drawable폴더에 xml 파일을 한개 더 생성한다.

  • selector 라는 디자인 요소를 정의한다.
  • item : 정상 상태일 때를 정의한다.
  • shape : 정상 상때일 때의 모양을 정의한다.
  • solid : 색을 정의한다.
  • corners : 모서리를 둥글게 한다.

  • line 44,61 : 모서리를 둥글게 처리하였다.
  • line 45,62 : 텍스트 컬러를 변경하였다.

[12. 버튼 컬러 변경하기]

  • bin_blue.xml 파일에 8번에서 딴 색깔 여섯자리를 line 6에 적용한다.bin_darkblue.xml 파일도 하나 생성하여 위와 같은 방법으로 색깔 6자리를 타이핑한다.

  • activity_login.xml 파일의 line 44, 61 : 버튼 컬러가 바뀜을 확인할 수 있다.

[13. 중간 점검]

  • 빌드를 하고 Email 칸에 타이핑을 하였으나 ‘Email’이라는 글자가 사라지는 것을 확인하였다. 이를 해결해보자.

[14. TextInputLayout & TextInputEditText 사용하기]

  • 위와 같이 타이핑하고 빌드해보자.

  • 타이핑을 하면 Email 이라는 글자가 사라지는 것 대신 위로 올라감을 확인할 수 있다.

[15. 여백 주기]

  • line 14, 24,32,46,64,73 과 같이 layout_marginBottom 을 16dp로 지정해준다.

결과

  • line 6, 7 : 양 옆에 padding 을 준다.
  • line 8 : 위에 padding 을 준다.

[16. 버튼에 이미지 넣기]

  • 버튼에 아이콘을 추가하기 위해 line 68을 추가했더니 오른쪽과 같은 결과가 나왔다. 크기 문제를 해결해보자. (해결책 — RelativeLayout 사용)

[17. 버튼이 눌렸을 때 효과 주기]

  • 좌측 프로젝트에서 app-src-main-res-values-colors.xml 파일에 색을 정의한다.

  • bin_blue.xml 파일을 위와 같이 수정한다.
  • 3개의 아이템 엘리멘트 : 각각 버튼이 눌린 상태(Yellow), 평소 상태(Blue), 누를 수 없는 상태(Gray)를 위한다.
  • colors.xml 파일에 색을 정의했으므로 “@color/colorYellow” 와 같이 쓸 수 있는 것이다.

  • bin_darkblue.xml 파일도 위와 같은 방식으로 수정해준다.

[17. 정렬 다듬기]

  • Log in 버튼과 Log in with Facebook 버튼을 만들기 위해 LinearLayout 안에 ImageView와 TextView를 사용한다.
  • 전체적인 틀은 LinearLayout 을 이용하고 weightSum 으로 그림과 텍스트 간의 비율을 맞춰준다.
  • 그러나 실행화면을 보면 ‘Log in’ 글자와 ‘Log in with Facebook’ 글자가 살짝 오른쪽으로 치우친 것을 확인할 수 있다. 이를 해결해보자.

[18. 입력한 값 가져오기]

  • 참고 : RelativeLayout은 버튼이 아니므로 clickable = “true” 가 필요하다.

  • line 40,55,63 : MainActivity.java 에게 xml 파일 안의 컴포넌트들의 존재를 알려주기 위해 id 를 지정한다.

  • line 12,13 : 컴포넌트 종류를 앞에 써 주고 그 뒤에 변수명을 타이핑하여 변수를 선언한다. (에러가 뜨면 맥 기준에서 alt+Enter 를 통해 class 를 import 해준다. )
  • line23,24,25 : 선언한 변수들에 실제 값들을 대입한다.

  • setClickable — 클릭 가능 여부 설정 / setOnClickListener : 클릭 리스너 설정
  • line 36 : 클릭이 가능하다는 것을 설정해준다.
  • line 37 : 클릭 리스너를 설정한다.
  • line 40,41 : 사용자가 이메일과 패스워드를 입력한 후 로그인을 클릭했을 때 값을 받아온다는 의미이다.

  • Intent 방식 : 값을 주고 받는 하나의 규약.
  • putExtra : key와 value 를 이용하여 값을 찾아온다. (key로 찾아서 value를 빼오는 것)
  • line 48 : 넣은 값을 다음 액티비티로 던지기 시작하겠다는 의미이다.
  • line 45 : 어디로 던질지 정해준다.

  • 값을 잘 받아 왔는지 확인해보자.
  • LoginResultActivity.java 에서 위와 같이 입력한다.
  • line 30 : intent.getDataString() 으로 하지 않은 이유는 MainActivity.java 에서 값을 던질 때 putExtra()로 보냈기 때문이다.

  • 빌드를 한 후, 이메일과 패스워드를 입력하고 로그인 버튼을 누르면 위와 같이 오류가 뜬다. 이를 해결해보자.

  • app — src — res — AndroidManifest.xml에 Activity를 정의해줘야한다.
  • line19–20 과 같이 정의해준다.

  • 그럼 성공적으로 로그인 정보를 스크린에 띄울 수 있다.

[19. 입력한 값이 올바른지 체크하기]

  • MainActivity.java 에 addTextChangedListener을 이용한 코드를 작성한다.
  • 이메일은 123@gmail.com 이고 패스워드는 1234일 때만 로그인 버튼을 클릭할 수 있도록 하는 것이 목표이다.
  • 어떤 값이 들어가는지 알기 위해 Log를 찍어보자.(Logcat 확인)
  • line 48의 s 가 입력한 이메일 값이라는 것을 알 수 있었다.
  • 전역변수의 데이터 타입을 CharSequence로 하던가, s를 String형으로 바꿔줘야 한다.

  • 주의 : toString()을 보면 string 을 return 한다고 했는데 null 이면 에러가 발생할 수 있으니 null 값을 체크한 후 toString 을 해야한다.

  • if 괄호 안의 식이 살짝 지저분하다.

  • validation() 함수를 이용하여 간단하게 만들어 보았다.
  • validation() 의 리턴 값에 따라 클릭이 가능하게 혹은 가능하지 않게 설정할 수 있다.
  • 실행하면 오류가 발생한다.
  • 첫번째 오류 : 아무것도 타이핑하지 않고 Log in 버튼을 눌러도 클릭이 된다. (해결 방법 => activity_login.xml파일에서 Log in 버튼이 있는 LinearLayout 의 clickable 을 설정한 코드를 지워준다.)
  • 두번째 오류 : 올바르게 입력하고 Log in 버튼을 눌렀을 땐 클릭이 되지 않는다.

  • validation() 함수를 위와 같이 수정해주면 된다. => 두번째 오류 해결
  • 자바에서는 문자열 비교는 equals()로 해야하기 때문이다.
728x90
728x90

참고 : 유투브 — 센치한 개발자

 

 

 

[레이아웃]

  • MainActivity.java 파일의 line12를 보면 activity_main.xml 파일과 연결이 되어 있는 것을 확인할 수 있다.

 

 

[1. LinearLayout]

  • 화면을 구성하기 위해서 가장 바깥의 레이아웃을 정해야 한다.
  • RelativeLayout 혹은 LinearLayout 중에 선택할 수 있다.
  • LinearLayout 안의 요소들은 가로 혹은 세로로 배치가 된다.

 

 

  • LinearLayout 안에 3개의 TextView를 horizontal 방향으로 배치해 보았다.

 

  • vertical 방향으로 배치해 보았다.

 

 

[2. RelativeLayout]

  • RelativeLayout 안의 요소들은 서로 관계를 정의해야 한다.
  • 아직 관계를 정의해주지 않아서 TextView 세 개가 함께 겹쳐있는 것을 확인할 수 있다.

 

line 12,20,28 추가

  • 부모(RelativeLayout)와 자식(TextView)의 관계를 설정해 준 상태이다.
  • 화면의 가운데로 1,2,3 이 간 것을 확인할 수 있다.
  • 아직 자식들간의 관계를 설정해주지 않아 1,2,3 이 함께 겹쳐있는 상태이다.

 

  • 1,2,3을 화면 가운데에 가로로 배치해보자.
  • line 18 : 2를 기준으로 잡기 위해 id를 설정한다.
  • line 23: 2를 부모(RelativeLayout)를 기준으로 center 에 위치시킨다.
  • line12,13 : 1을 2의 왼쪽으로 배치시킨다.
  • line 31,32 : 마찬가지로 3을 2의 오른쪽으로 배치시킨다.

 

  • 이번엔 1,2,3 을 화면 가운데에 세로로 배치해보자.
  • 위와 같은 방식으로 하면 되는데, 2를 기준으로 잡고 ‘1과 2의 관계’ ‘2와 3의 관계’ 를 설정해주면 된다.
  • 앱 구현 시 퍼포먼스 측면에서 RelativeLayout이 더 좋다.

 

 

[3. Layout 안에 Layout 배치하기]

 

 

[4. 화면 등분 하기]

  • line 6 : 전체 합을 9로 설정한다.
  • line 14,24,35 : 화면을 각각 3/9, 즉 1/3 씩 차지하겠다는 뜻이다.

 

  • line 14,24,35 : weight를 1/9,7/9,1/9 로 나눈 결과이다.

 

728x90

+ Recent posts