자바 안드로이드 앱개발 강좌, 내비게이션 뷰 – 드로어 화면 구성

작성자: 조광형

작성일: 2024년 11월 26일

1. 소개

안드로이드 앱 개발에서 내비게이션 뷰(Navigation View)는 사용자가 앱 내에서 다른 화면으로 효율적으로 이동할 수 있도록 돕는 중요한 UI 컴포넌트입니다. 이 강좌에서는 자바를 사용하여 안드로이드 앱의 내비게이션 뷰를 구성하는 방법을 자세히 설명하겠습니다. 또한, 실제 예제와 함께 드로어 레이아웃을 설정하여 사용자 친화적인 네비게이션을 구현하는 방법도 살펴볼 것입니다.

2. 내비게이션 뷰란?

내비게이션 뷰는 보통 화면의 왼쪽 또는 오른쪽에 숨겨져 있다가 사용자가 특정 아이콘(햄버거 아이콘)을 클릭하면 슬라이드 방식으로 나타나는 메뉴입니다. 사용자는 이 내비게이션 뷰를 통해 앱의 다양한 섹션으로 쉽게 이동할 수 있습니다. Google Material Design 가이드라인에 따르면 내비게이션 뷰는 앱 사용성을 높이는 데 중요한 역할을 합니다.

3. 프로젝트 설정

내비게이션 뷰를 구현하기 위해 새로운 Android 프로젝트를 생성합니다. Android Studio를 열고 다음 단계를 따릅니다:

  1. 새 프로젝트 만들기: “Empty Activity” 선택
  2. 이름, 패키지 이름 및 프로젝트 위치 지정
  3. 언어를 “Java”로 선택하고 “Finish” 클릭

프로젝트 생성 후, 필요한 라이브러리와 의존성을 추가하기 위해 build.gradle 파일을 수정합니다. 내비게이션 뷰는 다음 의존성이 필요합니다:

implementation 'com.google.android.material:material:1.5.0'

4. 레이아웃 구성

내비게이션 뷰와 드로어 레이아웃을 설정하기 위해 activity_main.xml 파일을 수정합니다. 기본 레이아웃으로 DrawerLayout을 사용하여 내비게이션 뷰를 포함한 구조를 만듭니다. 아래는 기본 레이아웃 구성 예제입니다.

<androidx.drawerlayout.widget.DrawerLayout
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <!-- Main content goes here -->

    </FrameLayout>

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/drawer_menu" 
        app:headerLayout="@layout/nav_header">
    </com.google.android.material.navigation.NavigationView>

</androidx.drawerlayout.widget.DrawerLayout>

5. 메뉴 리소스 정의

내비게이션 뷰에 표시될 메뉴를 정의하려면 res/menu 폴더 안에 새로운 XML 파일을 생성합니다. 메뉴 XML 파일 (예: drawer_menu.xml)에 항목을 추가하여 내비게이션 메뉴를 설정합니다.

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/nav_home"
        android:title="홈" />
    <item
        android:id="@+id/nav_gallery"
        android:title="갤러리" />
    <item
        android:id="@+id/nav_slideshow"
        android:title="슬라이드쇼" />
</menu>

6. 내비게이션 뷰 활용하기

MainActivity.java 파일을 수정하여 내비게이션 뷰의 항목 선택을 처리합니다. 사용자가 내비게이션 메뉴 항목을 선택할 때 각각의 동작을 정의할 수 있습니다.

public class MainActivity extends AppCompatActivity {

    private DrawerLayout drawerLayout;
    private NavigationView navigationView;

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

        drawerLayout = findViewById(R.id.drawer_layout);
        navigationView = findViewById(R.id.nav_view);

        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawerLayout, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawerLayout.addDrawerListener(toggle);
        toggle.syncState();

        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                int id = item.getItemId();
                switch (id) {
                    case R.id.nav_home:
                        // 홈 항목 선택 시 동작
                        break;
                    case R.id.nav_gallery:
                        // 갤러리 항목 선택 시 동작
                        break;
                    case R.id.nav_slideshow:
                        // 슬라이드쇼 항목 선택 시 동작
                        break;
                }
                drawerLayout.closeDrawer(GravityCompat.START);
                return true;
            }
        });
    }
}

7. 사용자 인터페이스 개선

내비게이션 뷰는 기본적으로 메뉴와 헤더 뷰를 사용하여 구성할 수 있습니다. 헤더 뷰를 추가하여 사용자에게 개인화된 경험을 제공할 수 있습니다. nav_header.xml 파일을 추가하여 사용자 정보를 표시하거나 링크를 제공할 수 있습니다.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:src="@drawable/header_image" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="사용자 이름"
        android:textColor="@android:color/black" />

</LinearLayout>

8. 드로어 열기 및 닫기 애니메이션

드로어를 여는 애니메이션은 사용자가 내비게이션 버튼을 클릭할 때마다 자동으로 처리됩니다. 그러나 사용자가 스와이프 제스처로 드로어를 열거나 닫을 수 있도록 설정할 수 있습니다. 이를 통해 더 자연스러운 사용자 경험을 제공합니다.

사용하려면 DrawerLayoutsetDrawerListener 메소드를 통해 리스너를 등록합니다. 사용자가 드로어를 열었을 때와 닫았을 때의 행동을 정의할 수 있습니다.

drawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() {
            @Override
            public void onDrawerSlide(@NonNull View drawerView, float slideOffset) {
                // 드로어와 연결된 애니메이션 동작
            }

            @Override
            public void onDrawerOpened(@NonNull View drawerView) {
                // 드로어가 열렸을 때 동작
            }

            @Override
            public void onDrawerClosed(@NonNull View drawerView) {
                // 드로어가 닫혔을 때 동작
            }

            @Override
            public void onDrawerStateChanged(int newState) {
                // 드로어 상태 변경 시 동작
            }
        });

9. 화면 전환 애니메이션 구현하기

내비게이션 뷰에서 선택된 메뉴 아이템에 따라 다른 Activity로 전환할 수 있습니다. 이때 화면 전환 애니메이션을 추가하여 사용자의 경험을 향상시킬 수 있습니다. 아래는 Intent를 통해 새로운 Activity로 전환할 때 애니메이션을 적용하는 방법입니다.

@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
    Intent intent;
    switch (item.getItemId()) {
        case R.id.nav_home:
            intent = new Intent(this, HomeActivity.class);
            startActivity(intent);
            overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left);
            break;
        case R.id.nav_gallery:
            intent = new Intent(this, GalleryActivity.class);
            startActivity(intent);
            overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left);
            break;
    }
    drawerLayout.closeDrawer(GravityCompat.START);
    return true;
}

10. 테스트 및 디버깅

앱을 완료한 후, 에뮬레이터 또는 실제 디바이스에서 충분히 테스트하여 드로어가 올바르게 작동하고 있는지 확인합니다. 버튼 클릭 시 예상대로 행동하는지, 메뉴 항목 선택 시 올바른 화면으로 전환되는지 확인합니다.
또한, 드로어가 열리고 닫힐 때의 애니메이션 효과를 테스트하여 매끄럽게 작동하는지 확인합니다.

11. 결론

이번 강좌에서는 자바를 사용해 안드로이드 앱에서 내비게이션 뷰를 구현하는 방법을 다루었습니다. 내비게이션 뷰는 사용자 친화적인 앱 구성의 중요한 요소로, 사용자에게 향상된 탐색 경험을 제공합니다.
본 강좌에서 설명한 내용을 바탕으로 여러분만의 앱에 맞는 내비게이션 뷰를 설정하고, 다양한 UI 요소 및 애니메이션을 활용해 풍부한 사용자 경험을 제공하시길 바랍니다.

© 2023 조광형. 모든 권리 보유.

자바 안드로이드 앱개발 강좌, 뉴스 앱 만들기

안녕하세요! 오늘은 안드로이드 앱을 개발하는 흥미로운 여정을 시작해 보겠습니다. 본 강좌에서는 자바를 활용하여 간단한 뉴스 앱을 만드는 과정을 단계별로 설명할 것입니다. 여러분이 앱 개발에 대한 깊은 이해를 갖게 되길 바라며, 이 강좌를 통해 유용한 기술들을 배우시기 바랍니다.

1. 앱 기획 및 요구사항 분석

뉴스 앱을 만들기 전에 우선 앱의 주요 기능과 요구사항을 정리해 보겠습니다. 다음은 기본 요구사항 목록입니다:

  • 뉴스 목록을 보여준다.
  • 각 뉴스 항목을 클릭할 수 있어야 한다.
  • 뉴스의 상세 내용을 볼 수 있어야 한다.
  • 뉴스 기사는 인터넷에서 API를 통해 가져온다.

2. 개발 환경 설정

앱 개발을 위해 먼저 Android Studio를 다운로드하고 설치해야 합니다. Android Studio는 공식 안드로이드 IDE로, 다양한 기능을 제공합니다. 아래의 단계에 따라 환경을 설정해보세요:

  1. Android Studio를 공식 웹사이트에서 다운로드하여 설치합니다.
  2. 설치 후 새로운 프로젝트를 생성합니다.
  3. 프로젝트 템플릿에서 ‘Empty Activity’를 선택합니다.
  4. 프로젝트 이름을 ‘NewsApp’으로 설정하고, 언어는 ‘Java’를 선택합니다.
  5. 마무리 후 프로젝트가 생성되면, 왼쪽의 파일 탐색기에서 ‘app/src/main’ 디렉토리로 이동합니다.

3. API 선택하기

뉴스 데이터를 가져오기 위해 사용할 수 있는 여러 뉴스 API가 있습니다. 여기서는 ‘News API’를 사용하여 데이터를 가져올 예정입니다. 뉴스 API를 사용하려면 API 키가 필요합니다. 다음과 같은 절차를 진행하세요:

  1. News API 웹사이트에 가입합니다.
  2. API 키를 생성합니다.
  3. 받은 API 키를 안전하게 저장합니다.

4. 의존성 추가하기

Android Studio에서 Gradle을 사용하여 쉽게 의존성을 추가할 수 있습니다. 뉴스 API에 접근하기 위해 ‘Retrofit’과 ‘Gson’ 라이브러리를 사용할 것입니다. 아래의 코드를 ‘build.gradle (Module: app)’ 파일에 추가해주세요:


