비전공자를 위한 안드로이드 강의, 4강 리스트 만들기!

안녕하세요, 비전공자를 위한 안드로이드 강의의 금손입니다.

이번 시간에는 리스트를 만들고 개별 클릭이벤트를 받아보는 앱을 만들겁니다. 리스트를 사용한 앱은 무엇이있을까요? 간단하게는 카카오톡 친구목록이 될 수 있을 것이고요, 여러분 인터넷 브라우저의 방문기록이나 즐겨찾기 목록도 다 리스트를 사용한 것이겠죠.

이렇듯 리스트는 우리 주위에 공기처럼 늘 존재 해 왔답니다. 페이스북이나 유튜브 처럼 카드로 피드가 뜨는 경우에는 리스트뷰 대신 RecyclerView와 CardView를 사용하지만 이들도 결국 ListView의 확장이라 보시면 되겠습니다.

어떤 앱을 만들 거죠!?

내가 좋아하는 음식 목록을 리스트로 보여주는 초간단 앱을 만들 예정입니다. 목록은 모두 하드코딩(코드 상에 손수 미리 적어놓음..) 되어있구요.

자 그럼 새로운 프로젝트를 만들어 시작해봅시다.


정보 준비하기

strings.xml

strings.xml을 너무 안써서 이번시간에 간단히 써 보려고 합니다. 앱에 들어가는 안내문이나 모든 시스템 문구들은 여기에 넣어두고 사용하는 것이 좋습니다. 여러 언어로 현지화(localization) 하기 쉽고 관리도 수월하기 때문이죠. res > values > strings.xml을 열어 아래와 같이 수정 해 보세요. app_name부분은 여러분의 앱 이름을 나타냅니다.

<resources>
<string name="app_name">course_3_list</string>
<string name="title_list">내가 좋아하는 음식들</string>
</resources>

UI 구성하기

activity_main.xml

간단히 TextView 아래에 ListView를 배치 시켜 놓았습니다.
TextView의 android:text 속성에 주목 해 주세요. 이것은 res > values > strings.xml에 위치한 title_list라는 문자열 리소스를 사용한다는 말 입니다. strings.xml에는 ‘내가 좋아하는 음식들’이라고 미리 적어두었죠? 그럼 그 문자를 사용할 수 있게됩니다.

<?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:id="@+id/activity_main"
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="com.lx5475.course_3_list.MainActivity">
<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/title_list"
android:gravity="center"
android:textStyle="bold" />
<ListView
android:id="@+id/lv_foods"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/tv_title"/>
</RelativeLayout>


리스트 만들기

MainActivity.java

부분별로 조명하면서 설명 해 드리겠습니다.

  • ListView lv_foods = (ListView) findViewById(R.id.lv_foods);: 사용 할 리스트뷰를 요로코롬 불러왔습니다. 변수명은 id랑 똑같이 지어놓았습니다.

  • String[] foods = {"계란말이", "된장국", "초밥", "제육볶음", "나시고랭"};: String 배열을 만들고 거기에 음식 몇 가지를 넣어놓았습니다.

  • ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);: ArrayAdapter? 리스트를 배우러 왔는데 이게뭐야! 하고 생소 해 하실 수도 있습니다. 간단하게 비유하면 listView는 총이고 ArrayAdapter등의 listViewAdapter는 탄창, ArrayAdapter에 담긴 데이터들은 탄약(총알)입니다. ~ 너무 잘 비유한거같아서 저 자신이 대견스럽네요 ㅋㅋㅋ ~

    ArrayAdapter<String>은는 String 형식의 데이터를 담는 ArrayAdapter입니다. 주석에도 표시되어 있지만 android.R.layout.simple_list_item_1이란 리스트뷰의 디자인 스타일을 말하는 것입니다. 제공되는 스타일 말고 원하는 대로 리스트뷰를 디자인 하고 싶다면 직접 Adapter를 만들면됩니다. BaseAdapter 클래스를 상속받아서요. 이 역시도 필수 과정이니 추후 강의에서 다룰 예정입니다.

  • adapter.addAll(foods);: foods 배열에 있는 데이터들을 adpater에 싣습니다. 탄창에 탄약을 채워 넣는거죠!

  • lv_foods.setAdapter(adapter);: 만든 adapter를 리스트뷰에 설정해 줍니다. 총기에 탄약을 채운 탄창을 넣어줍니다!

  • lv_foods.setOnItemClickListener(...): 우리는 개별 리스트 아이템을 클릭하면 ‘~를 클릭했습니다.’라고 메세지가 뜨는 걸 만들 것이기 때문에, 개별 아이템의 클릭 이벤트를 처리해주는 OnItemClickListener를 리스트뷰에 붙였습니다. 이 블록안에 있는 부분은 외우지 마시고, 필요할 때마다 찾아보시면 되는 부분입니다. 주석을 참고 해 주세요~

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView lv_foods = (ListView) findViewById(R.id.lv_foods);
String[] foods = {"계란말이", "된장국", "초밥", "제육볶음", "나시고랭"};
// android.R.layout.simple_list_item_1는 안드로이드 제공하는 리스트의 기본 레이아웃
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1);
adapter.addAll(foods);
lv_foods.setAdapter(adapter);
lv_foods.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// 클릭한 아이템 이름 가져옴
ListView listview = (ListView) parent;
String clickedFood = (String) listview.getItemAtPosition(position);
// 토스트 메세지로 표시
Toast.makeText(MainActivity.this,
clickedFood + "을(를) 클릭하셨습니다.", Toast.LENGTH_SHORT).show();
}
});
}
}

