이 글은 [Do it! 안드로이드 앱 프로그래밍](저자 정재곤, 출판사 이지스퍼블리싱) 교재를 보고 공부하며 정리한 글임.
string.xml에 저렇게 추가해두면
textview에서 text에 저렇게만 적어도 뜬다.
또한 이렇게 하면 다국어 지원이 가능하다
텍스트뷰의 속성들이 여러가지 있다
textColor
textStyle
textSize ... 등등
maxlines를 1로 해주면 저렇게 한줄로 표현이 가능하다
lineSpacingExtra는 줄간격을 조정할 수 있다
checked를 true 로 하거나 false로 하거나에 따라서 맨 처음에 체크표시를 어떻게 보일것인지 결정할 수 있다
RadioGroup 안에 RadioButton이 들어간다.
두번째 버튼에 margin left 에 10dp 를 줘서 간격을 둘 수도 있다.
text 중 inputType 속성을 통해서 키패드가 바뀐다.
숫자만 입력할 수 있는지, 아니면 글자만 입력가능한지 등등.
srcCompat이라는 속성을 통해 이미지를 설정한다
scaleType 유형에 따라서 이미지가 어떻게 보일건지를 설정할 수도 있다.
드로어블은 다양하지만 가장 많이 사용하는건 상태 드로어블과 셰이프 드로어블이다.
이렇게 drawable안에 finger_drawable.xml 을 따로 만들어서
이렇게 버튼 background 속성을 finger_drawable.xml 로 넣어주면
버튼이 저 기능을 갖게된다(누르면 1이미지 안누르면 2 이미지... 이런식으로)
<셰이프 드로어블>
xml로 도형을 그리기
drawable 에 rect_drawable 리소스 파일을 만들어 주고 shape 로 바꾸어 준다
그리고 내용을 작성하면 오른쪽에 내가 만든 도형이 뜬다
activity_main.xml 에 버튼을 새로 하나 만들고 background 를 내가 방금 만든 도형으로 해주려고 한다
근데 저 backgroundTint 때문에 원하는 대로 보이지 않고
보라색으로 뜬다.
https://stackoverflow.com/questions/65477334/android-button-background-color-not-changing-on-xml
Android Button background color not changing on xml
Android Stidio 4.1.1 SDK 29 (Android 10) I trying to change button background color on xml, but it doesn't changed. here's my code
stackoverflow.com
스택오버플로우에 원인이 나와있다고 한다.
문제는 앱의 테마를 Theme.MaterialComponents 이걸 기본 default 로 사용하면서 발생하는 문제라고 한다.
https://blog.naver.com/tjdcks0928/222217192502
안드로이드 스튜디오 - backgroundTint 사용안하기
안드로이드가 업데이트 되고나서 색이 기본색이 보라색으로 변경되었고 backgroundTint를 사용을 안하면 ...
blog.naver.com
drawable 파일에 리소스 파일을 하나 더 만들어 줬다
이건 그라데이션이 들어간 도형이다
gradient 를 써줬다
그리고 ConstraintLayout 의 background를 방금 내가 만든 그라데이션 도형으로 해줬다
border_drawable.xml 도 작성해준다
#00000000000... 요건 투명한거임
버튼 만들고 background 적용도 했는데 오류가 뜬다
The view is no constrained 어쩌구....
콘텐츠들 간에 연결이 있어야 하는데 없어서 생기는 문제라고 한다
저 마술봉 버튼이 infer constraints? 인데 누르면 바로 뷰들간의 연결을 만들어 준다
<이벤트 처리 이해하기>
MyEvent 라는 프로젝트를 새로 만들어 주고
LinearLayout으로 바꿔준후
세로 방향으로 3등분을 하기 위해서 orientation을 vertical 로 바꿔줌
3개를 모두 height 를 0dp 로 맞춰주기
weight 는 1씩 할당하기
package org.techtown.myevent;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
TextView textView; //변수 선언
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textView); //id를 xml 에서 찾아다가 변수에 할당
View view = findViewById(R.id.view);
view.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) { //터치 이벤트 -> 모션이벤트
int action = event.getAction();
float curX = event.getX();//눌린 곳의 x 좌표알아내기
float curY = event.getY();
if(action == MotionEvent.ACTION_DOWN){//눌린상태
println("손가락 눌림 : " + curX + " ," + curY);
}else if(action == MotionEvent.ACTION_MOVE){
println("손가락 움직임 : " + curX +" ," + curY);
}else if(action == MotionEvent.ACTION_UP){
println("손가락 뗌 : " + curX +" ," + curY);
}
return true;
}
});
}
public void println(String data){
textView.append(data + "\n");
}
}
첫번째 뷰를 findViewById() 메서드로 찾아서 참조하고
setOnTouchListener() 메서드를 호출해서 리스너를 등록한다
여기까지 터치 이벤트
터치이벤트 중에서 스크롤 등을 구별한 후 알려주는 이벤트
-> 제스처 이벤트
제스처 이벤트를 처리해주는 클래스는 GestureDetector 이고
이 객체를 만들고 터치 이벤트를 전달하면 GestureDetector 객체에서 각 상황에 맞는 메서드를 호출한다
package org.techtown.myevent;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
TextView textView; //변수 선언
GestureDetector detector;//제스처 디텍터 객체 선언
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textView); //id를 xml 에서 찾아다가 변수에 할당
View view = findViewById(R.id.view);
//setOnTouchListener
view.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) { //터치 이벤트 -> 모션이벤트
int action = event.getAction();
float curX = event.getX();//눌린 곳의 x 좌표알아내기
float curY = event.getY();
if (action == MotionEvent.ACTION_DOWN) {//눌린상태
println("손가락 눌림 : " + curX + " ," + curY);
} else if (action == MotionEvent.ACTION_MOVE) {
println("손가락 움직임 : " + curX + " ," + curY);
} else if (action == MotionEvent.ACTION_UP) {
println("손가락 뗌 : " + curX + " ," + curY);
}
return true;
}
});
//GestureDetector 의 객체 만들기
detector = new GestureDetector(this, new GestureDetector.OnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {//눌렸을때
return false;
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}
@Override
public void onLongPress(MotionEvent e) {//길게 눌렸을때
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
});
//두번째 뷰에서!
View view2 = findViewById(R.id.view2);
//두번째 뷰를 터치했을 때 발생하는 터치 이벤트를 제스처 디텍터로 전달
view2.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent motionEvent) {
detector.onTouchEvent(motionEvent);
return true;
}
});
}
public void println(String data){
textView.append(data + "\n");
}
}
마우스 포인터의 위치 변화를 일일이 계산하기는 쉽지 않다
그래서 제스처디텍터 객체는 이런 이벤트를 간단하게 처리할 수 있도록 거리나 속도값을
파라미터로 전달한다.
두 번째 뷰에는 OnTouchListener 객체를 설정하고 있다
따라서 두 번째 뷰를 터치하면 onTouch() 메서드가 호출되는거다
package org.techtown.myevent;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
TextView textView; //변수 선언
GestureDetector detector;//제스처 디텍터 객체 선언
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textView); //id를 xml 에서 찾아다가 변수에 할당
View view = findViewById(R.id.view);
//setOnTouchListener
view.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) { //터치 이벤트 -> 모션이벤트
int action = event.getAction();
float curX = event.getX();//눌린 곳의 x 좌표알아내기
float curY = event.getY();
if (action == MotionEvent.ACTION_DOWN) {//눌린상태
println("손가락 눌림 : " + curX + " ," + curY);
} else if (action == MotionEvent.ACTION_MOVE) {
println("손가락 움직임 : " + curX + " ," + curY);
} else if (action == MotionEvent.ACTION_UP) {
println("손가락 뗌 : " + curX + " ," + curY);
}
return true;
}
});
//GestureDetector 의 객체 만들기
detector = new GestureDetector(this, new GestureDetector.OnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {//눌렸을때
println("onDown 호출됨");
return true;
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}
@Override
public void onLongPress(MotionEvent e) {//길게 눌렸을때
println("onLongPress 호출됨");
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
println("onFling 호출됨 :" + velocityX + ", " + velocityY);
return true;
}
});
//두번째 뷰에서!
View view2 = findViewById(R.id.view2);
//두번째 뷰를 터치했을 때 발생하는 터치 이벤트를 제스처 디텍터로 전달
view2.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent motionEvent) {
detector.onTouchEvent(motionEvent);
return true;
}
});
}
public void println(String data){
textView.append(data + "\n");
}
}
Fling 은 빠른 속도로 스크롤 하는 거고 onDown 은 누르는 거다
두번째 뷰에 진짜로 해보면
이렇게 확인가능
이번엔 키 이벤트
*오버라이드 = 재정의
단말 방향 바꾸기
<방향 이벤트>
단말의 방향이 바뀔때 액티비티가 메모리에서 없어졌다가 새로 만들어지는구나
변수값이 그때 사라지니까 변수의 값을 저장했다가 복원하는 방법이 필요한데
그게 바로 onSaveInstanceState 구나..... 코드는 안익숙해서 복잡해보인다
단말 방향이 바뀔때 액티비티 유지하는 방법
configChanges 속성 추가 하고
속성값으로 orientation | screenSize | keyboardHidden 을 설정하면
단말의 방향이 바뀔때마다 액티비티에서 인식가능
<토스트 위치 바꾸기>
setGravity() 메서드로 토스트 뷰 보이는 위치 조정
동영상 강의 03 12 부터