dependencies {
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
}
        

5. 모델 클래스 생성하기

뉴스 데이터를 처리하기 위해 모델 클래스를 정의할 필요가 있습니다. ‘Article’이라는 클래스를 생성하겠습니다. 프로젝트의 ‘java’ 디렉토리 아래 ‘model’ 패키지를 생성하고, 그 안에 ‘Article.java’ 클래스를 만들어주세요.


package com.example.newsapp.model;

public class Article {
    private String title;
    private String description;
    private String url;
    private String urlToImage;

    // Getters and Setters
    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUrlToImage() {
        return urlToImage;
    }

    public void setUrlToImage(String urlToImage) {
        this.urlToImage = urlToImage;
    }
}
        

6. Retrofit 설정하기

Retrofit을 사용하여 API와 통신하기 위해 Service 클래스를 생성해야 합니다. ‘api’라는 패키지를 생성하고 그 안에 ‘NewsApiService.java’ 파일을 만들어보세요.


package com.example.newsapp.api;

import com.example.newsapp.model.Article;
import com.example.newsapp.model.NewsResponse;

import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;

public interface NewsApiService {
    @GET("top-headlines")
    Call getTopHeadlines(
            @Query("apiKey") String apiKey,
            @Query("country") String country
    );
}
        

7. 뉴스 응답 모델 생성하기

API에서 반환되는 JSON 데이터를 매핑하기 위해 ‘NewsResponse’라는 클래스를 만들어야 합니다. 앞서 생성한 ‘model’ 패키지 안에 ‘NewsResponse.java’ 클래스를 생성합니다.


package com.example.newsapp.model;

import java.util.List;

public class NewsResponse {
    private String status;
    private List
articles; public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public List
getArticles() { return articles; } public void setArticles(List
articles) { this.articles = articles; } }

8. MainActivity 구현하기

이제 MainActivity를 구현하여 API에서 뉴스를 가져오고 사용자에게 보여줄 준비를 합니다. ‘MainActivity.java’ 파일을 열고 다음 코드를 작성하세요.


package com.example.newsapp;

import android.os.Bundle;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;

import com.example.newsapp.api.NewsApiService;
import com.example.newsapp.model.NewsResponse;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class MainActivity extends AppCompatActivity {
    private static final String BASE_URL = "https://newsapi.org/v2/";
    private static final String API_KEY = "YOUR_API_KEY"; // API 키 입력

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

        loadNews();
    }

    private void loadNews() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        NewsApiService newsApiService = retrofit.create(NewsApiService.class);
        Call call = newsApiService.getTopHeadlines(API_KEY, "kr");
        call.enqueue(new Callback() {
            @Override
            public void onResponse(Call call, Response response) {
                if (response.isSuccessful()) {
                    // 뉴스 데이터 처리
                } else {
                    Toast.makeText(MainActivity.this, "뉴스를 가져오는 데 실패했습니다.", Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call call, Throwable t) {
                Toast.makeText(MainActivity.this, "네트워크 오류: " + t.getMessage(), Toast.LENGTH_LONG).show();
            }
        });
    }
}
        

9. 뉴스 목록 보여주기

뉴스 목록을 보여주기 위해 RecyclerView를 사용합니다. ‘res/layout’ 폴더에 ‘item_article.xml’ 레이아웃 파일을 생성하고 다음 코드를 작성해 주세요.





    

    

        

10. RecyclerView 어댑터 만들기

RecyclerView를 사용하기 위해 어댑터 클래스를 작성해야 합니다. ‘adapter’라는 패키지를 생성하고 ‘ArticleAdapter.java’ 파일을 만들어 주세요.


package com.example.newsapp.adapter;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.newsapp.R;
import com.example.newsapp.model.Article;
import java.util.List;

public class ArticleAdapter extends RecyclerView.Adapter {
    private List
articleList; static class ArticleViewHolder extends RecyclerView.ViewHolder { TextView textTitle; TextView textDescription; ArticleViewHolder(View itemView) { super(itemView); textTitle = itemView.findViewById(R.id.textTitle); textDescription = itemView.findViewById(R.id.textDescription); } } public ArticleAdapter(List
articleList) { this.articleList = articleList; } @NonNull @Override public ArticleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_article, parent, false); return new ArticleViewHolder(view); } @Override public void onBindViewHolder(@NonNull ArticleViewHolder holder, int position) { Article article = articleList.get(position); holder.textTitle.setText(article.getTitle()); holder.textDescription.setText(article.getDescription()); } @Override public int getItemCount() { return articleList.size(); } }

11. RecyclerView 초기화 및 데이터 설정하기

MainActivity에서 RecyclerView를 초기화하고, API를 통해 가져온 데이터를 어댑터에 설정합니다. ‘MainActivity.java’를 수정하여 다음과 같이 업데이트 합니다.


import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

private RecyclerView recyclerView;
private ArticleAdapter articleAdapter;

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

    recyclerView = findViewById(R.id.recyclerView);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));

    loadNews();
}

private void loadNews() {
    ...
    call.enqueue(new Callback() {
        @Override
        public void onResponse(Call call, Response response) {
            if (response.isSuccessful()) {
                articleAdapter = new ArticleAdapter(response.body().getArticles());
                recyclerView.setAdapter(articleAdapter);
            } else {
                ...
            }
        }
        ...
    });
}
        