실행시켰을 때 아래와 같은 화면이 나오면, 성공입니다!

비전공자를 위한 안드로이드 강의, 3강 화면 전환 하기

안녕하세요, 비전공자를 위한 안드로이드 강의의 금손입니다.
이 시간에 배울 내용은 안드로이드 앱에서 화면을 전환하고, 전환 시에 데이터도 넘겨보는 작업입니다.

이 모든 작업에 이용되는 것은 바로 Intent 라는 클래스입니다.

인텐트로는 많은 것들을 할 수 있지만, 가장 기본적인 것 두 가지만 배워보도록 하겠습니다. 첫번째 화면전환, 두번째 데이터 전달입니다.


예제 앱은 어떤 앱인가요?

A라고 적힌 화면을 누르면 B라고 적힌 화면으로 이동하는 앱입니다.

추가로, A라고 적힌 화면을 누르면 A 액티비티에서 보낸 내용을 B에서 받아서 표시하는 것도 해 볼 것입니다.


화면 구성하기

activity_main.xml

activity_main.xml은 첫번째 화면인 ‘A’가 표시된 화면입니다.
@color/colorAccent 색상을 가진 배경 rl_background를 클릭하면 B가적힌 화면으로 이동하도록 할 것입니다.

<?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:id="@+id/rl_background"
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"
android:background="@color/colorAccent"
tools:context="com.lx5475.course_2_intent.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textSize="100sp"
android:textColor="#FFF"
android:text="A" />
</RelativeLayout>

activity_sub.xml

res > layout 폴더를 오른쪽 클릭해서 새로운 레이아웃 파일을 만드세요. 여기서는 이름을 activity_sub.xml라고 지어주었습니다.
TextView 안에는 ‘B’라고 적어두었고, 차후에 A화면에서 보낸 데이터를 받아 표시하기 위해 TextView의 id를 tv_value라고 지어두었습니다.

<?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:id="@+id/activity_main"
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"
android:background="@color/colorPrimaryDark"
tools:context="com.lx5475.course_2_intent.MainActivity">
<TextView
android:id="@+id/tv_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textSize="100sp"
android:textColor="#FFF"
android:text="B" />
</RelativeLayout>

SubActivity.java

패키지 이름 폴더를 오른쪽 클릭하여 ‘SubActivity’ 라는 새로운 클래스를 만드세요.

public class SubActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sub);
}
}

MainActivity.java

MainActivity.java로 돌아가서 rl_background에 OnClickListener를 붙이고, 화면전환 코드를 적어줍니다.
Intent intent = new Intent(현재 액티비티, 전환할 액티비티) 방식으로 적어주고, startActivity(intent)라는 명령을 통해서 화면전환을 실행합니다.

