14 มกราคม 2556

[Android Code] เปลี่ยนภาพ Marker ใน Google Maps Android API v2


* Google Maps Android API v2 ไม่สามารถรันทดสอบบน AVD ได้ *


รอบนี้ก็ขอต่อจากเรื่อง Marker ของ Google Maps เลยละกัน
คราวนี้ก็จะเป็นการเปลี่ยนภาพ Marker ที่ใช้ปักลงบนแผนที่
สามารถเปลี่ยนสีหรือเปลี่ยนเป็นภาพอะไรก็ได้ตามใจชอบ


สำหรับการติดตั้งเบื้องต้นเพื่อจะใช้งาน API v2 ให้อ่านที่

โดยปกติแล้ว Marker เดิมของ Google Maps จะใช้ภาพนี้



ถ้าผู้ที่หลงเข้ามาอ่านอยากเปลี่ยนภาพ Marker ก็ใช้คำสั่ง icon ได้เลย
GoogleMap mMap = ((SupportMapFragment)getSupportFragmentManager()
    .findFragmentById(R.id.map)).getMap();

mMap.addMarker(new MarkerOptions().position(
    new LatLng(13.751, 100.534))
    .icon(BitmapDescriptorFactory.fromAsset("marker_icon.png"))
    .title("Asset"));

โดยที่ marker_icon.png คือไฟล์ภาพที่เจ้าของบล็อกใช้เป็น Marker
ซึ่งทำขึ้นมาเองแล้วเอาไปไว้ในโฟลเดอร์ assets ของโปรเจค



ในกรณีที่ผู้ที่หลงเข้ามาอ่านจะใช้ภาพใน drawable ก็เปลี่ยนมาใช้คำสั่งตามนี้
GoogleMap mMap = ((SupportMapFragment)getSupportFragmentManager()
    .findFragmentById(R.id.map)).getMap();

mMap.addMarker(new MarkerOptions().position(
    new LatLng(13.751, 100.535))
    .icon(BitmapDescriptorFactory.fromResource(R.drawable.marker_icon))
    .title("Drawable"));

ส่วนไฟล์ภาพก็เอามาไว้ใน drawable หรือว่าจะแยกตามหน้าจอก็ได้


นอกจาก assets และ drawable ก็จะมี bitmap กับ file ด้วย
แต่เจ้าของบล็อกไม่ลงตัวอย่างนะ เพราะไม่ค่อยได้ใช้
โดยภาพที่ใช้ในบทความนี้จะเป็นภาพ Marker ที่ลองวาดเล่นๆ



ในกรณีที่ไม่อยากเปลี่ยนภาพแต่อยากเปลี่ยนสีจากของเดิม
ก็จะมีสีให้เลือกอยู่ในระดับหนึ่งแล้ว ทั้งหมด 10 สี ดังนี้


เวลาจะเปลี่ยนสี Marker ให้เป็นสีดังกล่าว ก็ให้ใช้คำสั่ง
GoogleMap mMap = ((SupportMapFragment)getSupportFragmentManager()
    .findFragmentById(R.id.map)).getMap();
mMap.addMarker(new MarkerOptions().position(
    new LatLng(13.745, 100.534))
    .icon(BitmapDescriptorFactory.defaultMarker(
    BitmapDescriptorFactory.HUE_AZURE)));

ทีนี้ก็มาดูตัวอย่างของบทความนี้กันเลยดีกว่า

Main.java


1. ประกาศ mMap จากคลาส GoogleMap แล้วกำหนดค่าเป็น R.id.map ที่สร้างไว้ใน Layout

2. กำหนดให้แผนที่เลื่อนไปยังพิกัด 13.750, 100.100.53440 แล้วซูมเข้าไปที่ระดับ 16

3. ปัก Marker ที่พิกัด 13.751, 100.534 โดยใช้ภาพจาก assets/marker_icon.png
จากนั้นก็กำหนดข้อความให้กับ Marker ว่า "Asset" เพื่อให้แสดงว่าเป็นภาพจาก assets

4. ปัก Marker ที่พิกัด 13.751, 100.535 โดยใช้ภาพจาก drwable/marker_icon.png
จากนั้นก็กำหนดข้อความให้กับ Marker ว่า "Drawable" เพื่อให้แสดงว่าเป็นภาพจาก drawable

5. ปัก Marker ที่พิกัด 13.745, 100.534 โดยให้ Marker เปลี่ยนเป็นสี Azure


พอลองทดสอบดูก็จะพบว่ามี Marker เรียงอยู่ตามที่กำหนดไว้เลย






สำหรับพิกัดบนแผนที่ ผู้ที่หลงเข้ามาอ่านสามารถใช้ Coordinate Finder
ในการช่วยหาพิกัดได้นะ เปิดแอพขึ้นมาแล้วจิ้มเลือกที่ที่ต้องการเลย
สามารถดาวน์โหลดได้จาก Coordinate Finder [Play Store]




Main.java
package app.akexorcist.googlemapsv2markericon;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Window;

public class Main extends FragmentActivity {    
    public void onCreate(Bundle savedInstanceState) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
                
