Android Studio를 활용한 안드로이드 프로그래밍 P382 직접 풀어보기 9-3

*문제에서는 블러링, 엠보싱기능을 추가했지만 저는 실습 문제 그대로 구현했습니다.


아래의 그림처럼 간단한 포토샵 프로그램을 만들어라.

1. 확대, 축소 기능

2. 회전 기능

3. 화면 밝기 증가, 감소

4. 화면 어둡게/밝게 하기


*실행 결과는 일일이 보여드리기가 힘들어서 생략하겠습니다. 직접 돌려보시면 좋을 것 같아여



<activity_main_XML 코드>

메뉴를 담을 레이아웃과 사진을 담을 레이아웃을 분리할 때 각 레이아웃의 폭,높이 조정에 주의하셔야 합니다.

<LinearLayout 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:orientation="vertical">

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal"
android:id="@+id/iconLayout"
android:layout_weight="1">
<ImageButton
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/zoomin"
android:src="@drawable/icon_zoomin"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/zoomout"
android:src="@drawable/icon_zoomout"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/rotate"
android:src="@drawable/icon_rotate"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/zoombright"
android:src="@drawable/icon_bright"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/zoomdark"
android:src="@drawable/icon_dark"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/zoomgray"
android:src="@drawable/icon_ge"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="9"
android:gravity="center"
android:id="@+id/pictureLayout"
android:orientation="vertical"/>
</LinearLayout>


<MainActivity>

1. clickIcons함수를 정의하고 main문에서 호출할 수 있도록 했습니다. 메뉴 클릭 시 각 이벤트를 처리합니다.

2. 맨 마지막 버튼(화면 회색 전환)의 경우 satur값이 1이면 0으로 바꿔 회색화면으로 만들어주고 0일 시 다시 1로 바꿔줍니다.

=> 일종의 토글버튼(on/off)와 비슷합니다. 최초에 버튼 클릭시 회색으로전환, 또 한번 클릭 시 밝게 전환

아래 코드를 정확한 위치에 삽입해야합니다. 다른 위치에 코드 삽입 시 사진이 회색으로 전환되지 않습니다.

if(satur==0)cm.setSaturation(satur);// 위치 여기다가!!


package com.example.p374;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.View;
import android.widget.ImageButton;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity {
ImageButton zoomin,zoomout,zoombright,zoomdark,zoomrotate,zoomgray;
MyGraphicView graphicView;
static float scaleX=1,scaleY=1,angle=0,color=1,satur=1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setTitle("미니 포토샵");

LinearLayout pictureLayout=(LinearLayout)findViewById(R.id.pictureLayout);
graphicView=(MyGraphicView)new MyGraphicView(this);
pictureLayout.addView(graphicView);
clickIcons();
}

public void clickIcons() {
zoomin=(ImageButton)findViewById(R.id.zoomin);
zoomin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
scaleX=scaleX+0.2f;
scaleY=scaleY+0.2f;
graphicView.invalidate();
}
});
zoomout=(ImageButton)findViewById(R.id.zoomout);
zoomout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
scaleX=scaleX-0.2f;
scaleY=scaleY-0.2f;
graphicView.invalidate();
}
});
zoomrotate=(ImageButton)findViewById(R.id.rotate);
zoomrotate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
angle=angle+20;
graphicView.invalidate();
}
});
zoombright=(ImageButton)findViewById(R.id.zoombright);
zoombright.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
color=color+0.2f;
graphicView.invalidate();
}
});
zoomdark=(ImageButton)findViewById(R.id.zoomdark);
zoomdark.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
color=color-0.2f;
graphicView.invalidate();
}
});
zoomgray=(ImageButton)findViewById(R.id.zoomgray);
zoomgray.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(satur==0)satur=1;
else satur=0;
graphicView.invalidate();
}
});
}


