봉봉의 개인 블로그

2017-06-15-P 본문

학원에서 배운것들/TEA - P

2017-06-15-P

봉봉이네 2017. 6. 15. 17:28
5) 안드로이드 앱 화면을 구성하는 요소(뷰)
1. 액티비티와 뷰
앞서 안드로이드 앱의 실행화면을 액티비티라고 설명하였지만, 사실 액티비티는 화면이라기 보다는 화면을 기지는 프로그램이다. 안드로이드 앱의 화면은 "뷰"라는 것으로 만들어지고 액티비티는 하나의 뷰 또는 뷰들을 가지고 보여주는 기능을 담당하는 프로그램이다.


2. 앞서 만든 firstapp프로젝트에서 activity_main.xml 파일을 선택하자.

Palette 패널에서 보이는 것들이 뷰의 종류이다. 뷰는 종류는 안드로이드 버전마다 조금씩 다를 수 있다. 화면에 뷰는 안드로이드7.0 API 25버전에 타겟으로 하였을때 보이는 뷰들이다.

뷰는 다시 종류에 사용방법이나 용도 모양등에 따라 Widegets, Text, Layout, Containers, Images, Date, Transitions, Advanced, Google, Design, ApplCompat등의 카테고리로 분류된다. (뷰들 크게 두분류로 분류하면 다른 뷰를 포함할 수 있는 그룹뷰와 일반뷰로 나눌 수 있는데 Layout카테고리가 대표적인 그룹뷰들이 있다)

우리가 웹개발할때 모든 HTML태그를 다 외우고 개발필요가 없듯이 안드로이드의 모든 뷰(뷰 사용법, 뷰API 등)를 알고 있을 필요는 없다. 자주사용되는 것들과 앱을 만들다가 필요한것들이 있으면 그때그때 메뉴얼이나 레퍼런스를 참조하여 사용하면 된다. 



3. firstapp프로젝트 경우 ConstraintLayout이라는 뷰와 그 안에 TextView라는 두개의 뷰를 사용하여 앱화면을 구현했다. Component Tree에서 확인 가능하다. 




4. 아래 Text탭을 눌러 activity_main.xml 텍스트모드에서도 확인이 가능하다.


6) 액티비티에 글자 출력하기
1. Toast만들어서 글자 출력하기

MainActivty파일을 선택 후 Toast출력 관련 코드(14라인)를 추가한다.

onCreate()메서드는 액티비티가 실행될때 호출되는 메서드이다. 12라인에서 화면 뷰를 가지고 와서 설정 후 14라인에 Hello라는 문자열을 가진 토스트를 하나 만들어 보여준다.

12라인의 매개변수 R.layout.activity_main 은 res폴더 아래 layout폴더 아래 activity_main.xml파일을 가르킨다.





TIP makeText() 함수는 2가지가 있다





7) 액티비티에 버턴 추가 후 버턴 클릭 이벤트 처리하기


1. firstapp프로젝트에서 TextView를 삭제하고 팔레트에서 Button을 하나 추가 후 버턴의 ID값을 "helloBtn"이라고 한다.





2. MainActivity에 버턴클릭 이벤트를 처리할 수 있는 코드를 추가한다.




3. 클릭 이벤트를 다른 방법으로 구현도 가능하다.


익명클래스를 사용


레이아웃 파일
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="jjdev.cafe.chapter21.MainActivity">
 
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="EventTest"
        android:id="@+id/button"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true" />
</RelativeLayout>
cs

액티비티 파일
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package jjdev.cafe.chapter21;
 
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
 
public class MainActivity extends AppCompatActivity {
    Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = (Button)findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity.this, "EventTest Click", Toast.LENGTH_SHORT).show();
            }
        });
    }
}
cs





이베트 리스너를 구현하여 이벤트 처리하기


레이아웃 파일
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="jjdev.cafe.chapter21.MainActivity">
 
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="EventTest"
        android:id="@+id/button"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true" />
</RelativeLayout>
cs

액티비티 파일 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package jjdev.cafe.chapter21;
 
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
 
public class MainActivity extends AppCompatActivity {
    Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = (Button)findViewById(R.id.button);
        button.setOnClickListener(new MyListener());
    }
 
    class MyListener implements View.OnClickListener {
        @Override
        public void onClick(View view) {
            Toast.makeText(MainActivity.this, "EventTest Click", Toast.LENGTH_SHORT).show();
        }
    }
}
cs







액티비티 스스로 이벤트 리스너를 구현


레이아웃 파일
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="jjdev.cafe.chapter21.MainActivity">
 
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="EventTest"
        android:id="@+id/button"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true" />
</RelativeLayout>
cs

액티비티 파일
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package jjdev.cafe.chapter21;
 
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
 
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    Button button;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = (Button)findViewById(R.id.button);
        button.setOnClickListener(this);
    }
 
    @Override
    public void onClick(View view) {
        Toast.makeText(this, "EventTest Click",Toast.LENGTH_SHORT).show();
    }
}
cs




