2016年10月16日 星期日

Google map api demo I

Ref :  https://github.com/googlemaps/android-samples/tree/master/ApiDemos


Ref : https://github.com/googlemaps/android-samples/issues



先看MainActivity


public final class MainActivity extends AppCompatActivity
        implements AdapterView.OnItemClickListener{}


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView list = (ListView) findViewById(R.id.list);
ListAdapter adapter = new CustomArrayAdapter(this, DemoDetailsList.DEMOS);
list.setAdapter(adapter);
list.setOnItemClickListener(this);
list.setEmptyView(findViewById(R.id.empty));
}

他的主畫面一進去就是一個 listview....把所有的  demp sample 列出來

然後設定 onItemClickListener...

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
DemoDetails demo = (DemoDetails) parent.getAdapter().getItem(position);
startActivity(new Intent(this, demo.activityClass));
}

得道要啟動的  DemoDetails  物件,  然後  startActivity....


至於甚麼是 CustomArrayAdapter 物件

private static class CustomArrayAdapter extends ArrayAdapter<DemoDetails> {

    /**     * @param demos An array containing the details of the demos to be displayed.     */    public CustomArrayAdapter(Context context, DemoDetails[] demos) {
        super(context, R.layout.feature, R.id.title, demos);
    }

    @Override    public View getView(int position, View convertView, ViewGroup parent) {
        FeatureView featureView;
        if (convertView instanceof FeatureView) {
            featureView = (FeatureView) convertView;
        } else {
            featureView = new FeatureView(getContext());
        }

        DemoDetails demo = getItem(position);

        featureView.setTitleId(demo.titleId);
        featureView.setDescriptionId(demo.descriptionId);

        Resources resources = getContext().getResources();
        String title = resources.getString(demo.titleId);
        String description = resources.getString(demo.descriptionId);
        featureView.setContentDescription(title + ". " + description);

        return featureView;
    }
}


至於甚麼是 DemoDetails

public class DemoDetails {
    /**     * The resource id of the title of the demo.     */    public final int titleId;

    /**     * The resources id of the description of the demo.     */    public final int descriptionId;

    /**     * The demo activity's class.     */    public final Class<? extends AppCompatActivity> activityClass;

    public DemoDetails(
            int titleId, int descriptionId, Class<? extends AppCompatActivity> activityClass) {
        this.titleId = titleId;
        this.descriptionId = descriptionId;
        this.activityClass = activityClass;
    }
}


裡面的成員變數就是

public final int titleId;

/** * The resources id of the description of the demo. */public final int descriptionId;

/** * The demo activity's class. */public final Class<? extends AppCompatActivity> activityClass;


其實就是新增一個物件...然後把這三個東西存到這個物件


至於在那裏初始化這些 calss name

重點就在這一行

ListAdapter adapter = new CustomArrayAdapter(this, DemoDetailsList.DEMOS);


他用了 static 這個關鍵字...也就是說不需要去新增她....他就已經存在程式裡面


public final class DemoDetailsList {

    /** This class should not be instantiated. */    private DemoDetailsList() {
    }