private class MyGraphicView extends View {
public MyGraphicView(Context context) {
super(context);
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint=new Paint();
float[] array={color,0,0,0,0,
0,color,0,0,0,
0,0,color,0,0,
0,0,0,1,0};
ColorMatrix cm=new ColorMatrix(array);
if(satur==0)cm.setSaturation(satur);// 위치 여기다가!!
paint.setColorFilter(new ColorMatrixColorFilter(cm));

Bitmap picture= BitmapFactory.decodeResource(getResources(),R.drawable.img01);
int picX=(this.getWidth()-picture.getWidth())/2;
int picY=(this.getHeight()-picture.getHeight())/2;
int cenX=this.getWidth()/2;
int cenY=this.getHeight()/2;
canvas.scale(scaleX,scaleY,cenX,cenY);
canvas.rotate(angle,cenX,cenY);
canvas.drawBitmap(picture,picX,picY,paint);
picture.recycle();
}
}
}





'Android Studio를 활용한 안드로이드 프로그래밍' 카테고리의 다른 글

직접 풀어보기 9-2  (0) 2020.06.08
직접 풀어보기 9-1  (0) 2020.06.07
직접 풀어보기 8-2  (15) 2020.05.20
직접 풀어보기 8-1  (0) 2020.05.20
직접 풀어보기 7-3  (0) 2020.05.19


Android Studio를 활용한 안드로이드 프로그래밍 P364 직접 풀어보기 9-2


아래의 결과 화면 처럼 메뉴를 이용해 도형을 그리고 서브메뉴를 이용해 도형의 색깔을 선택되게 한다.


























<MainActivity 코드>

1. 도형을 그릴 때 초기 시작 값(도형)은 라인긋기로 되어있기 때문에 이를 이용해서 기본 색깔도 별도의 변수로 지정해줍니다.

2. onOptionsItemSelected 메소드 내부의 switch case문에 4~6번 case(색깔 선택)문을 추가해줍니다.

3. onDraw메소드에서 두개의 switch ~case문을 작성합니다. 하나는 도형, 나머지는 색깔에 관한 switch문입니다.

이 때 색깔선택switch문을 도형선택switch문 전에 작성해야합니다.

두 문장의 순서가 바뀔 시 paint 변수 선언(색깔 디폴트 값 :검정)-> 도형 그리기-> 색깔 선택-> paint변수 선언..........

식으로 이어지기 때문에 선택한 색깔로 바뀌지않고 검정색만 사용됩니다. 

즉, 색깔 선택-> 도형 선택으로 이어지게끔 색깔 선택 swith문을 먼저 수행하게 해야합니다.

package com.example.p364;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SubMenu;
import android.view.View;

public class MainActivity extends AppCompatActivity {

final static int LINE=1, CIRCLE=2,RECT=3,color_RED=4,color_GREEN=5,color_BLUE=6;
//final => 상수의 의미
//static=> 전역의 의미
// final static => 전역 상수
int current_shape=LINE;//기본 값
int current_color=color_RED;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyGraphicView(this));
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0,1,0,"선 그리기");
menu.add(0,2,0,"원 그리기");
menu.add(0,3,0,"사각형 그리기");

SubMenu sub=menu.addSubMenu("색상 변경");
sub.add(0,4,0,"빨간색");
sub.add(0,5,0,"초록색");
sub.add(0,6,0,"파란색");
return true;
}

@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {

switch(item.getItemId())
{
case 1:
current_shape=LINE;
break;
case 2:
current_shape=CIRCLE;
break;
case 3:
current_shape=RECT;
break;
case 4:
current_color=color_RED;
break;
case 5:
current_color=color_GREEN;
break;
case 6:
current_color=color_BLUE;
break;
}
return true;
}

private class MyGraphicView extends View {
int startX=-1,startY=-1,stopX=-1,stopY=-1;
public MyGraphicView(Context context) {
super(context);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
startX=(int)event.getX();
startY=(int)event.getY();
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_MOVE:
stopX=(int)event.getX();
stopY=(int)event.getY();
this.invalidate();
break;
}

return true;
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint=new Paint();
paint.setStrokeWidth(10);
paint.setStyle(Paint.Style.STROKE);

switch(current_shape)
{
case LINE:
canvas.drawLine(startX,startY,stopX,stopY,paint);
break;
case CIRCLE:
int radius=(int)Math.sqrt(Math.pow(stopX-startX,2)+Math.pow(stopY-startY,2));
canvas.drawCircle(startX,startY,radius,paint);
break;
case RECT:
canvas.drawRect(new Rect(startX,startY,stopX,stopY),paint);
break;

}
switch(current_color)
{
case color_RED:
paint.setColor(Color.RED);
break;
case color_GREEN:
paint.setColor(Color.GREEN);
break;
case color_BLUE:
paint.setColor(Color.BLUE);
break;
}
}
}
}