클릭 이벤트의 경우는 액티비티에 View타입을 매개변수로 받는 메서드를 만들고 레이아웃파일에서 메서드를 호출 설정을 할수 있다.

레이아웃 파일
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="jjdev.cafe.chapter21.MainActivity">
 
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="EventTest"
        android:id="@+id/button"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:onClick="testOnClick"/>
</RelativeLayout>
cs

액티비티 파일
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package jjdev.cafe.chapter21;
 
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
 
public class MainActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
 
    public void testOnClick(View view) {
        Toast.makeText(this,"EventTest Click",Toast.LENGTH_SHORT).show();
    }
}
cs



8) 클릭 외 다른 이벤트 처리 : SeekBar 이벤트 처리

대부분의 뷰들은 클릭 이벤트 처리 만으로 충분하지만 특별한 이벤트가 발생하는 뷰들도 있다. 다른 뷰들은 다음에 구현해 보도록 하고 여기서는 SeekBar와 관련된 이벤트 처리 코드를 구현해 보자.

1. 레이아웃 xml파일에서 수직리니어레이아웃(안에 수직으로 뷰들을 가지는 그룹뷰어)을 먼저 추가 후 TextView와 SeekBar를 추가한다. 

SeekBar 속성 중 최대값(max)은 100으로 시작할대 가질값은(progress) 0으로 설정




2. MainActivity 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.example.firstapp.firstapp;
 
import android.app.Activity;
import android.os.Bundle;
import android.widget.SeekBar;
import android.widget.TextView;
 
public class MainActivity extends Activity{
    private TextView volumeText;
    private SeekBar volumeBar;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        volumeText = (TextView)findViewById(R.id.volumeText);
        volumeBar = (SeekBar)findViewById(R.id.volumeBar);
 
        volumeBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            // 시크바에 변화가 있을대 마다 호출 되는 (콜백)메서드
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                volumeText.setText("volume : "+progress);
            }
            // 시크바를 움직이려고 터치시 호출되는 (콜백)메서드
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {}
            // 시크바를 움직임을 멈출때 호출되는 (콜백)메서드
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {}
        });
    }
}
cs

여기서 Progress 는 현재의 위치값
3. 실행 후 프로그래스를 움직이면 0~100(최대값)으로 값이 바뀐다.


Seekbar 이벤트 처리 예제


이런 예제를 만들어 보겠다.

먼저

이런식으로 화면을 만들어줍니다.

그다음

이런식으로 java 쪽 즉 MainActivity 의 내용을 채워줍니다.


설명을 조금 하자면 먼저 2~9까지는 import에 관한 내용이다.

그후 11~17번까지와 같이 사용하려는 변수들 즉 아까 화면에서 만든 seekbar 라던지 Textview 들을 가지고 와서 담을수 잇는 변수를 만들어 줍니다. 앞에 private 가 붙으면 더좋음

그후 21번줄에서 화면을 불러옵니다.

다음으로 22~ 28번 줄까지 불러온 화면에서 TextView 에 관련된 값들을 찾아서 변수 안에 담아줍니다 Seekbar 도 마찬가지 입니다.


그후 int 타입으로 변수들을 선언해 줍니다 30~33번째 출까지 그후 seek의 값들을 get 하는 getprogress를 통해서 int 값을 채워줍니다 그후 33번줄에서와 같이 Color.rgb 를 이용해 색을 표현하기 위한 (255,255,255) 이런값들을 채워주게 만들어줍니다 그후 resulttext 의 백그라운드 색을  Color.rgb를 이용해 만든 색으로 변경해주게끔 만들어줍니다.


그후 redsekk 에 대한 이벤트를 만들어줍니다 36~54번째 줄까지 만들어 줍니다 red 만 간략하게 설명 하자면 

먼저 36번줄을 보면 redseek 안에 setOnSeekBarChangeListener 메서드를 통해 이벤트를 셋해줍니다

그 이벤트의 내용은 SeekBar 안에 OnSeekBarChangeListener 로 새롭게 만든 객체이다 이 객체는 인터페이스객체 라고 생각하면 편하다 그렇게 때문에 Override 해서 사용하여야한다 38~45번줄까지는 값이 바뀔때이다 즉 SeekBar 의bar 를 움직일때 의 메서드이고 47~49 까지는 bar를 움직이기 위해서 터치하였을때이다.

그다음 51~53 까지는 bar를 움직이고 터치를 땟을때 나오는 이벤트이다.




터치 이벤트 처리 예제 만들기

먼저 프로젝츠를 새로 만들어줍니다. 그후

1.기본으로 들어와 있는 TextView의 속성을 다음과 같이 변경하자. 
Properties 우측에 화살표모양의 아이콘을 클릭하면 상세옵션 화면이 열린다. 다시 클릭하면 닫힌다.







 
2. MainActivity 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package com.example.touchapp;
 
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
 
