전체소스코드
- MainActivity.java
- activity_main.xml
- NewActivity.java
- activity_new.xml
- MyView.java
a) 그림 1의 MainActivity 화면 중앙에는 경성대 로고 그림(ku_logo.png)이 있다. 이 로고 그림의 실제 크기는 200x213픽셀로서 휴대폰 화면 크기에 비해 월등히 작지만 그림과 같이 휴대폰 화면을 가득 채우도록 설정되어있다. 이렇게 되도록 activity_main.xml 파일 내의 ImageView 태그 해당 부분을 완성하라.
- 이미지뷰 경로설정, 이미지뷰 크기 조절
android:src=”@drawble/ku_logo”
android:scaleType="centerInsdie"
- 이외에 scaleType 종류
- center, centerCrop, fitCenter,fitEnd,fitStart, fitXY,matrix 등 좀많음. 다외우긴힘들고 시험치기전에 한번봐야할듯.
b) MainActivity 화면 하단에는 에디트텍스트와 OK 버튼이 있다. 에디트텍스트에는 Hello, World! 라는 문자열이 입력되어있으며, OK 버튼을 누르면 그림 2와 같이 NewActivity 화면이 나타난다. MainActivity 는 NewActivity 에게 문자열 내용을 파라미터로 넘겨준다. 에디트텍스트 내용은 사용자가 바꿀 수 있다.
- 문제에는 안나와있지만 android:text=”Hello, World” 로 텍스트 설정가능, adnroid:enabled=”false”로 수정못하게 설정가능 근데 안배운거라 안나올거같긴함.
- 중요한건 버튼클릭시 NewActivity 화면나타나고, 문자열 내용 파라미터로 넘기는것(인텐트) 사용할수있냐임. 문제지에서 (2,3,4,5 번에 해당하는부분)
- 2 : View.OnClickListener() : 버튼클릭시 익명의 내부수신자
- 3 : Intent intent = new Intent(MainActivity.this, NewActivity.class) : 인텐트 생성, 파라미터값 입력
- 4 : intent.putExtra(”params”, ed.getText().toString()); : 인텐트 생성후 파라미터를 보내는 putExtra()메소드, params는 내가 임의로지정한것, 주의할점은 에디트텍스트에서 getText() 사용시 Editable 이라는 객체로 반환된느데 이 객체는 toString()메소드(문자열로 변환)를 사용할수있어서 반드시 문자열로 반환시켜서 보내야함.
- 5 : startActivity(intent) : 명시적인텐트로, 특정 액티비티 호출하는 메소드
c) NewActivity 화면의 상단에는 스피너가 있고, 중앙에는 MyView 뷰가 있다. MyView 배경색은 노란색이며, 그림 2와 같이 네 개의 동일 간격 수평 직선이 그려져 있다. MyView 에는 MainActivity 가 파라미터로 넘겨준 문자열이 보여진다. 문자열의 글씨체는 Serif, 굵은 기울임체이며, 크기는 100sp, 색상은 검정색이다.
- 문제를 a,b,c,d 이렇게 순서대로 풀어나가면 이문제가 좀당황스러운게 MainActivity에서 NewActiviy안에있는 MyView소스코드에 답을찾으러 가야된다는거임, NewActvity 에있는 어레이어댑터, 스피너 설정하고 MyView소스코드로 넘어가야함.
- 13 : ArrayAdapter 생성하는 방법 물어보는문제 문제에선 클래스내에서 문자열 배열 선언하고, 그문자열 배열을 바로사용 하는방식
- ArrayAdaper<String> aa = new ArrayAdpater<>(this, android.R.layout.simple_spinner_dropdown_item, ss); 이거좀헷갈림 .. 잘안외워짐4
- 배열을 XML (values/string.xml에 string-array로 정의)에 정의하고 사용하는 방법이있는데. 그럴경우 생성자 ArrayAdapter<String> aa = ArrayAdapter.createFromResource(this, R.array.name, android.R.layout.simple…, ) 이렇게 문제가 나올수도있는것도 유의
- 14 : sp.setAdapter(aa); : 스피너에 어댑터 적용.
- 15 : 여기 답을 찾을려면 여기선 답을 못찾음, MyView로 넘어감.
MyView 배경색은 노란색이며, 그림 2와 같이 네 개의 동일 간격 수평 직선이 그려져 있다.
- a : public class MyView extends View MainActivity, NewActivity 는 Activity 라서 액티비티의 최상위 extends Activity 로 되어있음, MyView의 경우엔 뷰이기 때문에 최상위 클래스 View를 상속받음.
- b : paint = new Paint(); , paint 객체생성.
- paint는 그림을 그릴때 색상, 선 굵기, 글씨체, 등등을 정하게함.
- 주요메소드
- setColor(int color) : 페인트 색상
- setStrokeWidth(float width) : 선굵기, 0,1,2,3
- setStyle(Paint.Style style) : 도형의 스타일지정, 따로지정하지않으면 FILL(색상으로채움)
- setTextSize(float size) : 글씨크기지정.
- setTypeface (Typeface typeface) : 글씨체지정
- c : canvas.drawColor(Color.YELLOW) : 캔버스 색상채우기
- canvas는 그림을 그리는 drawXXXX() 메소드를 가짐, canvas - drawXXX , paint - setXXX 이렇게 생각하자.
- 주요 메소드
- drawColor
- drawLine, drawRect(사각형), drawCircle, drawText, drawBitmap, getHeight(), getWidth()
- d, e : getWidth(), getHeight() : 뷰 또는 ,Canvas의 높이, 길이 값 반환하기.
- f : canvas.drawLine(0, ih, width, ih, paint) : 동일간격의 4개의 줄을그어야함.
- 줄을 긋는 메소드 : drawLine(start X, start Y, endX, endY, Paint paint)
- 뷰의 높이를 4로 나눠서, 한줄씩 긋는 코드 작성하면됨.
문자열의 글씨체는 Serif, 굵은 기울임체이며, 크기는 100sp, 색상은 검정색이다.
- g : Color.BLACK : paint를 검정색으로 설정.
- paint.setTextSize(100) : 텍스트사이즈 설정
- paint.setTypeface(Typeface.SERIF, Typeface.BOLD_ITALIC)
MyView 에는 MainActivity 가 파라미터로 넘겨준 문자열이 보여진다.
- j : canvas.drawText(msg, ~~) : MainActivity가 파라미터로 넘겨준 문자열은 코드의 흐름상 setMessage() 메소드에서 받아온 msg임을 파악해야함. 결론적으로 drawText에 msg가 들어가면되고 문자열의 위치는 다음문제에서 해결가능.
- 15 : setMessage는 MainActivity → NewActivity 로받은 문자열이다. 이문자열을 또 Myview의 파라미터값으로 보내줘야함. MainActivity에서 putExtra로 문자열데이터를 보냈으니, getStringExtra로 데이터를 받으면됨.
getintent().getStringExtra("params");
d) MyView에서 문자열의 수직 위치는 그림 2의 스피너에 의해 결정된다. 스피너에는 First, Second, Third, Fourth 등 네 가지 값이 들어있으며, First를 선택하면 MyView 의 1/4 위치에, Second를 선택하면 2/4 위치에, Third, Fourth를 선택하면 각각 3/4, 4/4 위치에 문자열이 위치한다.
- canvas.drawText(msg, startX,startY, paint) 에서 X좌표와 Y좌표를 조건에맞게 설정해야함.
- 16 : 스피너 OnItemSelectedListener의 리스너는
AdapterView.OnItemSelectedListener()
- 17 : 스피너의 선택한 값에따라, MyView에서 문자열의 수직위치가 정해지기때문에, 선택된 값의 index를 인자로 보내야함. 그리고, onStop() 메소드에서, 인덱스값을 공유레퍼런스에 저장해야하므로 , 해당클래스의 전역변수에도 업데이트를 동시에 해야하므로,
mv.move(sp_idx=i) 로 작성해야함.
- k :
y = idx NewActivity에서 받아온 배열의 index 값을, MyView 전역변수 y에 저장해놓고 사용해야함.
- l :
invalidate(); 변경된 내용을 다시 그리는 메소드.
e) 스피너의 선택된 인덱스 값은 NewActivity 가 끝날 때 공유 프레퍼런스에 자동 저장된다. 나중에 NewActivity 가 다시 시작되면 저장된 인덱스 값대로 스피너 항목이 자동 선택되며, MyView 의 문자열 수직 위치도 직전 위치와 동일하게 된다.
- 18 : NewActivity가 다시시작될때, 공유레퍼런스에서 값을 받아오고, 스피너도 레퍼런스에서 받아온값에따라.자동 선택되어있어야함. 공유레퍼런스를 사용하기위해 prefs객체를 getSharedPreferences로 생성함.
prefs = getSharedPreferences("mg",0);
- 19 :
sp.setSelection(prefs.getInt("sp_idx",0) : 공유프리퍼런스에 저장되어있는 sp_idx (인덱스) 값으로, 스피너 항목을 선택. 0은 값을 불러오지못했을경우, 설정될값.
- 20 :
SharedPreferences.Editor editor = prefs.edit(); 값을저장하기위해 editor 객체생성.
editor.putInt("sp_idx",sp_idx); 클래스의 전역변수에 잇는 sp_idx를 공유레퍼런스의 sp_idx에 저장.
editor.apply(); 값을업데이트하기 위해 반드시 실행해야함, 이문장이없을경우 업데이트가안됨.
f) 그림 2의 NewActivity 화면에서 휴대폰 Back 버튼을 누르면 다시 그림 1의 MainActivity 화면으로 되돌아온다.
- 명시적인텐트사용했으므로 NewActivity에서 back버튼눌리면 Main으로 돌아옴.
g) 그림 1의 MainActivity 화면 앱 바에 있는 태극기 아이콘을 누르면 그림 3과 같은 대화창이 나타나며, 대화창에서 Yes를 선택하면 앱이 종료한다. No를 선택하면 다시 그림 1의 화면이 나타난다.
- 태극기 아이콘 → id : quit, 일반적인 대화창 생성하는문제.
- 7 :
int id = item.getItemId(); id값얻는 메소드 사용.
- 8 :
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Confirm"); 제목 설정
builder.setMessage("Really quit?"); 내용설정
builder.setPositiveButton("YES", this); builder.setNegativeButton("NO", this); 버튼 두개 설정
- builder.show(); 마지막에 꼭 설정되어있어야 대화창이 보임.
h) 앱 바의 오버플로 메뉴 내에 있는 Dial 버튼을 누르면 그림 4와 같은 다이얼 창이 나타난다.
- 암시적 인텐트 사용예제. 암시적 인텐트 설정후, startActivity 사용하면됨. 암시적인텐트의경우 앱의 안전상 if문 하나가 들어가는데 그걸물어보는문제
Intent intent = new Intent(Intent.*ACTION_DIAL*, Uri.*parse*("tel:663-4783"));
if(intent.resolveActivity(getPackageManager()) != null)
startActivity(intent);