이 방법으로 화면이 전환될때는, 전환 된 화면에서 뒤로가기(Back) 키를 누르면 다시 원래 화면으로 돌아오게 됩니다.
그것을 원치 않을 경우에 startActivity(...) 뒤에 finish()를 하여 현재 액티비티의 생명을 끊어주세요…ㅎㅎ

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout rl_background = (RelativeLayout) findViewById(R.id.rl_background);
// 배경을 클릭하면
rl_background.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Main -> SubActivity로 이동
Intent intent = new Intent(MainActivity.this, SubActivity.class);
// 화면 전환 시작
startActivity(intent);
// 화면전환 후 이 페이지로 오기를 원치 않으면
// finish();
}
});
}
}


AndroidManifest에 새 액티비티 등록하기

아기가 태어나면 출생신고를 해야하는 것 처럼, 안드로이드에서도 새로운 액티비티를 추가하면 그것을 AndroidManifest.xml에 적어주어야합니다. 그렇지 않고 새로운 액티비티에 접근하려하면 오류가 납니다.

<activity android:name=".SubActivity"></activity>라는 코드를 추가 해 줍시다.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.lx5475.course_2_intent">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SubActivity"></activity>
</application>
</manifest>


화면전환 시 데이터 넘기기

화면전환 시 데이터 넘기기는 앱의 필수기능이라 할 수 있죠.

예를들어 회원가입 절차에서 다음 화면으로 넘어갈때라던가, 리스트를 클릭하면 정보를 알려주는 화면으로 넘어갈때라던가 사소한 곳에서도 필요합니다.

MainActivity.java

Intent에 정보를 싣는(put) 것은 putExtra(키, 값) 방식으로 할 수 있습니다. 앞의 키(key)는 뒤의 값(value)에 대한 별명 같은겁니다.

예를 들어서 주소인 String address = "부산광역시 금정구 장전동"이라는 값을 다음 액티비티에 전달해야한다면, intent.putExtra("address", address)라는 식으로 전달할 수 있습니다. 키는 String 타입이어야 하지만, 뒤의 값은 int, float, string, char 등 원시타입 모두 넣을 수 있습니다.

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout rl_background = (RelativeLayout) findViewById(R.id.rl_background);
rl_background.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, SubActivity.class);
// 추가한 코드
intent.putExtra("name", "금손");
startActivity(intent);
}
});
}
}

SubActivity.java

이전 액티비티에서 보낸 인텐트를 받을 때는 getIntent() 메소드를 사용하여 받아주면됩니다. 그 인텐트에 보낸 데이터가 있다면 받을 수 있겠죠? intent.get<Type>Extra(키) 메소드로 받을 수 있습니다. 예제에서는 “금손”이라는 String 타입의 데이터를 보냈으니 intent.getStringExtra("name")이라고 해 주었습니다.

그리고 해당 정보를 tv_value라는데 표시(setText) 해 주었습니다.

public class SubActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sub);
Intent intent = getIntent();
String value = intent.getStringExtra("name");
TextView tv_value = (TextView) findViewById(R.id.tv_value);
tv_value.setText(value);
}
}


Run!

이제 실행해서 직접 어떻게 앱이 돌아가는지 확인해보세요.

제대로 실행되지 않는다면 오류 코드를 복사해서 댓글로 남겨주시면 제가 빠르게 해결해드리도록 하겠습니다!ㅎㅎ


심화과정

Intent는 실로 다양한 일을 할 수 있습니다.
다른 앱도 실행시킬 수 있고, 메일이나 문자를 보낼 수도 있습니다.

강의에서는 intent로 보낼 수 있는 데이터 타입은 원시타입 뿐이라고 했으나, parcelable을 이용하여 자신이 직접 만든 객체를 통째로 보낼 수도 있습니다. parcelable로 커스텀 객체를 넘기는 방법은 여기서 확인하세요.

C++ 이진 탐색 트리 구현하기 (Binary Search Tree)

이진 탐색 트리 (Binary Search Tree)

이진 탐색트리는 데이터의 크기에 따라 노드의 위치가 다르다.
정의는 아래와 같다.