'Android Studio를 활용한 안드로이드 프로그래밍' 카테고리의 다른 글

직접 풀어보기 9-3  (2) 2020.06.08
직접 풀어보기 9-1  (0) 2020.06.07
직접 풀어보기 8-2  (15) 2020.05.20
직접 풀어보기 8-1  (0) 2020.05.20
직접 풀어보기 7-3  (0) 2020.05.19


Android Studio를 활용한 안드로이드 프로그래밍 P358 직접 풀어보기 9-1


그림과 같은 화면을 출력하도록 다음 메소드를 사용하여 JAVA를 코딩하라.

1. Paint.setStrokeCap()

2. Canvas.drawOval()

3. Paint.setColor(Color.argb())


<결과 화면>



<MainActivity 코드>

1. 첫 번째, 두 번째 사각형 모두 사각형이 아닌 선으로 그리고, 선의 두께를 50으로 설정하여 사각형처럼 보이게 그려봤습니다.

2. 두 번 째 사각형의 경우 Paint. setStrokeCap()함수의 옵션 내부에 인자로 Paint.Cap.Round로 하여 모서리를 둥글게 표현했습니다.

3. 타원의 경우 drawOval 함수로 좌표를 설정하여 그리면 됩니다.

4. 부채꼴(호)의 경우 전체 좌표를 지정하고(사각형 처럼 4가지) 시작 지점(startAngle)과 깎을 지점(sweepAngle)을 설정하여 부채꼴 모양을 형성합니다. 깎는 좌표에 따라 원, 반원, 등 다양한 모양이 생성될 수 있습니다.

5. 부분 투명 사각형은 빨간 사각형이 반투명하기 때문에 빨간 사각형의 투명도를 조정해야합니다.  Paint.setColor(Color.argb())함수 안의 인자는 각각 투명도, R,G,B색을 의미하므로 투명도를 0~255값의 중간인120을 넣어주고 R좌표값을 255로 채웠습니다.

package com.example.p358;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Build;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyGraphicView(this));
}

private class MyGraphicView extends View {

public MyGraphicView(Context context) {
super(context);
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint=new Paint();
paint.setColor(Color.BLACK);
paint.setStrokeWidth(50);

canvas.drawLine(70,70,370,70,paint);

paint.setStrokeCap(Paint.Cap.ROUND);
Rect f=new Rect(70,140,370,140);


canvas.drawOval(new RectF(70, 210, 70 + 300, 210 + 140), paint);

canvas.drawArc(new RectF(70,280,70+300,280+210),35,100,true,paint);

Rect rect1=new Rect(100,600,100+200,600+200);
paint.setColor(Color.BLUE);
canvas.drawRect(rect1,paint);

Rect rect2=new Rect(100+60,600+60,100+60+200,600+60+200);
paint.setColor(Color.argb(120,255,0,0));
canvas.drawRect(rect2,paint);

}
}
}




'Android Studio를 활용한 안드로이드 프로그래밍' 카테고리의 다른 글

직접 풀어보기 9-3  (2) 2020.06.08
직접 풀어보기 9-2  (0) 2020.06.08
직접 풀어보기 8-2  (15) 2020.05.20
직접 풀어보기 8-1  (0) 2020.05.20
직접 풀어보기 7-3  (0) 2020.05.19


Android Studio를 활용한 안드로이드 프로그래밍 P349 직접 풀어보기 8-2


실습 8-2 를 다음과 같이 수정하라.

1. "이전 그림" 버튼과 "다음 그림" 버튼 사이에 "현재번호/전체 그림 갯수"를 의미하는 텍스트뷰 표시하기

2. 토스트 메시지를 없애고, 첫 번 째 그림에서 "이전그림"클릭 시 마지막 그림을,