    public static final DemoDetails[] DEMOS = {
            new DemoDetails(R.string.basic_map_demo_label,
                    R.string.basic_map_demo_description,
                    BasicMapDemoActivity.class),
            new DemoDetails(R.string.camera_demo_label,
                    R.string.camera_demo_description,
                    CameraDemoActivity.class),
            new DemoDetails(R.string.camera_clamping_demo_label,
                    R.string.camera_clamping_demo_description,
                    CameraClampingDemoActivity.class),
            new DemoDetails(R.string.circle_demo_label,
                    R.string.circle_demo_description,
                    CircleDemoActivity.class),
            new DemoDetails(R.string.events_demo_label,
                    R.string.events_demo_description,
                    EventsDemoActivity.class),
            new DemoDetails(R.string.ground_overlay_demo_label,
                    R.string.ground_overlay_demo_description,
                    GroundOverlayDemoActivity.class),
            new DemoDetails(R.string.indoor_demo_label,
                    R.string.indoor_demo_description,
                    IndoorDemoActivity.class),
            new DemoDetails(R.string.layers_demo_label,
                    R.string.layers_demo_description,
                    LayersDemoActivity.class),
            new DemoDetails(R.string.lite_demo_label,
                    R.string.lite_demo_description,
                    LiteDemoActivity.class),
            new DemoDetails(R.string.lite_list_demo_label,
                    R.string.lite_list_demo_description,
                    LiteListDemoActivity.class),
            new DemoDetails(R.string.location_source_demo_label,
                    R.string.location_source_demo_description,
                    LocationSourceDemoActivity.class),
            new DemoDetails(R.string.map_in_pager_demo_label,
                    R.string.map_in_pager_demo_description,
                    MapInPagerDemoActivity.class),
            new DemoDetails(R.string.marker_demo_label,
                    R.string.marker_demo_description,
                    MarkerDemoActivity.class),
            new DemoDetails(R.string.multi_map_demo_label,
                    R.string.multi_map_demo_description,
                    MultiMapDemoActivity.class),
            new DemoDetails(R.string.my_location_demo_label,
                    R.string.my_location_demo_description,
                    MyLocationDemoActivity.class),
            new DemoDetails(R.string.options_demo_label,
                    R.string.options_demo_description,
                    OptionsDemoActivity.class),
            new DemoDetails(R.string.polygon_demo_label,
                    R.string.polygon_demo_description,
                    PolygonDemoActivity.class),
            new DemoDetails(R.string.polyline_demo_label,
                    R.string.polyline_demo_description,
                    PolylineDemoActivity.class),
            new DemoDetails(R.string.programmatic_demo_label,
                    R.string.programmatic_demo_description,
                    ProgrammaticDemoActivity.class),
            new DemoDetails(R.string.raw_map_view_demo_label,
                    R.string.raw_map_view_demo_description,
                    RawMapViewDemoActivity.class),
            new DemoDetails(R.string.retain_map_demo_label,
                    R.string.retain_map_demo_description,
                    RetainMapDemoActivity.class),
            new DemoDetails(R.string.save_state_demo_label,
                    R.string.save_state_demo_description,
                    SaveStateDemoActivity.class),
            new DemoDetails(R.string.snapshot_demo_label,
                    R.string.snapshot_demo_description,
                    SnapshotDemoActivity.class),
            new DemoDetails(R.string.split_street_view_panorama_and_map_demo_label,
                    R.string.split_street_view_panorama_and_map_demo_description,
                    SplitStreetViewPanoramaAndMapDemoActivity.class),
            new DemoDetails(R.string.street_view_panorama_basic_demo_label,
                    R.string.street_view_panorama_basic_demo_description,
                    StreetViewPanoramaBasicDemoActivity.class),
            new DemoDetails(R.string.street_view_panorama_events_demo_label,
                    R.string.street_view_panorama_events_demo_description,
                    StreetViewPanoramaEventsDemoActivity.class),
            new DemoDetails(R.string.street_view_panorama_navigation_demo_label,
                    R.string.street_view_panorama_navigation_demo_description,
                    StreetViewPanoramaNavigationDemoActivity.class),
            new DemoDetails(R.string.street_view_panorama_options_demo_label,
                    R.string.street_view_panorama_options_demo_description,
                    StreetViewPanoramaOptionsDemoActivity.class),
            new DemoDetails(R.string.street_view_panorama_view_demo_label,
                    R.string.street_view_panorama_view_demo_description,
                    StreetViewPanoramaViewDemoActivity.class),
            new DemoDetails(R.string.styled_map_demo_label,
                    R.string.styled_map_demo_description,
                    StyledMapDemoActivity.class),
            new DemoDetails(R.string.tile_coordinate_demo_label,
                    R.string.tile_coordinate_demo_description,
                    TileCoordinateDemoActivity.class),
            new DemoDetails(R.string.tile_overlay_demo_label,
                    R.string.tile_overlay_demo_description,
                    TileOverlayDemoActivity.class),
            new DemoDetails(R.string.ui_settings_demo_label,
                    R.string.ui_settings_demo_description,
                    UiSettingsDemoActivity.class),
            new DemoDetails(R.string.visible_region_demo_label,
                    R.string.visible_region_demo_description,
                    VisibleRegionDemoActivity.class),
    };
}