(1) 모든 원소는 서로 다른 유일한 키를 갖는다.

(2) 왼쪽 서브 트리에 있는 원소의 키는 그 루트의 키보다 작다.

(3) 오른쪽 서브 트리에 있는 원소의 키는 그 루트의 키보다 크다.

(4) 왼쪽 서브트리와 오른쪽 서브트리도 이진 탐색 트리이다.

이진 탐색 트리 C++ 구현

이제 이진 탐색트리를 구현할텐데,

  • 탐색(search)
  • 삽입(insert)

두 가지 기능을 수행하도록 할 것이다.
구현해볼 이진 탐색트리는 아래와 같이 생겼다.
주황색 표시된 부분은 새로 추가해볼 노드다.

#include <iostream>
#define null 0
using namespace std;
template <typename T>
class Tree;
template <typename T>
class TreeNode {
friend class Tree<T>;
private:
T data;
TreeNode* left;
TreeNode* right;
public:
TreeNode(T data = 0, TreeNode* left = null, TreeNode* right = null) {
this->data = data;
this->left = left;
this->right = right;
}
friend ostream& operator<<(ostream& os, const TreeNode<T>& node) {
os << "[data] " << node.data << endl;
if (node.left != null) {
os << "[left] " << node.left->data << endl;
}
if (node.right != null) {
os << "[right] " << node.right->data << endl;
}
return os;
}
};
template <typename T>
class Tree {
private:
TreeNode<T>* root;
public:
Tree(T data = 0) {
root = new TreeNode<T>(data);
}
// Tree 만들기
void buildSearchTree() {
insertNode(new TreeNode<int>(3));
insertNode(new TreeNode<int>(10));
insertNode(new TreeNode<int>(14));
insertNode(new TreeNode<int>(2));
insertNode(new TreeNode<int>(5));
insertNode(new TreeNode<int>(11));
insertNode(new TreeNode<int>(16));
}
void insertNode(TreeNode<T>* node) {
// 중복이 없을 때
if (search(root, node->data) == null) {
TreeNode<T>* parent = null;
TreeNode<T>* current = root;
// 작으면 왼쪽, 크면 오른쪽으로 이동,
// 새 노드의 부모가 정해짐
while (current != null) {
parent = current;
if (node->data < parent->data) {
current = current->left;
}
else {
current = current->right;
}
}
if (node->data < parent->data) {
parent->left = node;
}
else {
parent->right = node;
}
cout << "Inserted " << node->data << endl;
}
}
TreeNode<T>* getRoot() {
return root;
}
void preorder(TreeNode<T>* current) {
if (current != null) {
visit(current);
preorder(current->left);
preorder(current->right);
}
}
void visit(TreeNode<T>* current) {
cout << current->data << " ";
}
TreeNode<T>* search(TreeNode<T>* current, T data) {
if (current == null) return null;
if (data == current->data) {
return current;
}
else if (data < current->data) {
search(current->left, data);
}
else {
search(current->right, data);
}
}
};
int main() {
Tree<int> tree(8);
tree.buildSearchTree();
// 만들어진 Tree 출력하기
// 8 3 2 5 10 14 11 16
cout << "Preorder >> ";
tree.preorder(tree.getRoot());
cout << endl;
// Tree에 4 넣고, 확인
tree.insertNode(new TreeNode<int>(4));
cout << "Preorder >> ";
tree.preorder(tree.getRoot());
cout << endl;
// Tree에서 노드 찾기
int number;
cout << "Input number to search >> ";
cin >> number;
TreeNode<int>* found = tree.search(tree.getRoot(), number);
if (found != null) {
cout << "Found node." << endl;
cout << *found;
}
else {
cout << "Not found node." << endl;
}
}

구현결과

찾을 노드 데이터로 5를 넣었을 땐 정상적으로 찾아지고, 해당 노드의 정보를 출력해 준다.
5는 오른쪽 자식 노드가 없으므로 오른쪽 노드는 출력되지 않은 모습이다.

찾을 노드 데이터로 239를 넣었더니 못찾았다고 정상 수행된다.