마지막 그림에서 "다음 그림" 클릭 시 첫 번 째 그림을 나오게하기. (텍스트뷰도 갱신되어야함)



*한번 실행 후 프로젝트를 다시 실행할 때 화면이 꺼지거나 오류가 발생하면 AVD를 재부팅 하여 실행해야합니다.


<출력화면>

저는 sd카드의 Pictrues폴더에 그림파일을 7개 넣어두고 시작했습니다.


1. 최초 실행 화면


2. 첫 번째 그림화면에서 "이전 그림" 버튼 출력 후 


3. 맨 마지막 그림화면에서 "다음 그림" 버튼 클릭 후



<activity_main.xml 코드>

사용한 이미지가 총7개이므로 최초의 텍스트뷰의 텍스트를 "1/7"로 설정했습니다.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnPrev"
android:text="이전그림"
android:layout_weight="1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1/7"
android:textSize="20sp"
android:id="@+id/textview1"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnNext"
android:text="다음그림"
android:layout_weight="1"/>
</LinearLayout>
<com.example.a8_2practice.myPictrueView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/myPictureView1"/>
</LinearLayout>


<MainActivity 코드>

문제에서 "현재번호/전체 그림 갯수"를 나타내는 위젯을 텍스트뷰로 나타나게 하라고 한 것을 주의하셔야합니다.

즉, 숫자를 어떻게 텍스트뷰로 표현할까? 


방법1. 계산기 프로그램과 비슷하게 Integer와 toString()함수를 이용한다.

간단하게 TextView형 변수.setText(Integer.toString(int형변수)); 로 작성할 수 있는데

구글링으로 다른 방법을 찾아보다가 아래 방법으로 풀어봤습니다.

일단 정수 CurNum을 Integer 타입으로 캐스팅 해야합니다. (integer와 int 는 다름. integer는 객체)

int CurNum=0;

Integer num=new Integer(CurNum);

이렇게 작성 후 텍스트뷰로 출력할 때 num을 toString()함수로 문자열로 변환 후 출력하면 됩니다.


방법2. int형 변수를 String으로 출력한다.(이 방법 사용)

숫자를 문자열로 변환하고 싶으면 아래와 같이 작성하면 됩니다.

String.valueOf(int형 변수명)


*방법1, 방법2 모두 자바의 문법입니다. (캐스팅 방법)


주의할 것은 배열의 인덱스입니다. 텍스트뷰의 시작은 1부터 시작하지만 배열은 0부터 시작하기 때문입니다.

나머지 코드는 전체코드를 읽어보시면 이해가 쉬울 것 같습니다. 

package com.example.a8_2practice;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.Manifest;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import java.io.File;

public class MainActivity extends AppCompatActivity {
Button btnPrev,btnNext;
myPictrueView mypicture;
int curNum=1;
File[] imageFiles;
String imageFname;
TextView textView1;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setTitle("간단 이미지뷰어");
ActivityCompat.requestPermissions(this,new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE},MODE_PRIVATE);
btnPrev=(Button)findViewById(R.id.btnPrev);
btnNext=(Button)findViewById(R.id.btnNext);
textView1=(TextView)findViewById(R.id.textview1);
mypicture=(myPictrueView)findViewById(R.id.myPictureView1);
imageFiles= new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/Pictures").listFiles();
imageFname=imageFiles[0].toString();
mypicture.imagePath=imageFname;
btnPrev.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(curNum<=1)
{
curNum=imageFiles.length;
imageFname=imageFiles[curNum-1].toString();
mypicture.imagePath=imageFname;
mypicture.invalidate();
textView1.setText(String.valueOf(curNum)+"/"+String.valueOf(imageFiles.length));
//Toast.makeText(getApplicationContext(),"첫번쨰 그립입니다.",Toast.LENGTH_SHORT).show();
}
else
{
curNum--;
imageFname=imageFiles[curNum-1].toString();
mypicture.imagePath=imageFname;
mypicture.invalidate();
textView1.setText(String.valueOf(curNum)+"/"+String.valueOf(imageFiles.length));
}
}
});
btnNext.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(curNum>=imageFiles.length)
{
curNum=1;
imageFname=imageFiles[curNum-1].toString();
mypicture.imagePath=imageFname;
mypicture.invalidate();
textView1.setText(String.valueOf(curNum)+"/"+String.valueOf(imageFiles.length));
//Toast.makeText(getApplicationContext(),"마지막 그림입니다.",Toast.LENGTH_SHORT).show();
}
else {curNum++;
imageFname=imageFiles[curNum-1].toString();
mypicture.imagePath=imageFname;
mypicture.invalidate();}
textView1.setText(String.valueOf(curNum)+"/"+String.valueOf(imageFiles.length));
}
});
}
}







