๊ด€๋ฆฌ ๋ฉ”๋‰ด

Welcome! Everything is fine.

[Android] ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ๋ณธ๋ฌธ

Android

[Android] ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ

๊ฐœ๋ฐœ๊ณฐ๋ฐœ 2022. 3. 2.
728x90

๐Ÿ“Œ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ๋ฐฉ์‹ 

โœ” ๋Œ€ํ‘œ์ ์ธ ์ด๋ฒคํŠธ ์œ ํ˜•

์†์„ฑ ์„ค๋ช…
ํ„ฐ์น˜ ์ด๋ฒคํŠธ ํ™”๋ฉด์„ ์†๊ฐ€๋ฝ์œผ๋กœ ๋ˆ„๋ฅผ ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ
ํ‚ค ์ด๋ฒคํŠธ ํ‚คํŒจ๋“œ๋‚˜ ํ•˜๋“œ์›จ์–ด ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅผ ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ
์ œ์Šค์ฒ˜ ์ด๋ฒคํŠธ ํ„ฐ์น˜ ์ด๋ฒคํŠธ ์ค‘์—์„œ ์Šคํฌ๋กค๊ณผ ๊ฐ™์ด ์ผ์ • ํŒจํ„ด์œผ๋กœ ๊ตฌ๋ถ„๋˜๋Š” ์ด๋ฒคํŠธ
ํฌ์ปค์Šค ๋ทฐ๋งˆ๋‹ค ์ˆœ์„œ๋Œ€๋กœ ์ฃผ์–ด์ง€๋Š” ํฌ์ปค์Šค
ํ™”๋ฉด ๋ฐฉํ–ฅ ์„ค์ • ํ™”๋ฉด์˜ ๋ฐฉํ–ฅ์ด ๊ฐ€๋กœ์™€ ์„ธ๋กœ๋กœ ๋ฐ”๋€œ์— ๋”ฐ๋ผ ๋”ฐ๋ผ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ

๐Ÿ“Œํ„ฐ์น˜ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌํ•˜๊ธฐ