12. MainActivity 레이아웃 파일 수정하기

마지막으로 MainActivity의 레이아웃 파일을 수정하여 RecyclerView를 추가합니다. ‘res/layout/activity_main.xml’ 파일을 수정하여 다음과 같이 작성합니다.





    

        

13. 사용해보기 및 마무리

이제 모든 설정이 완료되었습니다! 앱을 실행해보면 최신 뉴스 기사를 목록으로 확인할 수 있습니다. API에서 가져온 데이터를 통해 사용자에게 유용한 정보를 제공하는 간단한 뉴스 앱이 완성되었습니다.

14. 추가 기능 구현하기

이번 강좌에서는 기본적인 뉴스 앱을 만드는 과정을 배우았습니다. 더 나아가 다음과 같은 추가 기능들을 구현해보세요:

  • 뉴스 상세 페이지 구현하기
  • 뉴스 기사 검색 기능 추가하기
  • 즐겨찾기 기능 추가하기
  • 다양한 뉴스 카테고리 추가하기

15. 결론

뉴스 앱 만들기를 통해 자바와 안드로이드의 기본적인 사용법을 익힐 수 있었습니다. 앞으로 더 많은 앱을 개발하면서 실력을 키워나가시길 바랍니다. 질문이나 의견이 있으신 분들은 댓글로 남겨주세요!

자바 안드로이드 앱개발 강좌, 구글 지도 활용하기

안드로이드 앱 개발에서 구글 지도를 사용하는 것에 대한 이해는 많은 개발자들에게 큰 가치가 있습니다.
구글 지도 API를 활용하면 사용자가 실시간으로 지도 정보를 보고, 특정 위치를 찾고, 내비게이션 기능을 제공하는 등의
다양한 기능을 구현할 수 있습니다. 이번 글에서는 자바를 사용하여 안드로이드 앱에서 구글 지도를 구현하는 방법과
주요 기능들을 자세히 설명하고 몇 가지 예제 코드를 제공하겠습니다.

1. 구글 지도 API란?

구글 지도 API는 구글에서 제공하는 지도 정보를 사용하여 웹사이트나 모바일 애플리케이션에서 지도 기능을 쉽게
구현할 수 있도록 해주는 서비스입니다. 이 API를 사용하면 사용자가 원하는 지역의 지도, 마커, 경로 등의 정보
를 제공받을 수 있습니다. 안드로이드 앱에서 구글 지도를 사용하기 위해서는 구글 맵 API를 연동해야 합니다.

2. 구글 지도 API 키 생성하기

구글 지도를 앱에서 사용하기 위해서는 API 키가 필요합니다. 다음은 API 키를 생성하는 방법입니다.

  1. 구글 클라우드 플랫폼에 로그인합니다. (Google Cloud Console)
  2. 새 프로젝트를 생성합니다.
  3. 대시보드에서 ‘API 및 서비스’ > ‘라이브러리’로 이동합니다.
  4. ‘Maps SDK for Android’를 검색하여 활성화합니다.
  5. ‘API 및 서비스’ > ‘사용자 인증 정보’로 이동하여 API 키를 생성합니다.

3. 안드로이드 프로젝트 설정

API 키 준비가 완료되면 안드로이드 프로젝트를 설정합니다. Android Studio를 열고 새로운 프로젝트를 생성합니다.
여기서는 ‘Empty Activity’를 선택하겠습니다.

3.1. Gradle 파일 수정

`build.gradle` 파일을 열고 다음 의존성을 추가합니다:


    dependencies {
        implementation 'com.google.android.gms:play-services-maps:17.0.1' // 구글 맵 의존성
    }
    

3.2. AndroidManifest.xml 수정

`AndroidManifest.xml` 파일에서 다음과 같이 권한과 API 키를 추가합니다:


    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.mymapapp">

        <uses-permission android:name="android.permission.INTERNET"/>
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

        <application
            ...
            android:meta-data
                android:name="com.google.android.geo.API_KEY"
                android:value="YOUR_API_KEY"/>
        </application>
    </manifest>
    

4. 지도 화면 구현하기

이제 본격적으로 지도를 화면에 표시해보겠습니다. `activity_main.xml` 파일을 수정하여 지도 프래그먼트를 추가합니다.


    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity">

        <fragment
            android:id="@+id/map"
            android:name="com.google.android.gms.maps.SupportMapFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

    </LinearLayout>
    

4.1. MainActivity.java 구현

지도를 제어하기 위해 `MainActivity.java` 파일을 다음과 같이 수정합니다.


    package com.example.mymapapp;

    import android.os.Bundle;
    import androidx.fragment.app.FragmentActivity;
    import com.google.android.gms.maps.CameraUpdateFactory;
    import com.google.android.gms.maps.GoogleMap;
    import com.google.android.gms.maps.OnMapReadyCallback;
    import com.google.android.gms.maps.SupportMapFragment;
    import com.google.android.gms.maps.model.LatLng;
    import com.google.android.gms.maps.model.MarkerOptions;

    public class MainActivity extends FragmentActivity implements OnMapReadyCallback {

        private GoogleMap mMap;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
            mapFragment.getMapAsync(this);
        }

        @Override
        public void onMapReady(GoogleMap googleMap) {
            mMap = googleMap;

            // 예시 위치: 서울
            LatLng seoul = new LatLng(37.5665, 126.978);
            mMap.addMarker(new MarkerOptions().position(seoul).title("Marker in 서울"));
            mMap.moveCamera(CameraUpdateFactory.newLatLng(seoul));
        }
    }
    