'Android Studio를 활용한 안드로이드 프로그래밍' 카테고리의 다른 글

직접 풀어보기 9-2  (0) 2020.06.08
직접 풀어보기 9-1  (0) 2020.06.07
직접 풀어보기 8-1  (0) 2020.05.20
직접 풀어보기 7-3  (0) 2020.05.19
직접 풀어보기 7-2  (4) 2020.05.19


Android Studio를 활용한 안드로이드 프로그래밍 P335 직접 풀어보기 8-1


실습 8-1을 처음 실행하면 데이트피커의 초기날짜(2020-5-19)에 텍스트파일이 있을 경우 

그날의 일기가 뜨지않고 아래와 같은 화면이 뜨는데, 초기날짜의 텍스트파일이 있을 경우 에디드텍스트에

일기를 출력하고, 일기가없을 시 "일기 없음" 힌트가 나오고 버튼은 <새로 저장> 이 되게 수정하라.


<수정 전 화면(실습 8-1)>



<수정 후 화면>

1. 최초 실행 시 데이트피커에 설정 된 날짜(2020-5-19)에 텍스트가 없을 때 


2. 최초의 데이트피커 날짜값의 파일(2020_5_19.txt)이 있을 경우

(실행 전 2020_5_19에 해당하는 텍스트파일을 만들고 내용 작성 후 내장 메모리에 저장해야합니다.)



activity_main.xml 코드

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<DatePicker
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/datePicker"
android:datePickerMode="spinner"
android:calendarViewShown="false"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/edtDiary"
android:background="#00ff00"
android:lines="8"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="BUTTON"
android:enabled="false"
android:id="@+id/btnWrite"/>

</LinearLayout>



MainActivity 코드

우선, pc바탕화면에서 초기의 데이트피커에 설정된 날짜에 해당하는 메모장파일을 만들어 내용을 입력 후 저장 한 다음, 

안드로이드 스튜디오의 해당 응용프로그램(진행 중인 프로젝트)의 내장 메모리(data/data/패키지명/files)에 만들어둔 파일을 업로드합니다.


코드를 보면, 실습 코드의 init메소드는 데이트 피커의 초기값을 설정해주고 날짜 변경리스너를 포함하기 때문에

초기화 메소드전에 아래와 같은 코드를 작성하여 최초 실행 시 기본으로 설정되어있는 데이트피커의 날짜 값에 해당하는 

메모장이 있을 경우 에디트텍스트로 출력할 수 있게 합니다.

String filename1= Integer.toString(cYear)+"_"+Integer.toString(cMonth+1)+"_"+Integer.toString(cday)+".txt";
String str1=readDiary(filename1);
edtDiary.setText(str1);
btnWrite.setEnabled(true);

전체코드는 아래와 같습니다.

package com.example.p327test;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.Toast;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.zip.Inflater;

public class MainActivity extends AppCompatActivity {
String filename;
DatePicker dp;
Button btnWrite;
EditText edtDiary;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dp=(DatePicker)findViewById(R.id.datePicker);
btnWrite=(Button)findViewById(R.id.btnWrite);
edtDiary=(EditText)findViewById(R.id.edtDiary);
setTitle("간단 일기장");
Calendar cal=Calendar.getInstance();
int cYear=cal.get(Calendar.YEAR);
int cMonth=cal.get(Calendar.MONTH);
int cday=cal.get(Calendar.DAY_OF_MONTH);
String filename1= Integer.toString(cYear)+"_"+Integer.toString(cMonth+1)+"_"+Integer.toString(cday)+".txt";
String str1=readDiary(filename1);
edtDiary.setText(str1);
btnWrite.setEnabled(true);

dp.init(cYear,cMonth,cday, new DatePicker.OnDateChangedListener() {
@Override
public void onDateChanged(DatePicker datePicker, int i, int i1, int i2) {
filename=Integer.toString(i)+"_"+ Integer.toString(i1+1)+"_"+Integer.toString(i2)+".txt";
String str=readDiary(filename);
edtDiary.setText(str);
btnWrite.setEnabled(true);
}
});
btnWrite.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
FileOutputStream outfs=openFileOutput(filename, Context.MODE_PRIVATE);
String str=edtDiary.getText().toString();
outfs.write(str.getBytes());
outfs.close();
Toast.makeText(getApplicationContext(),filename+"이 저장됨",Toast.LENGTH_SHORT).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}