        GoogleMap mMap = ((SupportMapFragment)getSupportFragmentManager()
                .findFragmentById(R.id.map)).getMap();

        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
                new LatLng(13.750, 100.53440), 16));    

        mMap.addMarker(new MarkerOptions().position(
                new LatLng(13.751, 100.534))
                .icon(BitmapDescriptorFactory
                        .fromAsset("marker_icon.png"))
                .title("Asset"));
        mMap.addMarker(new MarkerOptions().position(
                new LatLng(13.751, 100.535))
                .icon(BitmapDescriptorFactory
                        .fromResource(R.drawable.marker_icon))
                .title("Drawable"));
        
        mMap.addMarker(new MarkerOptions().position(
                new LatLng(13.745, 100.534))
                .icon(BitmapDescriptorFactory.defaultMarker(
                        BitmapDescriptorFactory.HUE_AZURE)));
        mMap.addMarker(new MarkerOptions().position(
                new LatLng(13.746, 100.534))
                .icon(BitmapDescriptorFactory.defaultMarker(
                        BitmapDescriptorFactory.HUE_BLUE)));
        mMap.addMarker(new MarkerOptions().position(
                new LatLng(13.747, 100.534))
                .icon(BitmapDescriptorFactory.defaultMarker(
                        BitmapDescriptorFactory.HUE_CYAN)));
        mMap.addMarker(new MarkerOptions().position(
                new LatLng(13.748, 100.534))
                .icon(BitmapDescriptorFactory.defaultMarker(
                        BitmapDescriptorFactory.HUE_GREEN)));
        mMap.addMarker(new MarkerOptions().position(
                new LatLng(13.749, 100.534))
                .icon(BitmapDescriptorFactory.defaultMarker(
                        BitmapDescriptorFactory.HUE_MAGENTA)));
        mMap.addMarker(new MarkerOptions().position(
                new LatLng(13.745, 100.535))
                .icon(BitmapDescriptorFactory.defaultMarker(
                        BitmapDescriptorFactory.HUE_ORANGE)));
        mMap.addMarker(new MarkerOptions().position(
                new LatLng(13.746, 100.535))
                .icon(BitmapDescriptorFactory.defaultMarker(
                        BitmapDescriptorFactory.HUE_RED)));
        mMap.addMarker(new MarkerOptions().position(
                new LatLng(13.747, 100.535))
                .icon(BitmapDescriptorFactory.defaultMarker(
                        BitmapDescriptorFactory.HUE_ROSE)));
        mMap.addMarker(new MarkerOptions().position(
                new LatLng(13.748, 100.535))
                .icon(BitmapDescriptorFactory.defaultMarker(
                        BitmapDescriptorFactory.HUE_VIOLET)));
        mMap.addMarker(new MarkerOptions().position(
                new LatLng(13.749, 100.535))
                .icon(BitmapDescriptorFactory.defaultMarker(
                        BitmapDescriptorFactory.HUE_YELLOW)));
    }
}

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"  >

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

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="app.akexorcist.googlemapsv2markericon"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="8" />
    
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name=
        "com.google.android.providers.gsf.permission.READ_GSERVICES"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
      <uses-permission android:name=
        "app.akexorcist.googlemapsv2markericon.permission.MAPS_RECEIVE"/>
      
    <permission 
        android:name=
                "app.akexorcist.googlemapsv2markericon.permission.MAPS_RECEIVE"
        android:protectionLevel="signature"/>
    
    <uses-feature android:glEsVersion="0x00020000" android:required="true"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="app.akexorcist.googlemapsv2markericon.Main"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <meta-data
           android:name="com.google.android.maps.v2.API_KEY"
           android:value="your_api_key"/>
    </application>
</manifest>


สำหรับผู้ที่หลงเข้ามาอ่านคนใดที่ต้องการไฟล์ตัวย่าง
สามารถดาวน์โหลดได้จาก Google Maps V2 Marker Icon

เมื่อดาวน์โหลดตัวอย่างไป Import แล้วให้ตรวจสอบตามนี้
• ใส่ API Key ที่ไปขอจาก Google API ลงใน AndroidManifest.xml
• เลือก Library ของ google-play-services_lib ให้ตรงกับเครื่อง

อาจจะมีปัญหาพอสมควรสำหรับผู้ที่ดาวน์โหลดไปทดสอบ
เพราะว่าการใช้ Google Maps นี้มีการขอ API Key และ Library
ดังนั้นจึงควรตรวจสอบให้แน่ใจว่าได้กำหนดไว้ถูกต้องแล้ว 
และก็อย่าลืมว่าทดสอบบน AVD หรือ Emulator ไม่ได้นะ
เพราะต้องมี Play Store ซึ่ง AVD ไม่มี ทำให้แอป Force Close





เหล่าพันธมิตรแอนดรอยด์

Devahoy Layer Net NuuNeoI The Cheese Factory Somkiat CC Mart Routine Artit-K Arnondora Kamonway Try to be android developer Oatrice Benz Nest Studios Kotchaphan@Medium Jirawatee@Medium Travispea@Medium