비전공자를 위한 안드로이드 강의, 1강 오리엔테이션

안녕하세요, 비전공자를 위한 안드로이드 강의의 금손입니다.
안드로이드를 배우고 싶은 일반인들을 위해 강의를 마련 해 보았습니다.
이 강의는 유튜브 동영상과 함께 진행됩니다!
각자의 스타일에 맞게 강의를 들어주시면 됩니다.


강의 커리큘럼

1강 오리엔테이션 : 안드로이드 프로젝트 구조 알아보기

2강 초간단 주사위 앱 만들기 : TextView, Button 다루기

3강 화면을 넘겨보자 : Intent

4강 리스트 만들기 : ListView

5강 즐겨찾기 앱 만들기

6강 라이브러리 활용하기


강의로 얻게 되는것

안드로이드 앱의 기본 작동 원리를 배우게 됩니다!
이것만으로도 충분히 앱 서비스를 만들 수 있습니다.
여러분의 상상력과 아이디어와 함께라면요.
* 주의 서버(백엔드) 및 DB에 관해서는 다루지 않습니다.


안드로이드 스튜디오 설치하기 & 시작하기

https://developer.android.com/studio/index.html?hl=ko

안드로이드 앱은 Android Studio에서 만듭니다.
Android Studio는 은근히 높은 사양을 요구합니다.


안드로이드 프로젝트의 구조

대강 펼쳐본 안드로이드 프로젝트의 구조입니다.
섹션별로 나누어서 설명하도록 하겠습니다.

앱 설정 관련 부분

앱 설정 관련 부분으로는 manifests > AndroidManifest.xml
Gradle Scripts > build.gradle (app 수준), Gradle Scripts > build.gradle (프로젝트 수준) 3가지 정도가 있겠습니다.
이 중에서 Gradle Scripts > build.gradle (프로젝트 수준)은 자주 만지지 않습니다.

AndroidManifest.xml에서 할 수 있는 일

아래는 AndroidManifest.xml에서 할 수 있는 주요 일들을 적어놓은 것입니다.
더 많은 것을 할 수 있지만 이정도만 해도 충분할 것 같네요!

Activity 및 Service 등록, 설정하기

안드로이드에서 각 화면을 액티비티(Activity)라고 부릅니다.
현재 이 앱에서 사용하는 액티비티를 등록하고 설정할 수 있습니다.
AndroidManifest.xml에 등록되지 않은 액티비티에 접근하려 할 경우 앱에서 오류가 발생됩니다.

뿐만 아니라 앱을 시작하면 어떤 액티비티부터 실행할 것인지도 이 곳에서 설정할 수 있습니다.

앱 아이콘 및 테마설정하기

<application 아래에는 android:icon, android:theme 등 다양한 속성이 있는데요,
이를 바꿈으로서 앱 아이콘 및 테마를 바꿀 수 있습니다.

앱 권한 설정하기

앱을 만들때 네트워크(인터넷 연결)가 필요한 앱이라면 인터넷 접근권한,
카메라가 필요하다면 카메라 접근권한 등 다양한 접근 권한이 필요합니다.
다양한 접근 권한을 AndroidManifest.xml에서 설정할 수 있습니다.

안드로이드 M(마시멜로우, 6.0) 버전 이상에서의 몇몇 중요 권한들은
AndroidManifest.xml가아닌 Activity 코드 내에서 직접 요청해야하기도 합니다.

build.gradle (app 수준)에서 할 수 있는 일

build.gradle(app 수준)은 대략 아래처럼 생겼습니다.
여기에서 할 수 있는 일을 대략 설명해드리겠습니다.

apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "com.lx5475.course_1"
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
testCompile 'junit:junit:4.12'
}

앱 최소 OS 버전, 타겟 OS 버전 설정

버전 코드와 버전 이름 설정

앱을 구글 플레이에 배포시 버전코드를 차차 올려가면서 배포해야합니다.
예를 들어 구글 플레이에 버전코드3인 앱을 배포했다면 버전코드 1이나 2인 버전을 배포하려해도 배포되지 않습니다.