String readDiary(String filename) {
String diaryStr=null;
FileInputStream infs;
try {
infs=openFileInput(filename);
byte txt[]=new byte[500];
infs.read(txt);
infs.close();
diaryStr=(new String(txt)).trim();
btnWrite.setText("수정하기");
} catch (FileNotFoundException e) {
edtDiary.setHint("일기없음");
btnWrite.setText("새로 저장");
} catch (IOException e) {
e.printStackTrace();
}
return diaryStr;
}
}








'Android Studio를 활용한 안드로이드 프로그래밍' 카테고리의 다른 글

직접 풀어보기 9-1  (0) 2020.06.07
직접 풀어보기 8-2  (15) 2020.05.20
직접 풀어보기 7-3  (0) 2020.05.19
직접 풀어보기 7-2  (4) 2020.05.19
직접 풀어보기 7-1  (0) 2020.05.18


Android Studio를 활용한 안드로이드 프로그래밍 P317 직접 풀어보기 7-3


실습7-3을 다음과 같이 수정하라.

(일단 7-3실습 코딩을 해보시면 쉽게 수정 할 수 있습니다.)


1. Activity Main.xml의 텍스트뷰를 에디트 텍스트로 변경


2. <여기를 클릭> 클릭 시 Activity Main.xml의 에디트텍스트 내용이 대화 상자의 에디트텍스트에 나타남


3. 대화상자에서 <확인> 클릭 시 대화상자의 에디트텍스트 내용이 Activity main.xml의 에디트텍스트 내용으로 변경되게 한다.

(즉, 열려진 대화상자에서 정보 수정 후 '확인'을 누르면 main의 에디트텍스트가 수정됨)


4. 대화상자에서 <취소> 클릭 시 토스트가 화면의 임의 위치에 나타나게 함



결과 화면

1. 바깥의 EditText에 이름, 이메일 작성



2. <여기를 클릭> 클릭 후 대화상자화면



3. 대화상자에서 정보 수정 후 <확인> 버튼 클릭 후


4. <취소>버튼 누를 시 랜덤위치에 토스트 출력



dialog1.xml 코드(대화 상자)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="사용자 이름"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/edit1"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="이메일"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/edit2"/>

</LinearLayout>


toast1.xml (토스트 뷰)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff0000"
android:gravity="center">
<ImageView
android:layout_width="10dp"
android:layout_height="10dp"
android:src="@drawable/pic01"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView"
android:textSize="20sp"
android:text="textview"/>
<ImageView
android:layout_width="10dp"
android:layout_height="10dp"
android:src="@drawable/pic01"/>

</LinearLayout>


activity_main.xml 코드

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_horizontal">

<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tvName"
android:hint="사용자 이름"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tvEmail"
android:hint="이메일"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn1"
android:text="여기를 클릭"/>

</LinearLayout>



MainActivity 코드

토스트뷰를 랜덤위치에 출력해주는 함수들만 조심하면 될 것 같습니다. 

random함수가 0~1의 임의의 수를 구해주는데 거기에 랜덤 좌표를곱하기때문에 토스트가 랜덤위치에 찍히게 됩니다.

그리고 EditText -> TextView의 경우, 읽어들인 EditText값을 문자열로 변환한 후 TextView에 저장해야하지만

이 문제는 EditeText->EditText의 경우이므로 굳이 문자열변환함수 toString()을 쓰지 않아도됩니다.