public class MainActivity extends AppCompatActivity {
    private TextView resultView;
    private float downX;
    private float upX;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        resultView = (TextView)findViewById(R.id.resultView);
 
        resultView.setOnTouchListener(new TextView.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch(event.getAction()) {
                    // 화면에 터치시 x좌표값을 받는다
                    case MotionEvent.ACTION_DOWN:
                        downX = event.getX();
                        break;
                    // 화면에서 터치가 끝날때 x좌표값을 받아서
                    // 터치시 좌표와 비교 후 증가인지 감소 인지 분기 시킨다
                    // -10, +10은 너무 작은 값에는 반응하지 않도록
                    case MotionEvent.ACTION_UP:
                        upX = event.getX();
                        if(upX < downX-10) {
                            int resultValue = Integer.parseInt(resultView.getText().toString());
                            resultView.setText(--resultValue+"");
                        } else if(upX > downX+10) {
                            int resultValue = Integer.parseInt(resultView.getText().toString());
                            resultView.setText(++resultValue + "");
                        }
                        break;
                }
                return true;
                // 터치 이벤트의 특성상 다른 이벤트와 중복될때 먼저 진행되는데
                // true를 리턴하면 이벤트를 소멸시키면서 다음 이벤트로 진행되지 않는다.
            }
        });
    }
}
 
cs

34라인 35라인 추가 설명 : 안드로이드는 문자열을 다룰때 자바의 String타입이 아닌 CharSequence라는 자체 문자열 타입을 사용한다. 그래서 안드로이에서 생성된 문자열에 자바API를 사용할려면 먼저 toString()메서드를 이용하여 CharSequence타입을 String타입으로 변경해야 한다.


3. 터치를 왼쪽으로 이동하면 감소, 오른쪽으로 이동하면 증가 한다.

 



뷰 단일 터치 이벤트 구현하기

레이아웃 파일


1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="jjdev.cafe.chapter23.MainActivity"
    android:id="@+id/layout">
</RelativeLayout>
cs

액티비티 파일

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package jjdev.cafe.chapter23;
 
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;
 
public class MainActivity extends AppCompatActivity {
    final String TAG = "chapter23";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        RelativeLayout layout = (RelativeLayout)findViewById(R.id.layout);
        layout.setOnTouchListener(new RelativeLayout.OnTouchListener(){
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                switch(motionEvent.getActionMasked()) {
                    case MotionEvent.ACTION_DOWN:
                        Log.i(TAG,"터치 다운!");
                        break;
                    case MotionEvent.ACTION_MOVE:
                        Log.i(TAG,"터치 무브!");
                        break;
                    case MotionEvent.ACTION_UP:
                        Log.i(TAG,"터치 업!");
                        break;
                }
                return true;
            }
        });
    }
}
cs

장치에서 플리킹(터치포인트에서 다른포인트까지 이동하는 행위) 후 LOGCAT창에서 확인



10) 이벤트 중복시 다음 이벤트로 전달

1. 이벤트 소비하기

하나의 뷰에 두개 이상의 이벤트가 발생하는 경우 진행된 콜백메서드의 리턴값에 따라 다음 이벤트로 이벤트를 보낼수도 있고 보내지 않을 수도 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package jjdev.cafe.chapter21;
 
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
 
public class MainActivity extends AppCompatActivity{
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        final Button button = (Button) findViewById(R.id.button);
 
        button.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity.this"Click!", Toast.LENGTH_SHORT).show();
            }
        });
 
        button.setOnLongClickListener(new View.OnLongClickListener(){
            @Override
            public boolean onLongClick(View view) {
                Toast.makeText(MainActivity.this"Long Click!", Toast.LENGTH_SHORT).show();
                return true;
            }
        });
    }
}
cs

버턴 클릭시 클릭 콜백 메서드가 호출되어 "Click" 출력됨.

버턴 롱클릭시 롱클릭 콜백 메서드가 호출되어 "Long Click"출력됨.(롱클릭과 클릭은 중복발생되며 우선순위는 롱클릭쪽에 있다)

29번 라인의 리턴값을 false로 하면 "Long Clcik"출력 후 이벤트가 클릭 콜백 메서드로 전달되어 "Click" 출력 - 이벤트가 소비되지 않아 롱클릭 후 클릭 이벤트가 발생함. true이면 이벤트가 소비되었음을 알리고 다음 이벤트로 전달되지 않음


'학원에서 배운것들 > TEA - P' 카테고리의 다른 글

2017-06-19-P  (0) 2017.06.19
2017-06-16-P  (0) 2017.06.16
2017-06-14-P  (0) 2017.06.14
2017-06-09-P  (0) 2017.06.09
2017-06-08-P  (0) 2017.06.08
Comments