5. 마커 추가하기

사용자가 다양한 장소를 쉽게 찾을 수 있도록 마커를 추가하는 기능을 구현합니다. 예시 코드에서 이미 한 마커를 추가했지만,
여러 개의 마커를 추가하는 방법을 보여드리겠습니다.


    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        // 서울 마커
        LatLng seoul = new LatLng(37.5665, 126.978);
        mMap.addMarker(new MarkerOptions().position(seoul).title("Marker in 서울"));

        // 부산 마커
        LatLng busan = new LatLng(35.1796, 129.0756);
        mMap.addMarker(new MarkerOptions().position(busan).title("Marker in 부산"));

        // 대구 마커
        LatLng daegu = new LatLng(35.8714, 128.6014);
        mMap.addMarker(new MarkerOptions().position(daegu).title("Marker in 대구"));

        // 카메라 위치 변경
        mMap.moveCamera(CameraUpdateFactory.newLatLng(seoul));
    }
    

6. 위치 접근 허가 요청하기

위치 기반 서비스를 구현할 때는 사용자로부터 위치 접근 권한을 요청해야 합니다. 다음은 위치 권한을 요청하는
방법입니다.


    import android.Manifest;
    import android.content.pm.PackageManager;
    import androidx.core.app.ActivityCompat;

    private static final int LOCATION_PERMISSION_REQUEST_CODE = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

        // 위치 권한 요청
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_PERMISSION_REQUEST_CODE);
        } else {
            mMap.setMyLocationEnabled(true);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                    mMap.setMyLocationEnabled(true);
                }
            }
        }
    }
    

7. 현재 위치 표시하기

사용자의 현재 위치를 지도에 표시하는 방법을 구현해보겠습니다. 방금 추가한 코드와 함께 .setMyLocationEnabled(true)
메서드를 통해 현재 위치를 표시할 수 있습니다. 현재 위치를 중심으로 카메라를 이동하려면 다음과 같이 수정합니다.


    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        // 사용자 위치 접근 허용 여부에 따라서 현재 위치 표시
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            mMap.setMyLocationEnabled(true);
        }

        // 서울 마커
        LatLng seoul = new LatLng(37.5665, 126.978);
        mMap.addMarker(new MarkerOptions().position(seoul).title("Marker in 서울"));
        
        // 카메라 위치 변경
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(seoul, 10));
    }
    

8. 경로 찾기 기능 구현하기

경로 찾기 기능은 사용자와 특정 목적지 간의 길을 찾는 데 사용됩니다. Google Directions API를 활용하여
경로를 찾을 수 있지만, 이를 위해서는 추가적인 작업이 필요합니다.

Directions API를 호출하기 위해 Axios 또는 Retrofit 같은 HTTP 클라이언트를 사용하여 요청을 보내고,
반환된 경로 데이터를 분석해 지도의 Polyline에 표시할 수 있습니다. 이 부분은 간단하게 설명하겠습니다.


    // Retrofit을 이용한 Directions API 호출
    public interface DirectionsService {
        @GET("directions/json")
        Call getDirections(@Query("origin") String origin,
                                          @Query("destination") String destination,
                                          @Query("key") String apiKey);
    }
    

이 API를 통해 얻은 경로 데이터를 통해 Polyline을 지도에 추가하여 경로를 표시할 수 있습니다.

9. 결론

이 글에서는 안드로이드 앱 개발에서 구글 지도를 활용하기 위한 기본적인 설정과 기능 구현 방법을
살펴보았습니다. 구글 지도 API를 활용하면 다양한 위치 기반 서비스를 제공하는 강력한 애플리케이션을
만들 수 있습니다. 추가로 사용자 친화적인 기능을 추가하고, Directions API를 활용하여 복잡한 경로
찾기 기능을 구현해보시기를 추천합니다.

앱 개발의 길은 쉽지 않지만, 구글 지도를 통해 다채로운 사용자 경험을 제공할 수 있는 가능성은 무한합니다.
여러분의 아이디어를 이끌어내는 데 도움이 되었길 바랍니다.

© 2023 블로그 아이디어

자바 안드로이드 앱개발 강좌, 기본적인 뷰 살펴보기

안드로이드 앱 개발에서 가장 기본적이면서도 중요한 부분이 바로 ‘뷰(View)’입니다. 뷰는 앱의 사용자 인터페이스를 구성하는 기본 요소로, 사용자와 상호작용하는 모든 요소를 포함합니다. 이 강좌에서는 안드로이드 애플리케이션에서 사용되는 주요 뷰의 종류와 사용법, 그리고 예제 코드를 통해 뷰를 어떻게 활용할 수 있는지에 대해 알아보겠습니다.

1. 뷰(View)란 무엇인가?