package com.example.a7_3;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import android.content.DialogInterface;
import android.os.Bundle;
import android.view.Display;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
EditText tvName,tvEmail;
EditText dlgEdtName,dlgEdtEmail;
TextView toastText;
View dialogView, toastView;
Button btn1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setTitle("사용자 정보 입력");
tvName=(EditText) findViewById(R.id.tvName);
tvEmail=(EditText) findViewById(R.id.tvEmail);
btn1=(Button)findViewById(R.id.btn1);
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dialogView=(View)View.inflate(MainActivity.this,R.layout.dialog1,null);
AlertDialog.Builder dlg=new AlertDialog.Builder(MainActivity.this);
dlg.setTitle("사용자 정보 입력");
dlg.setIcon(R.mipmap.ic_launcher);
dlg.setView(dialogView);
dlgEdtName=(EditText)dialogView.findViewById(R.id.edit1);
dlgEdtEmail=(EditText)dialogView.findViewById(R.id.edit2);

//에딧텍스트의 문구를 에딧텍스트에 복사하므로 .toString()함수 필요x
dlgEdtName.setText(tvName.getText());
dlgEdtEmail.setText(tvEmail.getText());
dlg.setPositiveButton("확인", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
tvName.setText(dlgEdtName.getText());
tvEmail.setText(dlgEdtEmail.getText());
}
});

dlg.setNegativeButton("취소", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Toast toast=new Toast(MainActivity.this);
toastView=(View)View.inflate(MainActivity.this,R.layout.toast1,null);
toastText=(TextView)toastView.findViewById(R.id.textView);
toastText.setText("취소했습니다.");
toast.setView(toastView) ;
Display display=((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
int xoffset=(int)(Math.random()*display.getWidth());
int yoffset=(int)(Math.random()*display.getHeight());
toast.setGravity(Gravity.TOP | Gravity.LEFT,xoffset,yoffset);
toast.show();
}
});
dlg.show();
}
});
}
}











'Android Studio를 활용한 안드로이드 프로그래밍' 카테고리의 다른 글

직접 풀어보기 8-2  (15) 2020.05.20
직접 풀어보기 8-1  (0) 2020.05.20
직접 풀어보기 7-2  (4) 2020.05.19
직접 풀어보기 7-1  (0) 2020.05.18
직접 풀어보기 6-3  (5) 2020.05.11


Android Studio를 활용한 안드로이드 프로그래밍 P301 직접 풀어보기 7-2


ContextMenu를 이용해 아래의 앱을 만드는데, 컨텍스트 메뉴XML파일 없이 JAVA코드로만 완성하시오.




XML코드

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
android:gravity="center_horizontal"
android:id="@+id/baseLayout">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button1"
android:text="배경색 변경"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button2"
android:text="버튼변경"/>



</LinearLayout>


MainActivity 코드

위젯별로 컨텍스트 메뉴가 나타나야 하므로, 메뉴파일 등록클래스(onCreateContextMenu)내부에

위젯별 컨텍스트 메뉴를 if문으로 등록합니다.

package com.example.a7_2test;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.graphics.Color;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity {
Button button1,button2;
LinearLayout baseLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setTitle("배경색 바꾸기(컨텍스트)");
baseLayout=(LinearLayout)findViewById(R.id.baseLayout);
button1=(Button)findViewById(R.id.button1);
registerForContextMenu(button1);
button2=(Button)findViewById(R.id.button2);
registerForContextMenu(button2);
}

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
if(v==button1){
menu.add(0,1,0,"배경색(빨강)");
menu.add(0,2,0,"배경색(초록)");
menu.add(0,3,0,"배경색(파랑)");}
if(v==button2){
menu.add(0,4,0,"버튼45도회전");
menu.add(0,5,0,"버튼 2배확대");}
}

@Override
public boolean onContextItemSelected(@NonNull MenuItem item) {
switch(item.getItemId())
{
case 1:
baseLayout.setBackgroundColor(Color.RED);
break;
case 2:
baseLayout.setBackgroundColor(Color.GREEN);
break;
case 3:
baseLayout.setBackgroundColor(Color.BLUE);
break;
case 4:
button1.setRotation(45);
break;
case 5:
button1.setScaleX(2);
break;
}
return true;
}
}