์ฑ…์— ์žˆ๋Š” ์˜ˆ์ œ๋ฅผ ์‹ค์Šตํ•ด๋ณด์•˜๋‹ค. ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋ณต์žกํ•ด๋ณด์ด์ง€๋งŒ ์ฐฌ์ฐฌํžˆ ์‚ดํŽด๋ณด๋ฉด ์ดํ•ดํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์ฑ…์—์„œ ๋‚ด๊ฐ€ ์ดํ•ดํ•œ ๋‚ด์šฉ์„ ๋ฒˆํ˜ธ๋ฅผ ๋งค๊ฒจ ์ •๋ฆฌํ•ด๋ณด์•˜๋‹ค.

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);

        View view = findViewById(R.id.view);
        view.setOnTouchListener(new View.OnTouchListener(){
           @Override
           public boolean onTouch(View view, MotionEvent motionEvent){
               int action = motionEvent.getAction();

               float curX = motionEvent.getX();
               float curY = motionEvent.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");
    }
}

โ‘  ํ…์ŠคํŠธ๋ทฐ(textView)์™€ ๋งจ ์œ„ ํŒŒ๋ž€์ƒ‰ ๋ทฐ(view)๋ฅผ findViewById ๋ฉ”์„œ๋“œ๋กœ ์ฐธ์กฐ

โ‘ก setOnTouchListener ๋ฉ”์„œ๋“œ ํ˜ธ์ถœํ•˜์—ฌ ๋ฆฌ์Šค๋„ˆ ๋“ฑ๋ก(new ์—ฐ์‚ฐ์ž๋ฅผ ํ†ตํ•ด OnTouchListener ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋ฉด์„œ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋ฆฌ์Šคํ„ฐ ๊ฐ์ฒด ์ „๋‹ฌ)

โ‘ข ๋ทฐ๊ฐ€ ํ„ฐ์น˜๋˜๋ฉด ํ•ด๋‹น ๋ฆฌ์Šค๋„ˆ ๊ฐ์ฒด์˜ onTouch ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ(MotionEvent ๊ฐ์ฒด๊ฐ€ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ „๋‹ฌ)

โ‘ฃ getAction ๋ฉ”์„œ๋“œ๋กœ ํ™•์ธํ•œ ์•ก์…˜์ •๋ณด๋ฅผ action ๋ณ€์ˆ˜์— ๋„ฃ์Œ

โ‘ค getX, getY ๋ฉ”์„œ๋“œ๋กœ ํ™•์ธํ•œ ์ขŒํ‘œ๊ฐ’์„ curX, curY ๋ณ€์ˆ˜์— ๋„ฃ์Œ

โ‘ฅ if~else if~else ๊ตฌ๋ฌธ์œผ๋กœ ์•ก์…˜์ •๋ณด ๊ฐ’(action)๊ณผ MotionEvent ํด๋ž˜์Šค์— ์ •์˜๋œ ์ƒ์ˆ˜ ๊ฐ’์„ ๋น„๊ต

โ‘ฆ textView์— ๊ธ€์ž๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์ถœ๋ ฅํ•˜๋Š” println ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœ

โ‘ง ์‹คํ–‰ํ•ด์„œ ์ฒซ๋ฒˆ์งธ ๋ทฐ๋ฅผ ํด๋ฆญํ–ˆ๋‹ค ๋–ผ๊ฑฐ๋‚˜ ํด๋ฆญํ•œ ์ฑ„๋กœ ์›€์ง์ด๋ฉด ํ…์ŠคํŠธ๊ฐ€ ์ฐํž˜

 

์•ฑ์„ ์‹คํ–‰ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์†๊ฐ€๋ฝ ์ƒํƒœ๋ฅผ ๊ตฌ๋ถ„ํ•˜๊ฑฐ๋‚˜ ์†๊ฐ€๋ฝ์ด ์–ด๋Š ์œ„์น˜์— ์žˆ๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“Œ์ œ์Šค์ฒ˜ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌํ•˜๊ธฐ

  • ์ œ์Šค์ฒ˜ ์ด๋ฒคํŠธ๋Š” ํ„ฐ์น˜ ์ด๋ฒคํŠธ ์ค‘์—์„œ ์Šคํฌ๋กค ๋“ฑ์„ ๊ตฌ๋ณ„ํ•œ ํ›„ ์•Œ๋ ค์ฃผ๋Š” ์ด๋ฒคํŠธ์ด๋‹ค.
  • GestureDetector ํด๋ž˜์Šค๋กœ ์ œ์Šค์ฒ˜ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค. ์ด ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  ํ„ฐ์น˜ ์ด๋ฒคํŠธ๋ฅผ ์ „๋‹ฌํ•˜๋ฉด GestureDetector ๊ฐ์ฒด์—์„œ ๊ฐ ์ƒํ™ฉ์— ๋งž๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

๐Ÿ“Œํ‚ค ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌํ•˜๊ธฐ

  • onKeyDown ๋ฉ”์„œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•˜์—ฌ ์ฒ˜๋ฆฌํ•œ๋‹ค.
  • onKeyDown์˜ ํŒŒ๋ผ๋ฏธํ„ฐ keyCode : ์–ด๋–ค ํ‚ค๊ฐ€ ์‚ฌ์šฉ๋˜๋Š”์ง€ ๊ตฌ๋ณ„ํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค.
  • onKeyDown์˜ ํŒŒ๋ผ๋ฏธํ„ฐ keyEvent : ํ‚ค ์ž…๋ ฅ ์ด๋ฒคํŠธ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์•Œ๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค.

๋‹ค์Œ์€ ์‹œ์Šคํ…œ [BACK] ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ ํ† ์ŠคํŠธ ๋ฉ”์„ธ์ง€๊ฐ€ ํ‘œ์‹œ๋˜๋Š” ์˜ˆ์ œ์ด๋‹ค. MainActivity ํด๋ž˜์Šค์— ๋งˆ์šฐ์Šค ์˜ค๋ฅธ์ชฝ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๊ณ  [Generate... - Override Methods... - onKeyDown ๋ฉ”์„œ๋“œ]๋ฅผ ์„ ํƒํ•œ๋‹ค.

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

        if(keyCode == KeyEvent.KEYCODE_BACK){
            Toast.makeText(this, "์‹œ์Šคํ…œ [BACK] ๋ฒ„ํŠผ์ด ๋ˆŒ๋ ธ์Šต๋‹ˆ๋‹ค.", Toast.LENGTH_LONG).show();

            return true;
        }

        return false;
    }

์‹คํ–‰ํ™”๋ฉด์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

๐Ÿ“Œ๋‹จ๋ง ๋ฐฉํ–ฅ์„ ์ „ํ™˜ํ–ˆ์„ ๋•Œ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌํ•˜๊ธฐ

โœ” ๋‹จ๋ง ๋ฐฉํ–ฅ ๋ฐ”๊ฟจ์„ ๋•Œ ๋‹ค๋ฅธ ํ™”๋ฉด ๋ณด์ด๊ฒŒ ํ•˜๊ธฐ