뷰는 화면에 표시되는 요소를 의미합니다. 이를 통해 사용자와 상호작용할 수 있는 버튼, 텍스트 필드, 이미지, 리스트 등을 구현할 수 있습니다. 안드로이드의 뷰 구조는 계층적이며, 각 뷰는 또 다른 뷰를 포함할 수 있습니다. 이처럼 복잡한 구조를 통해 개발자는 유연한 사용자 인터페이스를 만들 수 있습니다.

2. 안드로이드에서 사용할 수 있는 기본 뷰의 종류

  • TextView: 텍스트를 화면에 표시하는 데 사용됩니다.
  • EditText: 사용자가 텍스트를 입력할 수 있는 입력 필드입니다.
  • Button: 사용자가 클릭할 수 있는 버튼을 제공합니다.
  • ImageView: 이미지를 화면에 표시합니다.
  • CheckBox: 선택할 수 있는 체크박스를 제공합니다.
  • RadioButton: 여러 옵션 중 하나를 선택할 수 있도록 합니다.
  • Spinner: 드롭다운 리스트 형태의 선택 박스입니다.
  • ListView: 아이템 리스트를 표시합니다.
  • RecyclerView: 효율적으로 아이템 리스트를 표시함으로써 성능을 개선한 버전의 ListView입니다.

3. 각 뷰의 세부 설명 및 예제

3.1 TextView

TextView는 사용자에게 텍스트 정보를 표시할 수 있도록 도와주는 뷰입니다. 설정할 수 있는 속성으로는 글꼴, 크기, 색상, 줄 간격 등이 있습니다. 다음은 TextView를 사용하는 예제입니다.

xml
<TextView
    android:id="@+id/textView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello, Android!"
    android:textSize="20sp"
    android:textColor="#000000" />
java
TextView textView = findViewById(R.id.textView);
textView.setText("안녕하세요, 안드로이드!");

3.2 EditText

EditText는 사용자가 텍스트를 입력할 수 있는 필드입니다. 사용자로부터 데이터를 입력받고 처리하는 데 유용합니다. 다음은 EditText를 사용하는 예제입니다.

xml
<EditText
    android:id="@+id/editText"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="여기에 입력하세요" />
java
EditText editText = findViewById(R.id.editText);
String inputText = editText.getText().toString();

3.3 Button

Button은 사용자가 클릭할 수 있는 버튼입니다. 버튼을 클릭했을 때 특정 작업을 수행하도록 설정할 수 있습니다. 아래는 Button을 사용하는 예제입니다.

xml
<Button
    android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="클릭하세요" />
java
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Toast.makeText(getApplicationContext(), "버튼이 클릭되었습니다!", Toast.LENGTH_SHORT).show();
    }
});

3.4 ImageView

ImageView는 이미지를 화면에 표시하는 데 사용되는 뷰입니다. 다음 예제에서 ImageView를 어떻게 사용하는지 살펴보겠습니다.

xml
<ImageView
    android:id="@+id/imageView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:src="@drawable/sample_image" />
java
ImageView imageView = findViewById(R.id.imageView);
imageView.setImageResource(R.drawable.another_image);

3.5 CheckBox

CheckBox는 선택할 수 있는 체크박스 항목을 제공합니다. 여러 항목 중에서 선택하려는 경우 유용합니다. 아래 예제를 참고해 보세요.

xml
<CheckBox
    android:id="@+id/checkBox"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="옵션 선택" />
java
CheckBox checkBox = findViewById(R.id.checkBox);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (isChecked) {
            Toast.makeText(getApplicationContext(), "체크됨", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(getApplicationContext(), "체크 해제됨", Toast.LENGTH_SHORT).show();
        }
    }
});

3.6 RadioButton

RadioButton은 여러 옵션 중 하나를 선택할 수 있게 해주는 뷰입니다. 사용자는 라디오 버튼에서 하나만 선택할 수 있습니다. 예제는 다음과 같습니다.

xml
<RadioGroup
    android:id="@+id/radioGroup"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <RadioButton
        android:id="@+id/radioButton1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="옵션 1" />
    <RadioButton
        android:id="@+id/radioButton2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="옵션 2" />
</RadioGroup>
java
RadioGroup radioGroup = findViewById(R.id.radioGroup);
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(RadioGroup group, int checkedId) {
        switch (checkedId) {
            case R.id.radioButton1:
                Toast.makeText(getApplicationContext(), "옵션 1 선택", Toast.LENGTH_SHORT).show();
                break;
            case R.id.radioButton2:
                Toast.makeText(getApplicationContext(), "옵션 2 선택", Toast.LENGTH_SHORT).show();
                break;
        }
    }
});

3.7 Spinner

Spinner는 드롭다운 리스트 형태로 선택할 수 있는 아이템을 제공합니다. 다음은 Spinner의 사용 예제입니다.

xml
<Spinner
    android:id="@+id/spinner"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />
java
Spinner spinner = findViewById(R.id.spinner);
ArrayAdapter adapter = ArrayAdapter.createFromResource(this,
        R.array.options_array, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);

3.8 ListView

ListView는 항목 리스트를 표시하는데 사용됩니다. 여러 개의 항목을 심플하게 리스트 형태로 보여줄 수 있습니다. 아래는 ListView의 예제입니다.