따라서 버전코드 4 이상인 apk만 배포할 수 있다는 것이죠!
버전 이름(VersionName)은 유저나 우리가 알아볼 수 있는 것입니다. 버전 코드를 높였다고 해서 꼭 버전이름도 높일 필요는 없기도합니다. ^^

proguard 설정

앱의 apk를 누가 다시 해체해서(decomplie) 여러분이 작성한 코드를 볼 수도 있습니다.

proguard를 설정함으로서 이를 어렵게 만들 수 있습니다.
그리고 이러한 설정도 build.gradle에서 할 수 있는 거죠.

라이브러리 불러오기

좋은 안드로이드 라이브러리를 발견하셨다면, 그걸 다운받아 사용하는 건 그저 dependencies {} 블록 안에 compile 'com.~' 코드 한 줄을 적어주는 것으로 쉽게 할 수 있습니다.

라이브러리를 사용하면 개발기간을 단축할 수 있습니다.
이름때문에 그저 “뭐지 왠 도서관..?” 이라 생각하실 수 있지만 쉽게 비유하자면 여러분이 닭 요리를 할건데 닭을 직접 잡지 않고, 마트가서 손질된 닭 고기를 사오는 것과 비슷합니다. 한마디로 겁나 좋은거죠 ^-^

디자인 관련 부분

디자인 관련 부분은 res 폴더 전부인데요, 각 폴더별로 설명을 드리도록 하겠습니다.

res > drawable

각종 이미지 에셋을 여기에 두고 사용하시면 됩니다.
예를들어 별 모양 이미지 파일인 star.png을 여기에 넣으면,
xml에서 사용할때는 android:src="@drawable/star.png"
java 코드에서 사용할 때는 R.drawable.star.
뭐 이런식으로 사용할 수 있게 되는 겁니다!

png등 이미지 파일이 아니라 스타일을 정의한 xml 파일도 넣기도 합니다.

res > layout

말 그대로 레이아웃 xml 파일들이 여기에 들어갑니다.
한 화면을 통째로 디자인해서 넣기도 하지만, 복잡한 디자인의 앱의 경우에는
채팅창 말풍선 레이아웃 따로, 채팅창 상단 바 따로, 입력창 따로 만들어 놓고 코드 상에서 동적으로 합치고들합니다.

res > values > colors.xml

앱에서 자주쓰이는 색상들을 정리해놓는 곳입니다.
HEX 코드로 #90f2da라는 색상이있다면 기억하기 어려우니 colors.xml에서
<color name="mint">#90f2da</color> 해놓고 R.color.mint로 편하게 쓰는 것이죠!

res > values > strings.xml

앱의 문자리소스를 다루는 곳입니다.
앱의 인터페이스에는 다양한 문자들이 있죠. 예를들면 ‘확인’, ‘취소’ 같은 게 있겠습니다.

이를 일일이 하드코딩하는 것보다 strings.xml에 저장해두고 쓰는 것이 매우 매우 좋습니다.
언어별로 strings.xml 파일을 만들 수 있기 때문에 영어권에서는 ‘확인’을 ‘OK’로 한다던지하는 작업을 손쉽게 할 수 있습니다.
앱 이름도 여기에서 바꿀 수 있죠!

프로그래밍 관련 부분

패키지네임 > MainActivity.java가 존재하는 폴더!

MainActivity.java라던지하는 파일들도 만들 수 있고,
class도 만들고 interface, enum도 만들고…
java 프로그래밍에 필요한 모든 것을 생성하고 사용할 수 있습니다.

프로그래밍에 관련된 모든 부분이라 할 수 있겠네요.

비전공자를 위한 안드로이드 강의, 2강 주사위 앱을 만들자!

안녕하세요, 비전공자를 위한 안드로이드 강의의 금손입니다.
오늘은 주사위 앱을 만들면서 버튼 클릭 액션을 배워보겠습니다.

버튼을 클릭하면 1~6 사이의 숫자가 랜덤하게 표시되는 앱입니다.


프로젝트 만들기

안드로이드 스튜디오에서 File > New > New projects를 눌러 프로젝트를 만듭니다.
Application Name은 영어 대소문자로 자유롭게 해 주세요. (예: DiceApplication)
그대로 Next > Next > Finish를 해서 프로젝트를 만들어줍니다.