接下來看最簡單的BasicMapDemo

其實重點就是


public class BasicMapDemoActivity extends AppCompatActivity implements OnMapReadyCallback {

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

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

    /**     * This is where we can add markers or lines, add listeners or move the camera. In this case,     * we     * just add a marker near Africa.     */    @Override    public void onMapReady(GoogleMap map) {
        map.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
    }
}


先看 basic_demo.xml   

裡面就是一個 fragment..   class 為  com.google.android.gms.maps.SupportMapFragment

<fragment xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/map"    android:layout_width="match_parent"    android:layout_height="match_parent"    class="com.google.android.gms.maps.SupportMapFragment" />


然後繼承了 OnMapReadyCallback   interface....

實作   onMapReady


新增一個  (0,0) 的經緯度的 Marker ....

 @Override    public void onMapReady(GoogleMap map) {
        map.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
    }



接下來看 Camera Demo 的範例


public class CameraDemoActivity extends AppCompatActivity implements        OnCameraMoveStartedListener,
        OnCameraMoveListener,
        OnCameraMoveCanceledListener,
        OnCameraIdleListener,
        OnMapReadyCallback {


}


首先先看  CameraDemoActivity..   他繼承了很多  interface...


@Overridepublic void onMapReady(GoogleMap map) {
    mMap = map;

    mMap.setOnCameraIdleListener(this);
    mMap.setOnCameraMoveStartedListener(this);
    mMap.setOnCameraMoveListener(this);
    mMap.setOnCameraMoveCanceledListener(this);

    // We will provide our own zoom controls.    mMap.getUiSettings().setZoomControlsEnabled(false);
    mMap.getUiSettings().setMyLocationButtonEnabled(true);

    // Show Sydney    mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(-33.87365, 151.20689), 10));
}


先來看 onCreate()

@Overrideprotected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.camera_demo);

    mAnimateToggle = (CompoundButton) findViewById(R.id.animate);
    mCustomDurationToggle = (CompoundButton) findViewById(R.id.duration_toggle);
    mCustomDurationBar = (SeekBar) findViewById(R.id.duration_bar);

    updateEnabledState();

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

再來看layout....   camera_demo.xml