xml
<ListView
    android:id="@+id/listView"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
java
ListView listView = findViewById(R.id.listView);
ArrayAdapter adapter = new ArrayAdapter(this,
        android.R.layout.simple_list_item_1, dataArray);
listView.setAdapter(adapter);

3.9 RecyclerView

RecyclerView는 ListView보다 더 유연하고 기능이 풍부한 리스트를 만들어주는 뷰입니다. 성능이 개선된 버전이라고 할 수 있습니다. RecyclerView 사용 예제는 다음과 같습니다.

xml
<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
java
RecyclerView recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
MyAdapter adapter = new MyAdapter(myDataList);
recyclerView.setAdapter(adapter);

4. 레이아웃(Layout)과 뷰의 관계

안드로이드에서 모든 뷰는 레이아웃 안에 배치됩니다. 레이아웃은 뷰를 어떻게 배열할지를 정의하는 컨테이너입니다. 일반적으로 사용하는 레이아웃의 종류로는 LinearLayout, RelativeLayout, ConstraintLayout, FrameLayout 등이 있습니다. 각 레이아웃의 특성과 사용법은 다음과 같습니다.

4.1 LinearLayout

LinearLayout은 자식 뷰를 수직 또는 수평으로 정렬할 수 있는 레이아웃입니다. 아래 예제에서는 LinearLayout을 사용하는 법을 설명합니다.

xml
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="첫 번째 텍스트" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="두 번째 텍스트" />
</LinearLayout>

4.2 RelativeLayout

RelativeLayout은 자식 뷰를 서로의 상대 위치에 따라 배열할 수 있게 해주는 레이아웃입니다. 제목과 설명이 서로의 위치 관계를 유지하면서 배치되는 예」を 들 수 있습니다.

xml
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="제목" />
    <TextView
        android:id="@+id/description"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/title"
        android:text="설명" />
</RelativeLayout>

4.3 ConstraintLayout

ConstraintLayout은 더 복잡한 사용자 인터페이스를 작성할 수 있도록 돕는 레이아웃입니다. 다양한 제약 조건을 통해 뷰의 위치를 정할 수 있으며, 더 많은 뷰를 더 간결하게 배치할 수 있습니다.

xml
<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/textView1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="제약 조건으로 배치된 텍스트"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

5. 뷰와 이벤트 처리

뷰를 사용할 때 가장 중요한 부분 중 하나가 바로 이벤트 처리입니다. 안드로이드에서는 다양한 유형의 사용자 입력 이벤트를 처리할 수 있습니다. 이벤트를 처리하기 위한 방법으로는 리스너를 사용하여 각 뷰에 대한 클릭, 터치 등의 이벤트를 처리합니다. 다음은 버튼 클릭 이벤트를 처리하는 방법입니다.

java
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // 버튼 클릭 시 수행할 작업
    }
});

6. 결론

이번 강좌에서는 안드로이드 앱 개발에서 가장 기본이 되는 ‘뷰(View)’에 대해 살펴보았습니다. 각종 뷰의 종류와 사용법, 레이아웃의 개념, 그리고 이벤트 처리 방식에 대해 배웠습니다. 이러한 기초적인 요소들을 이해하고 활용하는 것은, 더욱 복잡하고 다양한 기능의 앱을 개발하는 데 있어 중요한 첫 걸음이 될 것입니다. 다음 강좌에서는 더욱 발전된 콘텐츠로 돌아오겠습니다. 여러분의 안드로이드 앱 개발 여정에 행운을 빕니다!

자바 안드로이드 앱개발 강좌, 구글 지도 앱 만들기

안드로이드 앱 개발은 오늘날 가장 인기 있는 모바일 개발 분야 중 하나입니다. 다양한 라이브러리와 프레임워크를 통해 개발자들은 훌륭한 사용자 경험을 제공하는 앱을 만들 수 있습니다. 이번 강좌에서는 자바를 사용하여 구글 지도를 활용한 안드로이드 앱을 만드는 방법에 대해 설명하겠습니다. 본 강좌는 다음과 같은 단계로 진행됩니다:

  • 1. 프로젝트 설정
  • 2. 구글 지도 API 설정
  • 3. 지도를 앱에 표시하기
  • 4. 마커 추가 및 사용자 위치 표시
  • 5. 지도 스타일 및 기능 추가

1. 프로젝트 설정

먼저, 안드로이드 스튜디오를 열고 새로운 프로젝트를 생성합니다. 다음과 같은 설정을 따라 프로젝트를 설정합니다:

  • 이름: GoogleMapsApp
  • 패키지 이름: com.example.googlemapsapp
  • 언어: Java
  • 최소 API 레벨: API 21: Android 5.0 (Lollipop)

프로젝트가 생성되면, app/build.gradle 파일에 구글 지도 라이브러리를 추가해야 합니다. 이를 위해 다음 코드를 dependencies 섹션에 추가합니다:

implementation 'com.google.android.gms:play-services-maps:18.0.2'

이제 Gradle 파일을 Sync하여 종속성을 업데이트합니다.

2. 구글 지도 API 설정

