자바 안드로이드 정리 - 2
커스텀뷰에서의 터치 이벤트
- 싱글터치 일때 :
@Override
public boolean onTouchEvent(MotionEvent event) {
float eventX = event.getX();
float eventY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
path.moveTo(eventX, eventY);
return true;
case MotionEvent.ACTION_MOVE:
path.lineTo(eventX, eventY);
break;
case MotionEvent.ACTION_UP:
break;
default:
return false;
}
invalidate();
return true;
}
ACTION_DOWN
누르는 동작이 시작됨
ACTION_UP
누르고 있다가 땔때 발생함
ACTION_MOVE
누르는 도중에 움직임
ACTION_CANCEL
터치 동작이 취소됨
ACTION_OUTSIDE
터칠가 현재의 위젯을 벗어남
- 멀티터치 일때 :
@Override
public boolean onTouchEvent(MotionEvent event) {
int index = event.getActionIndex();
int id = event.getPointerId(index);
int action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
x[id] = (int) event.getX(index);
y[id] = (int) event.getY(index);
touching[id] = true;
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_CANCEL:
touching[id] = false;
break;
}
invalidate();
return true;
}
추가되는 터치 이벤트
ACTION_POINTER_DOWN
첫 번째 포인터 이외의 포인터에 대하여 발생된다. 포인터 데이터는 getActionIndex()이 반환하는 인덱스에 저장된다.
ACTION_POINTER_UP
마지막 포인터가 아닌 다른 포인터가 화면에서 없어지면 발생된다.
첫번째 터치(index=0,id=0), 두번째 터치(index=1,id=1)가 있다고 할때 만약 첫번째 터치를 때게 된다면, 두번째 터치는 id=1로 유지하고, index는 1 -> 0으로 바뀌게 된다. 이후 세번째 터치를 하면 그 터치는 index=1,id=0으로 부여받게 된다.
컨텍스트 메뉴 종류
플로팅 컨텍스트 메뉴
: 사용자가 항목 위에서 오래 누르기를 하면 메뉴가 대화상자처럼 떠서 표시된다.컨텍스트 액션 모드
: 현재 선택된 항목에 관련된 메뉴가 액션바에 표시된다. 여러 항목을 선택하여 특정한 액션을 한꺼번에 적용할 수 있다.
Canvas, Paint
- Canvas 클래스는 그림을 그리는 캔버스에 해당되고, Paint 클래스는 색상이나 선의 스타일 등과 같은 그리기 속성을 가지고 있는 클래스
- 주로 View클래스의 onDraw(Canvas canvas)를 오버라이딩하면서 사용한다.
폰트
- onDraw내부에서
내부 폰트 예제 :
...
Typeface t;
t = Typeface.create(Typeface.DEFAULT, Typeface.NORMAL);
paint.setTypeface(t);
canvas.drawText("DEFAULT 폰트", 10, 400, paint);
외부 폰트 예제 :
...
myFont = Typeface.createFromAsset(getContext().getAssets(),
"animeace2_ital.ttf");
paint.setTypeface(myFont);
서피스 뷰
-
서피스뷰는 사용자 인터페이스와는 별도로 애플리케이션에게 그림을 그릴 수 있는 화면을 제공한다.
-
예제 :
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MySurfaceView w = new MySurfaceView(this);
setContentView(w);
}
}
class Ball {
int x, y, xInc = 1, yInc = 1;
int diameter;
static int WIDTH = 1080, HEIGHT = 1920;
public Ball(int d) {
this.diameter = d;
x = (int) (Math.random() * (WIDTH - d) + 3);
y = (int) (Math.random() * (HEIGHT - d) + 3);
xInc = (int) (Math.random() * 30 + 1);
yInc = (int) (Math.random() * 30 + 1);
}
public void paint(Canvas g) {
Paint paint = new Paint();
if (x < diameter || x > (WIDTH - diameter))
xInc = -xInc;
if (y < diameter || y > (HEIGHT - diameter))
xInc = -yInc;
x += xInc;
y += yInc;
paint.setColor(Color.RED);
g.drawCircle(x,y,diameter,paint);
}
}
class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {
public Ball basket[] = new Ball[10];
private MyThread thread;
public MySurfaceView(Context context) {
super(context);
SurfaceHolder holder = getHolder();
holder.addCallback(this);
thread = new MyThread(holder);
for (int i=0; i<10; i++)
basket[i] = new Ball(20);
}
public MyThread getThread() {
return thread;
}
@Override
public void surfaceCreated(@NonNull SurfaceHolder holder) {
thread.setRunning(true);
thread.start();
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) { }
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
boolean retry = true;
thread.setRunning(false);
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
class MyThread extends Thread {
private boolean mRun = false;
private SurfaceHolder mSurfaceHolder;
public MyThread(SurfaceHolder surfaceHolder) {
mSurfaceHolder = surfaceHolder;
}
@Override
public void run() {
while (mRun) {
Canvas c = null;
try {
c = mSurfaceHolder.lockCanvas(null);
c.drawColor(Color.BLACK);
synchronized (mSurfaceHolder) {
for (Ball b : basket) {
b.paint(c);
}
}
} finally {
if (c != null) {
mSurfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
public void setRunning(boolean b) {
mRun = b;
}
}
}
액티비티와 인텐트
-
애플리케이션 : 한 개 이상의 액티비티들로 구성된다. 액티비티들은 애플리케이션 안에서 느슨하게 묶여 있다.
-
액티비티 : 애플리케이션을 구성하는 빌딩 블록
-
태스크 : 스택에 있는 액티비티
-
액티비티 스택 : back키를 누르면 현재 액티비티를 제거하고 이전 액티비티로 되돌아 간다. 스택안에 같은 액티비티가 여러 개 들어가 있을 수도 있다.
-
인텐트 : 다른 액티비티를 시작하려면 액티비티의 실행에 필요한 여러가지 정보들을 보내주어야 한다. 정보를 인텐트에 실어서 보낸다.
-
명시적 인텐트 : 실행하고자 하는 액티비티의 이름을 적어 준다.
startActivity
를 사용하는 경우:
Intent in = new Intent(MainActivity.this, SubActivity.class);
startActivityForResult(in);
startActivityForResult
를 사용하는 경우:
보내는 쪽
Intent in = new Intent(MainActivity.this, SubActivity.class);
startActivityForResult(in, GET_STRING);
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == GET_STRING) {
if (resultCode == RESULT_OK) {
text.setText(data.getStringExtra("INPUT_TEXT"));
}
}
}
받는 쪽
Intent intent = new Intent();
intent.putExtra("INPUT_TEXT", edit.getText().toString());
setResult(RESULT_OK, intent);
finish();
이런식으로 onActivityResult
에서 requestCode,resultCode를 이용해 코드를 체크 할 수있다. 보통 어떤 엑티비티끼리 통신했는지 확인해기위해 사용한다.
- 암시적 인텐트
public void onClick(View view) {
Intent intent = null;
switch (view.getId()) {
case R.id.web:
intent = new Intent(Intent.ACTION_VIEW,
Uri.parse("http://www.google.com"));
break;
case R.id.call:
intent = new Intent(Intent.ACTION_DIAL,
Uri.parse("tel:(+82)12345789"));
break;
case R.id.map:
intent = new Intent(Intent.ACTION_VIEW,
Uri.parse("geo:37.30,127.2?z=10"));
break;
case R.id.contact:
intent = new Intent(Intent.ACTION_VIEW,
Uri.parse("content://contacts/people/"));
break;
}
if (intent != null) {
startActivity(intent);
}
}
멀티태스킹
- 동시에 여러 태스크를 실행
- 현재의 태스크를 배경으로 보내고 다른 태스크를 전경에서 시작할 수 있다.
액티비티
-
실행 상태 : 액티비티가 전경에 위치하고 있으며 사용자의 포커스를 가지고 있다.
-
일시멈춤 상태 : 다른 액티비티가 전경에 있으며 포커스를 가지고 있지만 현재 액티비티의 일부가 아직도 화면에서 보이고 있는 상태이다.
-
onCreate()
: 액티비티가 생성되면서 호출 / 중요한 구성요소들을 초기화 -
onPause()
: 사용자가 액티비티를 떠나고 있을 때, 이 메소드가 호출 / 그 동안 이루어졌던 변경사항을 저장 -
정지 상태 : 액티비티는 배경에 위치한다.
-
액티비티 생성
onCreate() -> onStart() -> onResume()
-
일시멈춤 상태
onPause() 했다가 onResume()으로 복귀
-
정지되었다가 다시 실행하는 경우
onStop() 이 불려지면서 정지 -> 다시 실행 -> onRestart() -> onStart() -> onResume()
-
액티비티 상태 저장
예제 :
public class MainActivity extends Activity {
Button button1;
TextView text;
int count = 0;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState != null) {
count = savedInstanceState.getInt("count");
text.setText("현재 개수=" + count);
}
text = (TextView) findViewById(R.id.text);
button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
count++;
text.setText("현재 개수=" + count);
}
});
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Log.i("LifeCycle","onSaveInstanceState() 호출");
outState.putInt("count", count);
}
}
리소스
- 기본 리소스 : 장치 구성과 상관없이 기본적으로 사용되는 리소스이다.
- 대체 리소스 : 대체 리소스는 특정한 장치 구성을 위하여 설계된 리소스이다. 기본 디렉토리 이름에 특정한 장치 구성의 이름을 붙인 디렉토리에 리소스들이 저장.
보안
- 안드로이드에서 각 애플리케이션은 자신의 프로세스 안에서 실행한다.
- 애플리케이션은 다른 애플리케이션을 건드릴 수 없다. 이것을 Sandboxing 이라고 한다.
Author And Source
이 문제에 관하여(자바 안드로이드 정리 - 2), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@edhz8888/자바-안드로이드-정리-2저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)