๋‹จ๋ง์˜ ๋ฐฉํ–ฅ์ด ๋ฐ”๋€Œ์—ˆ์„ ๋•Œ๋Š” ์•กํ‹ฐ๋น„ํ‹ฐ๊ฐ€ ์—†์–ด์กŒ๋‹ค๊ฐ€ ๋‹ค์‹œ ๋ณด์ด๊ฒŒ ๋œ๋‹ค. ์„ธ๋กœ ๋ฐฉํ–ฅ์˜ XML ๋ ˆ์ด์•„์›ƒ๊ณผ ๊ฐ€๋กœ ๋ฐฉํ–ฅ์˜ XML ๋ ˆ์ด์•„์›ƒ์„ ๋”ฐ๋กœ ๋งŒ๋“ค์–ด๋‘๋Š”๊ฒŒ ์ข‹๋‹ค. ์‹ค์Šต์—์„œ๋Š” layout ํด๋”์™€ ๊ฐ™์€ ์—ญํ• ์„ ํ•˜๋Š”  layout-land ๋ผ๋Š” ์ƒˆ๋กœ์šด ํด๋”๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค. layout-land ํด๋” ์•ˆ์— ๋“ค์–ด์žˆ๋Š” XML ๋ ˆ์ด์•„์›ƒ ํŒŒ์ผ(activity_main.xml)์€ ๋‹จ๋ง์ด ๊ฐ€๋กœ ๋ฐฉํ–ฅ์œผ๋กœ ๋ณด์ผ ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค.

์œ„ ์˜ˆ์ œ์—๋Š” layout ํด๋”์˜ activity_main.xml ์—์„œ๋Š” '์„ธ๋กœ ๋ฐฉํ–ฅ'์ด๋ผ๊ณ  ์“ฐ๊ณ , layout-land ํด๋”์˜ activity_main.xml ์—์„œ๋Š” '๊ฐ€๋กœ ๋ฐฉํ–ฅ'์ด๋ผ๊ณ  ์“ด ์•ฑ์„ ์‹คํ–‰์‹œํ‚จ ๊ฒฐ๊ณผ๋‹ค.

โœ” ๋‹จ๋ง ๋ฐฉํ–ฅ์ด ๋ฐ”๋€” ๋•Œ ์•กํ‹ฐ๋น„ํ‹ฐ์˜ ์ƒํƒœ ์•Œ์•„๋ณด๊ธฐ

  • ์ˆ˜๋ช… ์ฃผ๊ธฐ(Life Cycle) ๋˜๋Š” ์ƒ๋ช… ์ฃผ๊ธฐ ๋ฉ”์„œ๋“œ : ํ™”๋ฉด์˜ ์ƒํƒœ์— ๋”ฐ๋ผ ์‹œ์Šคํ…œ์ด ์ž๋™์œผ๋กœ ํ˜ธ์ถœํ•ด์ฃผ๋Š” ๋ฉ”์„œ๋“œ
  • ์•„๋ž˜ ์ฝ”๋“œ์—์„œ๋Š” onStart, onStop, onDestroy ๋ฉ”์„œ๋“œ๋ฅผ ๋ชจ๋‘ ์žฌ์ •์˜ํ•˜๊ณ , ํ•ด๋‹น ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰๋  ๋•Œ ํ† ์ŠคํŠธ ๋ฉ”์„ธ์ง€๊ฐ€ ๋ณด์ด๋„๋ก ํ–ˆ๋‹ค. ํ† ์ŠคํŠธ ๋ฉ”์„ธ์ง€๋ฅผ ํ†ตํ•ด ๋‹จ๋ง์˜ ๋ฐฉํ–ฅ์„ ๋ฐ”๊ฟ€ ๋•Œ๋งˆ๋‹ค ์•กํ‹ฐ๋น„ํ‹ฐ๊ฐ€ ์—†์–ด์กŒ๋‹ค๊ฐ€ ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์ง€๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์•กํ‹ฐ๋น„ํ‹ฐ๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์— ๋งŒ๋“ค์–ด์งˆ ๋•Œ → onCreate ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
  • ํ™”๋ฉด์— ๋ณด์ด๊ธฐ ์ „์— → onStart ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
  • ํ™”๋ฉด์— ๋ณด์ด๋‹ค๊ฐ€ ์—†์–ด์งˆ ๋•Œ  → onStop ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
  • ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์—†์–ด์งˆ ๋•Œ → onDestroy ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        showToast("onCreate ํ˜ธ์ถœ๋จ.");
    }

    @Override
    protected void onStart(){
        super.onStart();
        showToast("onStart ํ˜ธ์ถœ๋จ.");
    }

    @Override
    protected void onStop(){
        super.onStop();
        showToast("onStop ํ˜ธ์ถœ๋จ.");
    }

    @Override
    protected void onDestroy(){
        super.onDestroy();
        showToast("onDestroy ํ˜ธ์ถœ๋จ.");
    }

    private void showToast(String data) {
        Toast.makeText(this, data, Toast.LENGTH_LONG).show();
    }

}