<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"> //   水平排列

        <LinearLayout            android:layout_width="wrap_content"            android:layout_height="match_parent"            android:orientation="vertical">

            <Button                android:id="@+id/stop_animation"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:onClick="onStopAnimation"                android:text="@string/stop_animation" />

            <ToggleButton                android:id="@+id/animate"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:checked="true"                android:onClick="onToggleAnimate"                android:textOn="@string/animate"                android:textOff="@string/animate" />
        </LinearLayout>

        <RelativeLayout            android:layout_width="0dp"            android:layout_height="match_parent"            android:gravity="center_horizontal"            android:layout_weight="1">

            <Button                android:id="@+id/scroll_left"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:minWidth="48dp"                android:onClick="onScrollLeft"                android:layout_alignParentLeft="true"                android:layout_centerVertical="true"                android:text="@string/left_arrow" />

            <Button                android:id="@+id/scroll_up"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:minWidth="48dp"                android:onClick="onScrollUp"                android:layout_alignParentTop="true"                android:layout_toRightOf="@id/scroll_left"                android:text="@string/up_arrow" />

            <Button                android:id="@+id/scroll_down"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:minWidth="48dp"                android:onClick="onScrollDown"                android:layout_below="@id/scroll_up"                android:layout_toRightOf="@id/scroll_left"                android:text="@string/down_arrow" />

            <Button                android:id="@+id/scroll_right"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:minWidth="48dp"                android:onClick="onScrollRight"                android:layout_centerVertical="true"                android:layout_toRightOf="@id/scroll_down"                android:text="@string/right_arrow" />
        </RelativeLayout>

        <LinearLayout            android:layout_width="wrap_content"            android:layout_height="match_parent"            android:layout_gravity="right"            android:orientation="vertical">

            <Button                android:id="@+id/zoom_in"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:minWidth="48dp"                android:onClick="onZoomIn"                android:text="@string/zoom_in" />

            <Button                android:id="@+id/zoom_out"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:minWidth="48dp"                android:onClick="onZoomOut"                android:text="@string/zoom_out" />
        </LinearLayout>

        <LinearLayout            android:orientation="vertical"            android:layout_width="wrap_content"            android:layout_height="fill_parent"            android:layout_gravity="right">

            <Button                android:id="@+id/tilt_more"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:minWidth="48dp"                android:text="@string/tilt_more"                android:onClick="onTiltMore" />

            <Button                android:id="@+id/tilt_less"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:minWidth="48dp"                android:text="@string/tilt_less"                android:onClick="onTiltLess" />
        </LinearLayout>
    </LinearLayout>

    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content">

        <CheckBox            android:id="@+id/duration_toggle"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:onClick="onToggleCustomDuration"            android:text="@string/duration" />

        <SeekBar            android:id="@+id/duration_bar"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_weight="1"            android:max="5000" />
    </LinearLayout>

    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content">

        <Button            android:id="@+id/sydney"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:onClick="onGoToSydney"            android:layout_weight="0.5"            android:text="@string/go_to_sydney" />

        <Button            android:id="@+id/bondi"            android:layout_width="0dp"            android:layout_height="wrap_content"            android:onClick="onGoToBondi"            android:layout_weight="0.5"            android:text="@string/go_to_bondi" />
    </LinearLayout>

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



重點已經用紅色的字標起來了


先來看 onGoToBondi

/** * Called when the Go To Bondi button is clicked. */public void onGoToBondi(View view) {
    if (!checkReady()) {
        return;
    }

    changeCamera(CameraUpdateFactory.newCameraPosition(BONDI));
}

其實就是把鏡頭移到 BONDI  這個 position...

BONDI \和   SYDNEY 這兩個  CameraPosition  的定義如下:




public static final CameraPosition BONDI =
        new CameraPosition.Builder().target(new LatLng(-33.891614, 151.276417))
                .zoom(15.5f)
                .bearing(300)
                .tilt(50)
                .build();

public static final CameraPosition SYDNEY =
        new CameraPosition.Builder().target(new LatLng(-33.87365, 151.20689))
                .zoom(15.5f)
                .bearing(0)
                .tilt(25)
                .build();


接下來看 onGoToSydney()

把作標點改成  SYDNEY.   然後加入新的   CancelableCallback   interface

/** * Called when the Animate To Sydney button is clicked. */public void onGoToSydney(View view) {
    if (!checkReady()) {
        return;
    }

    changeCamera(CameraUpdateFactory.newCameraPosition(SYDNEY), new CancelableCallback() {
        @Override        public void onFinish() {
            Toast.makeText(getBaseContext(), "Animation to Sydney complete", Toast.LENGTH_SHORT)
                    .show();
        }

        @Override        public void onCancel() {
            Toast.makeText(getBaseContext(), "Animation to Sydney canceled", Toast.LENGTH_SHORT)
                    .show();
        }
    });
}


接下來看 上下左右四個function

onScrollLeft ()  , onScrollDown(), onScrollUp(),  onScrollRight()



public void onScrollLeft(View view) {
    if (!checkReady()) {
        return;
    }

    changeCamera(CameraUpdateFactory.scrollBy(-SCROLL_BY_PX, 0));
}

public void onScrollRight(View view) {
    if (!checkReady()) {
        return;
    }

    changeCamera(CameraUpdateFactory.scrollBy(SCROLL_BY_PX, 0));
}