'Android Studio를 활용한 안드로이드 프로그래밍' 카테고리의 다른 글

직접 풀어보기 8-1  (0) 2020.05.20
직접 풀어보기 7-3  (0) 2020.05.19
직접 풀어보기 7-1  (0) 2020.05.18
직접 풀어보기 6-3  (5) 2020.05.11
직접 풀어보기 6-2  (2) 2020.05.04


Android Studio를 활용한 안드로이드 프로그래밍 P295 직접 풀어보기 7-1


RelativeLayout과 텍스트뷰, 에디트텍스트뷰, 이미지뷰, 옵션메뉴를 적절히 배치하여  아래와 같은 앱을 작성하시오.


순서: 각도입력-> 사진선택-> 그림 회전


* 각 동물이름 메뉴 선택 시 라디오버튼 처럼 한개의 메뉴만 선택할 수 있어야하고, 체크가 되어야됨




activity_main XML코드

렐러티브 레이아웃을 사용해야하므로 텍스트뷰, 에디트텍스트, 이미지뷰의 위치를 잘 구성해야합니다.

회전된 화면이 에디트텍스트란을 덮지 않게 이미지뷰의 위치를 중앙에 배치합니다.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="각도 입력"
android:id="@+id/textView1"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="입력하세요."
android:layout_toRightOf="@+id/textView1"
android:layout_alignBaseline="@+id/textView1"
android:id="@+id/Edit1"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/imgView"
android:visibility="invisible"
android:scaleType="fitXY"
android:layout_centerInParent="true"/>
</RelativeLayout>

menu XML코드

메뉴의 목록에서 동물이름끼리 모아서 각각을 라디오 버튼처럼 생성하려면 group을 이용해야합니다.

checkableBehavier="single" 코드를 통해 하나만 체크할 수 있습니다.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:title="그림 회전"
android:id="@+id/rotate"/>
<group
android:checkableBehavior="single">
<item
android:id="@+id/lion"
android:title="사자" />
<item
android:id="@+id/dog"
android:title="개" />
<item
android:id="@+id/cat"
android:title="토끼" />
</group>
</menu>


MainActivity

onCreateOptionsMenu메소드를 통해 메뉴의 내용을 XML파일로부터 읽어오고, 

onOptionsItemSelected 메소드는 메뉴를 선택했을 때 어떤 동작을 할 것인지를 코딩합니다.

회전을 선택하면 에디트텍스트에 입력된 각도만큼 회전하며, 

각 동물이름 선택 시 라디오버튼 처럼 체크하기  item.setChecked(true)코드를 작성합니다. (*이 코드 미작성 시 체크안됨)

package com.example.practice7_1;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.media.Image;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;

import java.security.acl.Group;
import java.util.zip.Inflater;

public class MainActivity extends AppCompatActivity {
EditText edit1;
ImageView img;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edit1=(EditText)findViewById(R.id.Edit1);
img=(ImageView)findViewById(R.id.imgView);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuInflater inflater=getMenuInflater();
inflater.inflate(R.menu.menu1,menu);
return true;
}

@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch(item.getItemId())
{
case R.id.rotate:
img.setRotation(Integer.parseInt(edit1.getText().toString()));
break;
case R.id.lion:
item.setChecked(true);
img.setImageResource(R.drawable.lion);
img.setVisibility(View.VISIBLE);
break;
case R.id.dog:
item.setChecked(true);
img.setImageResource(R.drawable.dog);
img.setVisibility(View.VISIBLE);
break;

case R.id.cat:
item.setChecked(true);
img.setImageResource(R.drawable.rab);
img.setVisibility(View.VISIBLE);
break;

}
return true;
}








'Android Studio를 활용한 안드로이드 프로그래밍' 카테고리의 다른 글

직접 풀어보기 7-3  (0) 2020.05.19
직접 풀어보기 7-2  (4) 2020.05.19
직접 풀어보기 6-3  (5) 2020.05.11
직접 풀어보기 6-2  (2) 2020.05.04
직접 풀어보기 6-1  (1) 2020.05.03

+ Recent posts