โœ” ์ƒํƒœ ์ €์žฅํ–ˆ๋‹ค๊ฐ€ ๋ณต์›ํ•˜๊ธฐ(onSaveInstanceState๋ฉ”์„œ๋“œ)

  • ๋‹จ๋ง์˜ ๋ฐฉํ–ฅ์ด ๋ฐ”๋€” ๋•Œ ์•กํ‹ฐ๋น„ํ‹ฐ๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์‚ฌ๋ผ์กŒ๋‹ค๊ฐ€ ์ƒˆ๋กœ ๋งŒ๋“ค์–ด์ง€๋ฏ€๋กœ, ์•กํ‹ฐ๋น„ํ‹ฐ ์•ˆ์— ์„ ์–ธํ•œ ๋ณ€์ˆ˜์˜ ๊ฐ’๋„ ์‚ฌ๋ผ์ง„๋‹ค. ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด onSaveInstanceState ์ฝœ๋ฐฑ ๋ฉ”์„œ๋“œ๊ฐ€ ์ œ๊ณต๋œ๋‹ค.
  • onSaveInstanceState ๋ฉ”์„œ๋“œ : ์•กํ‹ฐ๋น„ํ‹ฐ๊ฐ€ ์ข…๋ฃŒ๋˜๊ธฐ ์ „์˜ ์ƒํƒœ๋ฅผ ์ €์žฅํ•ด๋‘๊ณ , onCreate ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ ๋  ๋•Œ ์ „๋‹ฌ๋˜๋Š” ๋ฒˆ๋“ค ๊ฐ์ฒด๋กœ ๋ณต์›ํ•œ๋‹ค.

์‹ค์Šต ์ฝ”๋“œ์ธ๋ฐ ์™œ ์ž๊พธ ๋‹จ๋ง์„ ๊ฐ€๋กœ๋กœ ๋Œ๋ฆด ๋•Œ๋งˆ๋‹ค ๊ฐ•์ œ ์ข…๋ฃŒ๋˜๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ๋‹ค..๊ฒฝ๊ณ  ๋œจ๋Š” ๊ฒƒ๋„ ๋‹ค ํ•ด๊ฒฐํ–ˆ๋Š”๋ฐ ์•„์ง ๋ฌธ์ œ๋ฅผ ๋ชป์ฐพ์•˜๋‹ค.

public class MainActivity extends AppCompatActivity {

    String name;
    EditText editText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editText = findViewById(R.id.editText);

        Button button = findViewById(R.id.button);
        button.setOnClickListener(view -> {
            name = editText.getText().toString();
            showToast("์ž…๋ ฅ๋œ ๊ฐ’์„ ๋ณ€์ˆ˜์— ์ €์žฅํ–ˆ์Šต๋‹ˆ๋‹ค : " + name);
        });

        if (savedInstanceState != null){
            name = savedInstanceState.getString("name");
            showToast("๊ฐ’์„ ๋ณต์›ํ–ˆ์Šต๋‹ˆ๋‹ค : " + name);
        }
    }

    private void showToast(String data) {
        Toast.makeText(this, data, Toast.LENGTH_LONG).show();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        outState.putString("name",name);
    }
}

โœ” ๋‹จ๋ง ๋ฐฉํ–ฅ์ด ๋ฐ”๋€” ๋•Œ ์•กํ‹ฐ๋น„ํ‹ฐ ์œ ์ง€ํ•˜๋Š” ๋ฐฉ๋ฒ•

  • ์•กํ‹ฐ๋น„ํ‹ฐ๋Š” ๋ฐ”๋€Œ์ง€ ์•Š๊ณ  ๋‹จ์ˆœํžˆ ํ™”๋ฉด์— ๋ณด์ด๋Š” ๋ ˆ์ด์•„์›ƒ๋งŒ ๋ฐ”๊พธ๊ณ  ์‹ถ๋‹ค๋ฉด ์•กํ‹ฐ๋น„ํ‹ฐ๋ฅผ ๊ตณ์ด ์—†์•ด๋‹ค๊ฐ€ ๋‹ค์‹œ ๋งŒ๋“ค ํ•„์š”๊ฐ€ ์—†๋‹ค. ๋”ฐ๋ผ์„œ ์•กํ‹ฐ๋น„ํ‹ฐ๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ๋”ฐ๋กœ ์ œ๊ณต๋œ๋‹ค.