구글 지도를 사용하기 위해서는 구글 클라우드 플랫폼에서 API 키를 발급받아야 합니다. 다음 단계를 따라 구글 지도 API 키를 생성합니다:

  1. 구글 클라우드 플랫폼에 로그인하여 새 프로젝트를 생성합니다.
  2. 대시보드에서 ‘API 및 서비스’ -> ‘라이브러리’로 이동합니다.
  3. ‘Google Maps Android API’를 검색하고 활성화합니다.
  4. ‘API 및 서비스’ -> ‘사용자인증 정보’에서 ‘사용자인증 정보 만들기’ 버튼을 클릭합니다.
  5. API 키를 선택하고 생성하여 발급받은 키를 복사합니다.

발급받은 API 키는 AndroidManifest.xml 파일 내에 추가해야 합니다:


<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.googlemapsapp">

    <application>
        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="YOUR_API_KEY"/>
        ...
    </application>

</manifest>

이제 구글 지도 API를 사용할 준비가 완료되었습니다.

3. 지도를 앱에 표시하기

구글 지도를 앱에 표시하기 위해 지도 프래그먼트를 레이아웃에 추가해야 합니다. res/layout/activity_main.xml 파일을 열고 다음 코드를 추가합니다:


<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"
    tools:context=".MainActivity">

    <fragment
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>

다음으로, MainActivity.java 파일에서 지도를 초기화하고 표시하는 코드를 추가하겠습니다:


import androidx.fragment.app.FragmentActivity;
import android.os.Bundle;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

public class MainActivity extends FragmentActivity implements OnMapReadyCallback {

    private GoogleMap mMap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        // 지도의 중심 위치 설정
        LatLng seoul = new LatLng(37.56, 126.97);
        mMap.moveCamera(CameraUpdateFactory.newLatLng(seoul));
    }
}

위의 코드에서, 지도가 준비되면 서울의 위치로 카메라를 이동하도록 설정했습니다.

4. 마커 추가 및 사용자 위치 표시

이제 사용자가 정의한 위치에 마커를 추가해 보겠습니다. onMapReady 메서드에 다음 코드를 추가하여 마커를 배치합니다:


    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        // 지도의 중심 위치 설정
        LatLng seoul = new LatLng(37.56, 126.97);
        mMap.moveCamera(CameraUpdateFactory.newLatLng(seoul));

        // 마커 추가
        mMap.addMarker(new MarkerOptions().position(seoul).title("Marker in Seoul"));

        // 사용자 위치 표시 허용
        mMap.setMyLocationEnabled(true);
    }

위의 코드는 서울 위치에 마커를 추가하고 사용자의 현재 위치를 표시하는 기능을 활성화합니다.

5. 지도 스타일 및 기능 추가

마지막으로, 구글 지도에 스타일을 추가하고 몇 가지 기능을 확장해 보겠습니다. 예를 들어, 사용자 위치가 변경될 때 마커를 업데이트하도록 하겠습니다:


import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;

public class MainActivity extends FragmentActivity implements OnMapReadyCallback {

    private GoogleMap mMap;
    private FusedLocationProviderClient fusedLocationClient;

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

        fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        LatLng seoul = new LatLng(37.56, 126.97);
        mMap.moveCamera(CameraUpdateFactory.newLatLng(seoul));
        mMap.addMarker(new MarkerOptions().position(seoul).title("Marker in Seoul"));
        mMap.setMyLocationEnabled(true);
        
        // 사용자 위치 업데이트 설정
        startLocationUpdates();
    }

    private void startLocationUpdates() {
        LocationRequest locationRequest = LocationRequest.create();
        locationRequest.setInterval(10000);
        locationRequest.setFastestInterval(5000);
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

        LocationCallback locationCallback = new LocationCallback() {
            @Override
            public void onLocationResult(LocationResult locationResult) {
                if (locationResult == null) {
                    return;
                }
                for (Location location : locationResult.getLocations()) {
                    // 사용자 위치 업데이트
                    LatLng userLocation = new LatLng(location.getLatitude(), location.getLongitude());
                    mMap.addMarker(new MarkerOptions().position(userLocation).title("You are here"));
                    mMap.moveCamera(CameraUpdateFactory.newLatLng(userLocation));
                }
            }
        };
        
        fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, null);
    }
}

위의 코드는 사용자의 위치가 변경될 때마다 마커를 업데이트하여 지도 위에 사용자 위치를 반영합니다.

결론

이제 기본적인 구글 지도 앱을 만들기 위한 모든 단계를 완료했습니다. 이 앱은 비즈니스나 개인 프로젝트등 다양한 용도로 확장할 수 있습니다. 필요한 추가 기능, 예를 들어 다양한 마커 스타일, 경로 표시, 또는 여러 위치 검색 등을 쉽게 구현할 수 있습니다. 안드로이드 앱 개발에 있어 구글 지도 API는 매우 유용한 도구입니다. 더 나아가 이 API를 사용하여 사용자에게 풍부한 경험을 제공할 수 있습니다. 다음 단계로는 이 앱을 추가 기능과 스타일로 발전시키는 것입니다.

이 강좌가 여러분의 앱 개발에 재미와 도움이 되었기를 바랍니다. 이제 여러분만의 구글 지도 앱을 만들어 보세요!