UI 구성하기

activity_main.xml


res > layout > activity_main.xml을 수정 해 봅시다.
위와 같은 화면으로 만들 것입니다.

안드로이드에서 UI를 만들때는 res > layout 안에 만들어주면 됩니다.

TextView 하나와 Button 하나를 자유롭게 배치 해 주시고,
각각 뷰에 id를 적어줍니다.

id는 그 뷰를 식별하기 위한 고유값입니다.
예제에서 TextView에는 tv_result, Button에는 btn_roll이라고 id를 붙여주었는데요,
이렇게 규칙적이고 통일성있는 이름을 지어주시면 더 좋습니다.

아래는 예제 코드입니다.
여러가지 만져보시면서 각각 속성들이 어떻게 돌아가는지 살펴보세요.

<?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:id="@+id/activity_main"
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="com.lx5475.course_1.MainActivity">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true">
<TextView
android:id="@+id/tv_result"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Roll the Dice!"
android:layout_centerHorizontal="true"
android:layout_centerInParent="false"
android:gravity="center"
android:textSize="36sp" />
<Button
android:text="Roll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btn_roll" />
</LinearLayout>
</RelativeLayout>


프로그래밍 하기

MainActivity.java

<패키지 네임> > MainActivity.java 파일을 열어봅시다.
아마도 대략 아래와 같은 상태일 것입니다.

package com.lx5475.course_1;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}

setContentView(R.layout.activity_main);에서 이 액티비티가 우리가 방금 만든
activity_main.xml의 화면을 보여주고 있다는 것을 알 수 있습니다.

onCreate()는 화면이 생성될때 자동으로 실행되는 함수입니다.
거의 main함수라고 보시면 될 것 같네요. 이 블록 안에다가 코드를 적어주도록 하겠습니다.

package com.lx5475.course_1;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
private TextView tv_result;
private Button btn_button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
btn_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 1~6 까지 랜덤 숫자를 얻는다.
Random dice = new Random();
int result = dice.nextInt(6) + 1;
// TextView에 표시한다.
tv_result.setText(String.valueOf(result));
}
});
}
public void init() {
tv_result = (TextView) findViewById(R.id.tv_result);
btn_button = (Button) findViewById(R.id.btn_roll);
}
}

여기서 외울 코드가 너무 많아서 혼란스러우실 수 있습니다.
하지만 여러분은 코드를 외우는게 아니라, 어떤 메소드가 어떤 역할을 하는지만 알고 있으면 됩니다.
즉 아래와 같은 사실만 기억하면 된다는 겁니다!

1) “아, 버튼을 클릭하는 액션을 정의하려면 OnClickListener가 필요하구나!”

2) “xml에 정의한 뷰를 불러오려면 findViewById()를 사용하는구나~”

3) “TextView의 글자를 바꾸려면 setText()를 사용하는구나!”

간단하죠?
이 코드를 눈감고 못 쓰신다고 해서 코딩을 못하는게 아니라는 겁니다!
저도 물론 눈감고 못씁니다. 기억안날땐 그때 그때 찾아보면서 그렇게 익혀나가면 되는겁니다.


오늘 배운걸로 해볼 수 있는 것들

오늘 배운 OnClickListener를 이용해서 아래와 같은 것도 시도 해 보세요.
여러분의 상상력을 동원해서 에러와 맞서싸우며 앱을 가지고 놀아보세요!

1) 버튼을 클릭하면 텍스트 뷰에 있는 값을 Log 또는 Toast 메세지로 출력하기

2) 버튼을 클릭하면 텍스트 뷰의 글자 크기가 커지도록 하기

3) 텍스트 뷰 안에있는 값을 계속 바뀌도록 하다가 버튼을 클릭하면 멈추게 하기

한 포크 새우 그림

2016년 8월 6일

아크릴 물감으로 그렸다.
새우는 너무 좋다…

엄마께서는 이 그림이 무슨 의미냐고 했다.

심오한 의미를 찾을 필요없이 그냥 새우가 먹고싶어 그린거다.