public void onScrollUp(View view) {
    if (!checkReady()) {
        return;
    }

    changeCamera(CameraUpdateFactory.scrollBy(0, -SCROLL_BY_PX));
}

/** * Called when the down arrow button is clicked. This causes the camera to move down. */public void onScrollDown(View view) {
    if (!checkReady()) {
        return;
    }

    changeCamera(CameraUpdateFactory.scrollBy(0, SCROLL_BY_PX));
}


private static final int SCROLL_BY_PX = 100;


changeCamera() 的實作如下:

private void changeCamera(CameraUpdate update) {
    changeCamera(update, null);
}


private void changeCamera(CameraUpdate update, CancelableCallback callback) {
    if (mAnimateToggle.isChecked()) {  // 看有沒有打開   animate 的 option
        if (mCustomDurationToggle.isChecked()) {
            int duration = mCustomDurationBar.getProgress();
            // The duration must be strictly positive so we make it at least 1.            mMap.animateCamera(update, Math.max(duration, 1), callback);
        } else {
            mMap.animateCamera(update, callback);
        }
    } else {
        mMap.moveCamera(update);
    }
}


 
接下來再來看  onZoomIn() 和  onZoomOut()


public void onZoomIn(View view) {
    if (!checkReady()) {
        return;
    }

    changeCamera(CameraUpdateFactory.zoomIn());
}

/** * Called when the zoom out button (the one with the -) is clicked. */public void onZoomOut(View view) {
    if (!checkReady()) {
        return;
    }

    changeCamera(CameraUpdateFactory.zoomOut());
}


接下來看    onTiltMore()  和  onTiltLess()




/** * Called when the tilt more button (the one with the /) is clicked. */public void onTiltMore(View view) {
    if (!checkReady()) {
        return;
    }

    CameraPosition currentCameraPosition = mMap.getCameraPosition();
    float currentTilt = currentCameraPosition.tilt;
    float newTilt = currentTilt + 10;

    newTilt = (newTilt > 90) ? 90 : newTilt;

    CameraPosition cameraPosition = new CameraPosition.Builder(currentCameraPosition)
            .tilt(newTilt).build();

    changeCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}

/** * Called when the tilt less button (the one with the \) is clicked. */public void onTiltLess(View view) {
    if (!checkReady()) {
        return;
    }

    CameraPosition currentCameraPosition = mMap.getCameraPosition();

    float currentTilt = currentCameraPosition.tilt;

    float newTilt = currentTilt - 10;
    newTilt = (newTilt > 0) ? newTilt : 0;

    CameraPosition cameraPosition = new CameraPosition.Builder(currentCameraPosition)
            .tilt(newTilt).build();

    changeCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}


首先呼叫 mMap.getCameraPosition()  來得到   currentCameraPosition  (類別型態為 CameraPosition )   

然後抓出     currentCameraPosition.currentTilt

然後去改變他
 float newTilt = currentTilt - 10;
    newTilt = (newTilt > 0) ? newTilt : 0;

然後重新去新建一個  CameraPosition....在呼叫  changeCamera()


 CameraPosition cameraPosition = new CameraPosition.Builder(currentCameraPosition)
            .tilt(newTilt).build();

 changeCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));




接下來看跟 animate 有關的

             "onStopAnimation"             "onToggleAnimate"



/** * Called when the animate button is toggled */public void onToggleAnimate(View view) {
    updateEnabledState();
}

/** * Update the enabled state of the custom duration controls. */private void updateEnabledState() {
    mCustomDurationToggle.setEnabled(mAnimateToggle.isChecked());
    mCustomDurationBar            .setEnabled(mAnimateToggle.isChecked() && mCustomDurationToggle.isChecked());
}

/** * Called when the stop button is clicked. */public void onStopAnimation(View view) {
    if (!checkReady()) {
        return;
    }

    mMap.stopAnimation(); //  直接呼叫  stopAnimation()
}










沒有留言:

張貼留言