Map context menu for sample in progress
7
OsmAndCore-sample/res/anim/slide_in_bottom.xml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<translate android:fromYDelta="100%p" android:toYDelta="0"
|
||||
android:duration="@android:integer/config_mediumAnimTime"/>
|
||||
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
|
||||
android:duration="@android:integer/config_mediumAnimTime" />
|
||||
</set>
|
7
OsmAndCore-sample/res/anim/slide_in_left.xml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<translate android:fromXDelta="-100%p" android:toXDelta="0"
|
||||
android:duration="@android:integer/config_mediumAnimTime"/>
|
||||
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
|
||||
android:duration="@android:integer/config_mediumAnimTime" />
|
||||
</set>
|
7
OsmAndCore-sample/res/anim/slide_out_bottom.xml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<translate android:fromYDelta="0" android:toYDelta="100%p"
|
||||
android:duration="@android:integer/config_mediumAnimTime"/>
|
||||
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
|
||||
android:duration="@android:integer/config_mediumAnimTime" />
|
||||
</set>
|
7
OsmAndCore-sample/res/anim/slide_out_left.xml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<translate android:fromXDelta="0" android:toXDelta="-100%p"
|
||||
android:duration="@android:integer/config_mediumAnimTime"/>
|
||||
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
|
||||
android:duration="@android:integer/config_mediumAnimTime" />
|
||||
</set>
|
After Width: | Height: | Size: 2 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.1 KiB |
11
OsmAndCore-sample/res/drawable/bg_bottom_menu_light.xml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<nine-patch android:src="@drawable/bg_contextmenu_shadow_top_light" />
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<solid android:color="@color/bg_color_light" />
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
12
OsmAndCore-sample/res/drawable/bg_left_menu_light.xml
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<nine-patch android:src="@drawable/bg_contextmenu_shadow_right_light" />
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<solid
|
||||
android:color="@color/bg_color_light" />
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
12
OsmAndCore-sample/res/drawable/bg_map_context_menu_light.xml
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<nine-patch android:src="@drawable/bg_contextmenu_dots_light" />
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<solid
|
||||
android:color="@color/bg_color_light" />
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
5
OsmAndCore-sample/res/drawable/blue_button_drawable.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/blue_button_drawable_pressed" android:state_pressed="true"/>
|
||||
<item android:drawable="@drawable/blue_button_drawable_idle"/>
|
||||
</selector>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<corners android:radius="4dp" />
|
||||
<solid android:color="@color/map_widget_blue"/>
|
||||
</shape>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<corners android:radius="4dp" />
|
||||
<solid android:color="@color/map_widget_blue_pressed"/>
|
||||
</shape>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@color/list_item_light_pressed" android:state_focused="true"/>
|
||||
<item android:drawable="@color/list_item_light_pressed" android:state_selected="true"/>
|
||||
<item android:drawable="@color/list_item_light_pressed" android:state_pressed="true"/>
|
||||
</selector>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@color/list_item_light_pressed" android:state_selected="true"/>
|
||||
<item android:drawable="@color/list_item_light_pressed" android:state_pressed="true"/>
|
||||
<item android:drawable="@color/list_item_light_pressed" android:state_focused="true"/>
|
||||
<item android:drawable="@color/list_item_light"/>
|
||||
|
||||
</selector>
|
22
OsmAndCore-sample/res/drawable/fab_background_normal.xml
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
|
||||
<item>
|
||||
<bitmap
|
||||
android:gravity="fill"
|
||||
android:src="@drawable/map_bt_round_1_shadow" />
|
||||
</item>
|
||||
<item>
|
||||
|
||||
<inset
|
||||
android:insetBottom="@dimen/map_button_inset_shadow"
|
||||
android:insetLeft="@dimen/map_button_inset_shadow"
|
||||
android:insetRight="@dimen/map_button_inset_shadow"
|
||||
android:insetTop="@dimen/map_button_inset_shadow" >
|
||||
<shape android:shape="oval" >
|
||||
<solid android:color="@color/map_widget_blue" />
|
||||
</shape>
|
||||
</inset>
|
||||
</item>
|
||||
|
||||
</layer-list>
|
21
OsmAndCore-sample/res/drawable/fab_background_pressed.xml
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
|
||||
<item>
|
||||
<bitmap
|
||||
android:gravity="fill"
|
||||
android:src="@drawable/map_bt_round_1_shadow" />
|
||||
</item>
|
||||
<item>
|
||||
|
||||
<inset
|
||||
android:insetBottom="@dimen/map_button_inset_shadow"
|
||||
android:insetLeft="@dimen/map_button_inset_shadow"
|
||||
android:insetRight="@dimen/map_button_inset_shadow"
|
||||
android:insetTop="@dimen/map_button_inset_shadow" >
|
||||
<shape android:shape="oval" >
|
||||
<solid android:color="@color/map_widget_blue_pressed" />
|
||||
</shape>
|
||||
</inset>
|
||||
</item>
|
||||
</layer-list>
|
5
OsmAndCore-sample/res/drawable/fab_background_style.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/fab_background_pressed" android:state_pressed="true"/>
|
||||
<item android:drawable="@drawable/fab_background_normal"></item>
|
||||
</selector>
|
|
@ -96,13 +96,10 @@
|
|||
|
||||
</FrameLayout>
|
||||
|
||||
<ListView
|
||||
android:id="@android:id/list"
|
||||
<FrameLayout
|
||||
android:id="@+id/fragmentContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/listBackgroundColor"
|
||||
android:drawSelectorOnTop="true"
|
||||
android:visibility="gone"/>
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
|
|
257
OsmAndCore-sample/res/layout/map_context_menu_fragment.xml
Normal file
|
@ -0,0 +1,257 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
android:id="@+id/context_menu_layout"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/transparent">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/context_menu_main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/context_menu_top_shadow"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/context_menu_top_shadow_h"
|
||||
android:orientation="horizontal">
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/context_menu_top_shadow_all"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="true"
|
||||
android:background="?attr/bg_map_context_menu"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/context_menu_top_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/context_menu_first_line_bottom_margin"
|
||||
android:baselineAligned="false"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/context_menu_icon_layout"
|
||||
android:layout_width="52dp"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/context_menu_icon_view"
|
||||
android:layout_width="@dimen/map_widget_icon"
|
||||
android:layout_height="@dimen/map_widget_icon"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="@dimen/context_menu_icon_top_padding"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/context_menu_first_line_top_margin"
|
||||
android:layout_weight="1">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/context_menu_line1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/TextAppearance.ContextMenuTitle"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/context_menu_close_btn_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:minWidth="@dimen/context_menu_top_right_button_min_width"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/title_button_top_right"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:gravity="center"
|
||||
android:paddingLeft="@dimen/context_menu_button_padding_x"
|
||||
android:paddingRight="@dimen/context_menu_button_padding_x"
|
||||
android:textColor="?attr/contextMenuButtonColor"
|
||||
android:textSize="@dimen/default_desc_text_size"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginTop="@dimen/context_menu_second_line_top_margin"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/context_menu_line2_layout"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/context_menu_line2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
style="@style/TextAppearance.ContextMenuSubtitle"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/compass_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:minWidth="@dimen/context_menu_top_right_button_min_width"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/direction"
|
||||
android:layout_width="@dimen/directionIconSize"
|
||||
android:layout_height="@dimen/directionIconSize"
|
||||
android:layout_marginTop="1sp"
|
||||
android:layout_gravity="center_vertical"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/distance"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="2dp"
|
||||
android:layout_marginRight="4dp"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_desc_text_size"
|
||||
tools:text="100500 km"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/title_button_container"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="@dimen/context_menu_action_buttons_h"
|
||||
android:layout_marginTop="@dimen/context_menu_buttons_top_margin"
|
||||
android:clickable="true"
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="@dimen/context_menu_buttons_padding_bottom"
|
||||
android:paddingLeft="62dp"
|
||||
android:paddingRight="2dp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<Button
|
||||
android:id="@+id/title_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:gravity="left|center_vertical"
|
||||
android:paddingLeft="@dimen/context_menu_button_padding_x"
|
||||
android:paddingRight="@dimen/context_menu_button_padding_x"
|
||||
android:textColor="?attr/contextMenuButtonColor"
|
||||
android:textSize="@dimen/default_desc_text_size"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title_button_right_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="-4dp"
|
||||
android:clickable="true"
|
||||
android:gravity="center_vertical"
|
||||
tools:text="— 00:26"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_desc_text_size"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/title_button_right"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:gravity="center"
|
||||
android:paddingLeft="@dimen/context_menu_button_padding_x"
|
||||
android:paddingRight="@dimen/context_menu_button_padding_x"
|
||||
android:textColor="?attr/contextMenuButtonColor"
|
||||
android:textSize="@dimen/default_desc_text_size"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:foreground="@drawable/bg_contextmenu_shadow"
|
||||
android:foregroundGravity="top|fill_horizontal">
|
||||
|
||||
<ScrollView
|
||||
android:id="@+id/context_menu_bottom_scroll"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?attr/ctx_menu_info_view_bg">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/context_menu_bottom_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/ctx_menu_info_view_bg"
|
||||
android:orientation="vertical">
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/context_menu_fab_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/context_menu_fab_view"
|
||||
android:layout_width="@dimen/fab_size_with_shadow"
|
||||
android:layout_height="@dimen/fab_size_with_shadow"
|
||||
android:layout_gravity="right"
|
||||
android:layout_marginRight="@dimen/fab_margin_right"
|
||||
android:background="@drawable/fab_background_style"
|
||||
android:scaleType="center"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</FrameLayout>
|
76
OsmAndCore-sample/res/layout/menu_obj_list_item.xml
Normal file
|
@ -0,0 +1,76 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/expandable_list_item_background"
|
||||
android:minHeight="@dimen/list_item_height"
|
||||
android:orientation="horizontal"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/context_menu_icon_layout"
|
||||
android:layout_width="42dp"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/context_menu_icon_view"
|
||||
android:layout_width="@dimen/standard_icon_size"
|
||||
android:layout_height="@dimen/standard_icon_size"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="17dp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginTop="14dp"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/context_menu_line1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="12dp"
|
||||
android:layout_marginRight="12dp"
|
||||
android:maxLines="3"
|
||||
android:ellipsize="end"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/default_list_text_size_large"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/context_menu_line2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="12dp"
|
||||
android:layout_marginRight="12dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/default_desc_text_size"/>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/context_menu_close_btn_layout"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/close_btn_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top"
|
||||
android:layout_marginTop="12dp"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/ic_action_remove_dark"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
20
OsmAndCore-sample/res/layout/menu_obj_selection_fragment.xml
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
android:id="@+id/main_view"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:background="?attr/bottom_menu_view_bg"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ListView
|
||||
android:id="@+id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:divider="@null"
|
||||
android:dividerHeight="0dp">
|
||||
|
||||
</ListView>
|
||||
|
||||
</LinearLayout>
|
|
@ -1,7 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<declare-styleable name="AppTheme">
|
||||
<!-- list colors -->
|
||||
<attr name="bg_map_context_menu" format="reference" />
|
||||
<attr name="dashboard_button" format="reference" />
|
||||
<attr name="left_menu_view_bg" format="reference" />
|
||||
<attr name="bottom_menu_view_bg" format="reference" />
|
||||
|
||||
<attr name="dashboard_divider" format="reference" />
|
||||
<attr name="ctx_menu_info_divider" format="color"/>
|
||||
<attr name="searchbar_text" format="color"/>
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
<item name="android:windowBackground">@color/windowBackgroundColor</item>
|
||||
<item name="android:colorBackground">@color/windowBackgroundColor</item>
|
||||
|
||||
<item name="bg_map_context_menu">@drawable/bg_map_context_menu_light</item>
|
||||
<item name="dashboard_button">@drawable/dashboard_button_light</item>
|
||||
<item name="left_menu_view_bg">@drawable/bg_left_menu_light</item>
|
||||
<item name="bottom_menu_view_bg">@drawable/bg_bottom_menu_light</item>
|
||||
<item name="toolbar_theme">@style/AppTheme.Toolbar</item>
|
||||
<item name="bg_color">@color/bg_color_light</item>
|
||||
<item name="ctx_menu_info_divider">@color/ctx_menu_info_divider_light</item>
|
||||
|
@ -59,4 +63,16 @@
|
|||
<style name="OsmandListView" parent="@android:style/Widget.ListView">
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.ContextMenuTitle" parent="TextAppearance.AppCompat">
|
||||
<item name="android:textColor">?android:textColorPrimary</item>
|
||||
<item name="android:textSize">@dimen/default_list_text_size_large</item>
|
||||
<item name="android:maxLines">6</item>
|
||||
<item name="android:ellipsize">end</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.ContextMenuSubtitle" parent="TextAppearance.AppCompat.Subhead">
|
||||
<item name="android:textColor">?android:textColorSecondary</item>
|
||||
<item name="android:textSize">@dimen/default_desc_text_size</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -0,0 +1,290 @@
|
|||
package net.osmand.core.samples.android.sample1;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
|
||||
import net.osmand.Location;
|
||||
import net.osmand.ResultMatcher;
|
||||
import net.osmand.binary.GeocodingUtilities.GeocodingResult;
|
||||
import net.osmand.binary.RouteDataObject;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
public class GeocodingLookupService {
|
||||
|
||||
private SampleApplication app;
|
||||
private ConcurrentLinkedQueue<LatLon> lookupLocations = new ConcurrentLinkedQueue<>();
|
||||
private ConcurrentHashMap<LatLon, List<AddressLookupRequest>> addressLookupRequestsMap = new ConcurrentHashMap<>();
|
||||
private LatLon currentRequestedLocation = null;
|
||||
|
||||
private boolean searchDone;
|
||||
private String lastFoundAddress;
|
||||
|
||||
public interface OnAddressLookupProgress {
|
||||
void geocodingInProgress();
|
||||
}
|
||||
|
||||
public interface OnAddressLookupResult {
|
||||
void geocodingDone(String address);
|
||||
}
|
||||
|
||||
public static class AddressLookupRequest {
|
||||
|
||||
private LatLon latLon;
|
||||
private OnAddressLookupResult uiResultCallback;
|
||||
private OnAddressLookupProgress uiProgressCallback;
|
||||
|
||||
public AddressLookupRequest(LatLon latLon, OnAddressLookupResult uiResultCallback,
|
||||
OnAddressLookupProgress uiProgressCallback) {
|
||||
this.latLon = latLon;
|
||||
this.uiResultCallback = uiResultCallback;
|
||||
this.uiProgressCallback = uiProgressCallback;
|
||||
}
|
||||
|
||||
public LatLon getLatLon() {
|
||||
return latLon;
|
||||
}
|
||||
}
|
||||
|
||||
public GeocodingLookupService(SampleApplication app) {
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
public void lookupAddress(AddressLookupRequest request) {
|
||||
synchronized (this) {
|
||||
LatLon requestedLocation = request.latLon;
|
||||
LatLon existingLocation = null;
|
||||
if (requestedLocation.equals(currentRequestedLocation)) {
|
||||
existingLocation = currentRequestedLocation;
|
||||
requestedLocation = existingLocation;
|
||||
request.latLon = existingLocation;
|
||||
} else if (lookupLocations.contains(requestedLocation)) {
|
||||
for (LatLon latLon : lookupLocations) {
|
||||
if (latLon.equals(requestedLocation)) {
|
||||
existingLocation = latLon;
|
||||
requestedLocation = latLon;
|
||||
request.latLon = latLon;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
List<AddressLookupRequest> list = addressLookupRequestsMap.get(requestedLocation);
|
||||
if (list == null) {
|
||||
list = new ArrayList<>();
|
||||
addressLookupRequestsMap.put(requestedLocation, list);
|
||||
}
|
||||
list.add(request);
|
||||
if (existingLocation == null) {
|
||||
lookupLocations.add(requestedLocation);
|
||||
}
|
||||
|
||||
if (currentRequestedLocation == null && !lookupLocations.isEmpty()) {
|
||||
currentRequestedLocation = lookupLocations.peek();
|
||||
execute(new AddressLookupRequestsAsyncTask(app));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void cancel(AddressLookupRequest request) {
|
||||
synchronized (this) {
|
||||
List<AddressLookupRequest> requests = addressLookupRequestsMap.get(request.latLon);
|
||||
if (requests != null && requests.size() > 0) {
|
||||
requests.remove(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void cancel(LatLon latLon) {
|
||||
synchronized (this) {
|
||||
List<AddressLookupRequest> requests = addressLookupRequestsMap.get(latLon);
|
||||
if (requests != null && requests.size() > 0) {
|
||||
requests.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasAnyRequest(LatLon latLon) {
|
||||
synchronized (this) {
|
||||
List<AddressLookupRequest> requests = addressLookupRequestsMap.get(latLon);
|
||||
return requests != null && requests.size() > 0;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <P> void execute(AsyncTask<P, ?, ?> task, P... requests) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, requests);
|
||||
} else {
|
||||
task.execute(requests);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean geocode(final LatLon latLon) {
|
||||
Location loc = new Location("");
|
||||
loc.setLatitude(latLon.getLatitude());
|
||||
loc.setLongitude(latLon.getLongitude());
|
||||
return app.getLocationProvider()
|
||||
.getGeocodingResult(loc, new ResultMatcher<GeocodingResult>() {
|
||||
|
||||
@Override
|
||||
public boolean publish(GeocodingResult object) {
|
||||
String result = null;
|
||||
if (object != null) {
|
||||
String lang = SampleApplication.LANGUAGE;
|
||||
boolean transliterate = SampleApplication.TRANSLITERATE;
|
||||
|
||||
String geocodingResult = "";
|
||||
double relevantDistance = -1;
|
||||
|
||||
if (object.building != null) {
|
||||
String bldName = object.building.getName(lang, transliterate);
|
||||
if (!Algorithms.isEmpty(object.buildingInterpolation)) {
|
||||
bldName = object.buildingInterpolation;
|
||||
}
|
||||
geocodingResult = object.street.getName(lang, transliterate) + " " + bldName + ", "
|
||||
+ object.city.getName(lang, transliterate);
|
||||
} else if (object.street != null) {
|
||||
geocodingResult = object.street.getName(lang, transliterate) + ", " + object.city.getName(lang, transliterate);
|
||||
relevantDistance = object.getDistanceP();
|
||||
} else if (object.city != null) {
|
||||
geocodingResult = object.city.getName(lang, transliterate);
|
||||
} else if (object.point != null) {
|
||||
RouteDataObject rd = object.point.getRoad();
|
||||
String sname = rd.getName(lang, transliterate);
|
||||
if (Algorithms.isEmpty(sname)) {
|
||||
sname = "";
|
||||
}
|
||||
String ref = rd.getRef(true);
|
||||
if (!Algorithms.isEmpty(ref)) {
|
||||
if (!Algorithms.isEmpty(sname)) {
|
||||
sname += ", ";
|
||||
}
|
||||
sname += ref;
|
||||
}
|
||||
geocodingResult = sname;
|
||||
relevantDistance = object.getDistanceP();
|
||||
}
|
||||
|
||||
result = geocodingResult;
|
||||
if (relevantDistance == -1) {
|
||||
relevantDistance = object.getDistance();
|
||||
}
|
||||
|
||||
if (!Algorithms.isEmpty(result) && relevantDistance > 100) {
|
||||
result = app.getString("shared_string_near") + " " + result;
|
||||
}
|
||||
}
|
||||
|
||||
lastFoundAddress = result;
|
||||
searchDone = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return !hasAnyRequest(latLon);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private class AddressLookupRequestsAsyncTask extends AsyncTask<AddressLookupRequest, AddressLookupRequest, Void> {
|
||||
|
||||
private SampleApplication app;
|
||||
|
||||
public AddressLookupRequestsAsyncTask(SampleApplication app) {
|
||||
super();
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(AddressLookupRequest... addressLookupRequests) {
|
||||
for (;;) {
|
||||
try {
|
||||
while (!lookupLocations.isEmpty()) {
|
||||
final LatLon latLon;
|
||||
synchronized (GeocodingLookupService.this) {
|
||||
latLon = lookupLocations.poll();
|
||||
currentRequestedLocation = latLon;
|
||||
List<AddressLookupRequest> requests = addressLookupRequestsMap.get(latLon);
|
||||
if (requests == null || requests.size() == 0) {
|
||||
addressLookupRequestsMap.remove(latLon);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// geocode
|
||||
searchDone = false;
|
||||
while (!geocode(latLon)) {
|
||||
try {
|
||||
Thread.sleep(50);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
long counter = 0;
|
||||
while (!searchDone) {
|
||||
try {
|
||||
Thread.sleep(50);
|
||||
counter++;
|
||||
// call progress every 500 ms
|
||||
if (counter == 10) {
|
||||
counter = 0;
|
||||
synchronized (GeocodingLookupService.this) {
|
||||
List<AddressLookupRequest> requests = addressLookupRequestsMap.get(latLon);
|
||||
for (final AddressLookupRequest request : requests) {
|
||||
if (request.uiProgressCallback != null) {
|
||||
app.runInUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
request.uiProgressCallback.geocodingInProgress();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
synchronized (GeocodingLookupService.this) {
|
||||
List<AddressLookupRequest> requests = addressLookupRequestsMap.get(latLon);
|
||||
for (final AddressLookupRequest request : requests) {
|
||||
if (request.uiResultCallback != null) {
|
||||
app.runInUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
request.uiResultCallback.geocodingDone(lastFoundAddress);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
addressLookupRequestsMap.remove(latLon);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
synchronized (GeocodingLookupService.this) {
|
||||
currentRequestedLocation = null;
|
||||
if (lookupLocations.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -101,7 +101,7 @@ public class IconsCache {
|
|||
long hash = ((long)resId << 31L) + clrId;
|
||||
Drawable d = osmandDrawable.get(hash);
|
||||
if (d == null) {
|
||||
d = OsmandResources.getDrawable(resId);
|
||||
d = OsmandResources.getDrawableNonCached(resId);
|
||||
if (d != null) {
|
||||
d = DrawableCompat.wrap(d);
|
||||
d.mutate();
|
||||
|
@ -118,7 +118,7 @@ public class IconsCache {
|
|||
long hash = ((long)resId << 31L) + color;
|
||||
Drawable d = osmandDrawable.get(hash);
|
||||
if(d == null) {
|
||||
d = OsmandResources.getDrawable(resId);
|
||||
d = OsmandResources.getDrawableNonCached(resId);
|
||||
if (d != null) {
|
||||
d = DrawableCompat.wrap(d);
|
||||
d.mutate();
|
||||
|
@ -129,6 +129,10 @@ public class IconsCache {
|
|||
return d;
|
||||
}
|
||||
|
||||
public Drawable getPaintedOsmandIcon(int resId, @ColorInt int color){
|
||||
return getPaintedOsmandDrawable(resId, color);
|
||||
}
|
||||
|
||||
public Drawable getPaintedIcon(String osmandId, @ColorInt int color){
|
||||
int id = OsmandResources.getDrawableId(osmandId);
|
||||
if (id != 0) {
|
||||
|
|
|
@ -8,6 +8,8 @@ import android.content.SharedPreferences.Editor;
|
|||
import android.content.pm.PackageManager;
|
||||
import android.graphics.PointF;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
|
@ -40,8 +42,12 @@ import net.osmand.core.jni.ResolvedMapStyle;
|
|||
import net.osmand.core.jni.RoadLocator;
|
||||
import net.osmand.core.jni.Utilities;
|
||||
import net.osmand.core.samples.android.sample1.MultiTouchSupport.MultiTouchZoomListener;
|
||||
import net.osmand.core.samples.android.sample1.data.PointDescription;
|
||||
import net.osmand.core.samples.android.sample1.mapcontextmenu.MapContextMenu;
|
||||
import net.osmand.core.samples.android.sample1.mapcontextmenu.MapMultiSelectionMenu;
|
||||
import net.osmand.core.samples.android.sample1.search.QuickSearchDialogFragment;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.RotatedTileBox;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -77,6 +83,9 @@ public class MainActivity extends AppCompatActivity {
|
|||
private float elevationAngle;
|
||||
private MultiTouchSupport multiTouchSupport;
|
||||
|
||||
private MapContextMenu menu;
|
||||
private MapMultiSelectionMenu multiMenu;
|
||||
|
||||
private boolean noMapsFound;
|
||||
|
||||
// Germany
|
||||
|
@ -224,6 +233,11 @@ public class MainActivity extends AppCompatActivity {
|
|||
|
||||
app.getIconsCache().setDisplayDensityFactor(displayDensityFactor);
|
||||
|
||||
menu = new MapContextMenu();
|
||||
menu.setMainActivity(this);
|
||||
|
||||
multiMenu = new MapMultiSelectionMenu(this);
|
||||
|
||||
if (!InstallOsmandAppDialog.showIfNeeded(getSupportFragmentManager(), this)
|
||||
&& externalStoragePermissionGranted) {
|
||||
checkMapsInstalled();
|
||||
|
@ -280,6 +294,10 @@ public class MainActivity extends AppCompatActivity {
|
|||
return (SampleApplication) getApplication();
|
||||
}
|
||||
|
||||
public AtlasMapRendererView getMapView() {
|
||||
return mapView;
|
||||
}
|
||||
|
||||
public void showOnMap(LatLon latLon, int zoom) {
|
||||
if (latLon != null) {
|
||||
PointI target = Utilities.convertLatLonTo31(
|
||||
|
@ -289,6 +307,38 @@ public class MainActivity extends AppCompatActivity {
|
|||
}
|
||||
}
|
||||
|
||||
public void refreshMap() {
|
||||
//todo
|
||||
}
|
||||
|
||||
public MapContextMenu getContextMenu() {
|
||||
return menu;
|
||||
}
|
||||
|
||||
public boolean showContextMenu(@NonNull LatLon latLon,
|
||||
@Nullable PointDescription pointDescription,
|
||||
@Nullable Object object) {
|
||||
if (multiMenu.isVisible()) {
|
||||
multiMenu.hide();
|
||||
}
|
||||
if (!getBox().containsLatLon(latLon)) {
|
||||
menu.setMapCenter(latLon);
|
||||
menu.setCenterMarker(true);
|
||||
}
|
||||
menu.show(latLon, pointDescription, object);
|
||||
return true;
|
||||
}
|
||||
|
||||
public RotatedTileBox getBox() {
|
||||
RotatedTileBox.RotatedTileBoxBuilder boxBuilder = new RotatedTileBox.RotatedTileBoxBuilder();
|
||||
LatLon screenCenter = getScreenCenter();
|
||||
boxBuilder.setLocation(screenCenter.getLatitude(), screenCenter.getLongitude());
|
||||
boxBuilder.setPixelDimensions(mapView.getWidth(), mapView.getHeight(), 0.5f, 0.5f);
|
||||
boxBuilder.setZoom((int)getZoom());
|
||||
boxBuilder.setRotate(mapView.getRotation());
|
||||
return boxBuilder.build();
|
||||
}
|
||||
|
||||
public PointI getScreenCenter31() {
|
||||
PointI point = new PointI();
|
||||
mapView.getLocationFromScreenPoint(new PointI(mapView.getWidth() / 2, mapView.getHeight() / 2), point);
|
||||
|
@ -302,6 +352,10 @@ public class MainActivity extends AppCompatActivity {
|
|||
return new LatLon(jniLatLon.getLatitude(), jniLatLon.getLongitude());
|
||||
}
|
||||
|
||||
public float getZoom() {
|
||||
return zoom;
|
||||
}
|
||||
|
||||
public void saveMapState() {
|
||||
SharedPreferences prefs = getPreferences(MODE_PRIVATE);
|
||||
Editor edit = prefs.edit();
|
||||
|
|
|
@ -4,11 +4,23 @@ import android.content.Context;
|
|||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.v4.graphics.drawable.DrawableCompat;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import gnu.trove.map.hash.TLongObjectHashMap;
|
||||
|
||||
public class OsmandResources {
|
||||
|
||||
public static final String BIG_ICON_PREFIX = "mx_";
|
||||
|
||||
private static Resources osmandResources;
|
||||
private static String packageName;
|
||||
private static Map<String, Integer> stringIds = new HashMap<>();
|
||||
private static Map<String, Integer> drawableIds = new HashMap<>();
|
||||
private static TLongObjectHashMap<Drawable> drawable = new TLongObjectHashMap<>();
|
||||
private static TLongObjectHashMap<String> string = new TLongObjectHashMap<>();
|
||||
|
||||
public static void init(Context ctx) {
|
||||
String packageName = "net.osmand";
|
||||
|
@ -43,40 +55,104 @@ public class OsmandResources {
|
|||
}
|
||||
|
||||
public static String getString(String id) {
|
||||
if (osmandResources != null) {
|
||||
int resolvedId = osmandResources.getIdentifier(id, "string", packageName);
|
||||
return osmandResources.getString(resolvedId);
|
||||
}
|
||||
return null;
|
||||
return getStringInternal(resolveStringId(id));
|
||||
}
|
||||
|
||||
public static String getString(String id, Object... formatArgs) {
|
||||
if (osmandResources != null) {
|
||||
int resolvedId = osmandResources.getIdentifier(id, "string", packageName);
|
||||
int resolvedId = resolveStringId(id);
|
||||
if (resolvedId != 0) {
|
||||
return osmandResources.getString(resolvedId, formatArgs);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Drawable getDrawable(String id) {
|
||||
if (osmandResources != null) {
|
||||
int resolvedId = osmandResources.getIdentifier(id, "drawable", packageName);
|
||||
return osmandResources.getDrawable(resolvedId);
|
||||
}
|
||||
return null;
|
||||
return getDrawableInternal(resolveDrawableId(id));
|
||||
}
|
||||
|
||||
public static Drawable getBigDrawable(String id) {
|
||||
return getDrawableInternal(resolveDrawableId(BIG_ICON_PREFIX + id));
|
||||
}
|
||||
|
||||
public static Drawable getDrawable(int id) {
|
||||
if (osmandResources != null) {
|
||||
return osmandResources.getDrawable(id);
|
||||
return getDrawableInternal(id);
|
||||
}
|
||||
|
||||
public static Drawable getDrawableNonCached(int id) {
|
||||
if (osmandResources != null && id != 0) {
|
||||
Drawable d = osmandResources.getDrawable(id);
|
||||
if (d != null) {
|
||||
d = DrawableCompat.wrap(d);
|
||||
d.mutate();
|
||||
}
|
||||
return d;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int getDrawableId(String id) {
|
||||
return resolveDrawableId(id);
|
||||
}
|
||||
|
||||
public static int getBigDrawableId(String id) {
|
||||
return resolveDrawableId(BIG_ICON_PREFIX + id);
|
||||
}
|
||||
|
||||
private static Drawable getDrawableInternal(int resId) {
|
||||
if (osmandResources != null && resId != 0) {
|
||||
long hash = getResIdHash(resId);
|
||||
Drawable d = drawable.get(hash);
|
||||
if (d == null) {
|
||||
d = osmandResources.getDrawable(resId);
|
||||
if (d != null) {
|
||||
d = DrawableCompat.wrap(d);
|
||||
d.mutate();
|
||||
drawable.put(hash, d);
|
||||
}
|
||||
}
|
||||
return d;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String getStringInternal(int resId) {
|
||||
if (osmandResources != null && resId != 0) {
|
||||
long hash = getResIdHash(resId);
|
||||
String s = string.get(hash);
|
||||
if (s == null) {
|
||||
s = osmandResources.getString(resId);
|
||||
string.put(hash, s);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static int resolveStringId(String id) {
|
||||
if (osmandResources != null) {
|
||||
return osmandResources.getIdentifier(id, "drawable", packageName);
|
||||
Integer resolvedId = stringIds.get(id);
|
||||
if (resolvedId == null) {
|
||||
resolvedId = osmandResources.getIdentifier(id, "string", packageName);
|
||||
stringIds.put(id, resolvedId);
|
||||
}
|
||||
return resolvedId;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static int resolveDrawableId(String id) {
|
||||
if (osmandResources != null) {
|
||||
Integer resolvedId = drawableIds.get(id);
|
||||
if (resolvedId == null) {
|
||||
resolvedId = osmandResources.getIdentifier(id, "drawable", packageName);
|
||||
drawableIds.put(id, resolvedId);
|
||||
}
|
||||
return resolvedId;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static long getResIdHash(int resId) {
|
||||
return ((long)resId << 31L);
|
||||
}
|
||||
}
|
|
@ -41,8 +41,10 @@ public class SampleApplication extends Application {
|
|||
|
||||
private SampleLocationProvider locationProvider;
|
||||
private QuickSearchHelper searchUICore;
|
||||
private GeocodingLookupService geocodingLookupService;
|
||||
|
||||
public static final String LANGUAGE;
|
||||
public static String LANGUAGE;
|
||||
public static boolean TRANSLITERATE = false;
|
||||
|
||||
static {
|
||||
String langCode = Locale.getDefault().getLanguage();
|
||||
|
@ -58,6 +60,7 @@ public class SampleApplication extends Application {
|
|||
OsmandResources.init(this);
|
||||
locationProvider = new SampleLocationProvider(this);
|
||||
searchUICore = new QuickSearchHelper(this);
|
||||
geocodingLookupService = new GeocodingLookupService(this);
|
||||
uiHandler = new Handler();
|
||||
|
||||
poiTypes = MapPoiTypes.getDefaultNoInit();
|
||||
|
@ -76,6 +79,10 @@ public class SampleApplication extends Application {
|
|||
iconsCache = new IconsCache(assetsCustom, this);
|
||||
}
|
||||
|
||||
public GeocodingLookupService getGeocodingLookupService() {
|
||||
return geocodingLookupService;
|
||||
}
|
||||
|
||||
public int getCoordinatesFormat() {
|
||||
return coordinatesFormat;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,10 @@ import android.support.v7.app.AlertDialog;
|
|||
import android.util.Log;
|
||||
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.ResultMatcher;
|
||||
import net.osmand.binary.GeocodingUtilities;
|
||||
import net.osmand.binary.GeocodingUtilities.GeocodingResult;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -513,16 +517,24 @@ public class SampleLocationProvider implements SensorEventListener {
|
|||
public boolean getRouteSegment(net.osmand.Location loc, ResultMatcher<RouteDataObject> result) {
|
||||
return currentPositionHelper.getRouteSegment(loc, result);
|
||||
}
|
||||
*/
|
||||
|
||||
public boolean getGeocodingResult(net.osmand.Location loc, ResultMatcher<GeocodingResult> result) {
|
||||
return currentPositionHelper.getGeocodingResult(loc, result);
|
||||
return false; //currentPositionHelper.getGeocodingResult(loc, result); todo
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
public net.osmand.Location getLastKnownLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public LatLon getLastKnownLocationLatLon() {
|
||||
if (location != null) {
|
||||
return new LatLon(location.getLatitude(), location.getLongitude());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class GPSInfo {
|
||||
public int foundSatellites = 0;
|
||||
|
|
|
@ -5,10 +5,13 @@ import android.app.AlarmManager;
|
|||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorManager;
|
||||
import android.view.WindowManager;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.Surface;
|
||||
|
||||
import net.osmand.PlatformUtil;
|
||||
|
||||
public class SampleUtils {
|
||||
|
||||
|
@ -69,6 +72,7 @@ public class SampleUtils {
|
|||
return installed;
|
||||
}
|
||||
|
||||
/*
|
||||
public static int getScreenOrientation(Activity a) {
|
||||
int screenOrientation = ((WindowManager) a.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
|
||||
switch (screenOrientation) {
|
||||
|
@ -92,4 +96,75 @@ public class SampleUtils {
|
|||
}
|
||||
return screenOrientation;
|
||||
}
|
||||
*/
|
||||
|
||||
public static int getScreenOrientation(Activity activity) {
|
||||
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
|
||||
DisplayMetrics dm = new DisplayMetrics();
|
||||
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
|
||||
int width = dm.widthPixels;
|
||||
int height = dm.heightPixels;
|
||||
int orientation;
|
||||
// if the device's natural orientation is portrait:
|
||||
if ((rotation == Surface.ROTATION_0
|
||||
|| rotation == Surface.ROTATION_180) && height > width ||
|
||||
(rotation == Surface.ROTATION_90
|
||||
|| rotation == Surface.ROTATION_270) && width > height) {
|
||||
switch(rotation) {
|
||||
case Surface.ROTATION_0:
|
||||
orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
|
||||
break;
|
||||
case Surface.ROTATION_90:
|
||||
orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
|
||||
break;
|
||||
case Surface.ROTATION_180:
|
||||
orientation =
|
||||
ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
|
||||
break;
|
||||
case Surface.ROTATION_270:
|
||||
orientation =
|
||||
ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
|
||||
break;
|
||||
default:
|
||||
Log.e(PlatformUtil.TAG, "Unknown screen orientation. Defaulting to " +
|
||||
"portrait.");
|
||||
orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// if the device's natural orientation is landscape or if the device
|
||||
// is square:
|
||||
else {
|
||||
switch(rotation) {
|
||||
case Surface.ROTATION_0:
|
||||
orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
|
||||
break;
|
||||
case Surface.ROTATION_90:
|
||||
orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
|
||||
break;
|
||||
case Surface.ROTATION_180:
|
||||
orientation =
|
||||
ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
|
||||
break;
|
||||
case Surface.ROTATION_270:
|
||||
orientation =
|
||||
ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
|
||||
break;
|
||||
default:
|
||||
Log.e(PlatformUtil.TAG, "Unknown screen orientation. Defaulting to " +
|
||||
"landscape.");
|
||||
orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return orientation;
|
||||
}
|
||||
|
||||
public static boolean isOrientationPortrait(Activity ctx) {
|
||||
int orientation = getScreenOrientation(ctx);
|
||||
return orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ||
|
||||
orientation == ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import com.jwetherell.openmap.common.LatLonPoint;
|
|||
import com.jwetherell.openmap.common.UTMPoint;
|
||||
|
||||
import net.osmand.LocationConvert;
|
||||
import net.osmand.core.samples.android.sample1.OsmandResources;
|
||||
import net.osmand.core.samples.android.sample1.SampleApplication;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
@ -354,4 +355,27 @@ public class PointDescription {
|
|||
}
|
||||
}
|
||||
|
||||
public int getIconId() {
|
||||
int iconId;
|
||||
if (isAddress()) {
|
||||
iconId = OsmandResources.getDrawableId("ic_type_address");
|
||||
} else if (isFavorite()) {
|
||||
iconId = OsmandResources.getDrawableId("ic_type_favorites");
|
||||
} else if (isLocation()) {
|
||||
iconId = OsmandResources.getDrawableId("ic_type_coordinates");
|
||||
} else if (isPoi()) {
|
||||
iconId = OsmandResources.getDrawableId("ic_type_info");
|
||||
} else if (isWpt()) {
|
||||
iconId = OsmandResources.getDrawableId("ic_type_waypoint");
|
||||
} else if (isAudioNote()) {
|
||||
iconId = OsmandResources.getDrawableId("ic_type_audio");
|
||||
} else if (isVideoNote()) {
|
||||
iconId = OsmandResources.getDrawableId("ic_type_video");
|
||||
}else if (isPhotoNote()) {
|
||||
iconId = OsmandResources.getDrawableId("ic_type_img");
|
||||
} else {
|
||||
iconId = OsmandResources.getDrawableId("ic_type_address");
|
||||
}
|
||||
return iconId;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
package net.osmand.core.samples.android.sample1.mapcontextmenu;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import net.osmand.core.samples.android.sample1.IconsCache;
|
||||
import net.osmand.core.samples.android.sample1.MainActivity;
|
||||
import net.osmand.core.samples.android.sample1.R;
|
||||
import net.osmand.core.samples.android.sample1.SampleUtils;
|
||||
|
||||
public abstract class BaseMenuController {
|
||||
|
||||
private MainActivity mainActivity;
|
||||
private boolean portraitMode;
|
||||
private boolean nightMode;
|
||||
private int landscapeWidthPx;
|
||||
|
||||
public BaseMenuController(MainActivity mainActivity) {
|
||||
this.mainActivity = mainActivity;
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
portraitMode = SampleUtils.isOrientationPortrait(mainActivity);
|
||||
landscapeWidthPx = mainActivity.getResources().getDimensionPixelSize(R.dimen.dashboard_land_width);
|
||||
updateNightMode();
|
||||
}
|
||||
|
||||
public MainActivity getMainActivity() {
|
||||
return mainActivity;
|
||||
}
|
||||
|
||||
public void setMainActivity(MainActivity mainActivity) {
|
||||
this.mainActivity = mainActivity;
|
||||
init();
|
||||
}
|
||||
|
||||
public boolean isLight() {
|
||||
return !nightMode;
|
||||
}
|
||||
|
||||
public void updateNightMode() {
|
||||
//nightMode = mainActivity.getMyApplication().getDaynightHelper().isNightModeForMapControls();
|
||||
}
|
||||
|
||||
public boolean isLandscapeLayout() {
|
||||
return !portraitMode;
|
||||
}
|
||||
|
||||
public int getLandscapeWidthPx() {
|
||||
return landscapeWidthPx;
|
||||
}
|
||||
|
||||
public float getHalfScreenMaxHeightKoef() {
|
||||
return .7f;
|
||||
}
|
||||
|
||||
public int getSlideInAnimation() {
|
||||
if (isLandscapeLayout()) {
|
||||
return R.anim.slide_in_left;
|
||||
} else {
|
||||
return R.anim.slide_in_bottom;
|
||||
}
|
||||
}
|
||||
|
||||
public int getSlideOutAnimation() {
|
||||
if (isLandscapeLayout()) {
|
||||
return R.anim.slide_out_left;
|
||||
} else {
|
||||
return R.anim.slide_out_bottom;
|
||||
}
|
||||
}
|
||||
|
||||
protected Drawable getIconOrig(int osmandIconId) {
|
||||
IconsCache iconsCache = getMainActivity().getMyApplication().getIconsCache();
|
||||
return iconsCache.getOsmandIcon(osmandIconId, 0);
|
||||
}
|
||||
|
||||
protected Drawable getIcon(int osmandIconId) {
|
||||
return getIcon(osmandIconId, isLight() ? R.color.icon_color : R.color.icon_color_light);
|
||||
}
|
||||
|
||||
protected Drawable getIcon(int osmandIconId, int colorId) {
|
||||
IconsCache iconsCache = getMainActivity().getMyApplication().getIconsCache();
|
||||
return iconsCache.getOsmandIcon(osmandIconId, colorId);
|
||||
}
|
||||
|
||||
protected Drawable getPaintedIcon(int osmandIconId, int color) {
|
||||
IconsCache iconsCache = getMainActivity().getMyApplication().getIconsCache();
|
||||
return iconsCache.getPaintedOsmandIcon(osmandIconId, color);
|
||||
}
|
||||
|
||||
protected Drawable getIcon(int osmandIconId, int colorLightId, int colorDarkId) {
|
||||
IconsCache iconsCache = getMainActivity().getMyApplication().getIconsCache();
|
||||
return iconsCache.getOsmandIcon(osmandIconId, isLight() ? colorLightId : colorDarkId);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,242 @@
|
|||
package net.osmand.core.samples.android.sample1.mapcontextmenu;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.view.MenuItemCompat;
|
||||
import android.support.v7.widget.PopupMenu;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.text.util.Linkify;
|
||||
import android.view.Gravity;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebView;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.core.samples.android.sample1.OsmandResources;
|
||||
import net.osmand.core.samples.android.sample1.R;
|
||||
import net.osmand.core.samples.android.sample1.SampleApplication;
|
||||
import net.osmand.core.samples.android.sample1.data.PointDescription;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
public class ContextMenuHelper {
|
||||
|
||||
public static void showDescriptionDialog(Context ctx, SampleApplication app, String text, String title) {
|
||||
showText(ctx, app, text, title);
|
||||
}
|
||||
|
||||
public static void showWikipediaDialog(Context ctx, SampleApplication app, Amenity a) {
|
||||
if (a.getType().isWiki()) {
|
||||
showWiki(ctx, app, a, SampleApplication.LANGUAGE);
|
||||
}
|
||||
}
|
||||
|
||||
private static void showWiki(final Context ctx, final SampleApplication app, final Amenity a, final String lang) {
|
||||
String preferredLang = lang;
|
||||
if (Algorithms.isEmpty(preferredLang)) {
|
||||
preferredLang = SampleApplication.LANGUAGE;
|
||||
}
|
||||
final Dialog dialog = new Dialog(ctx);
|
||||
final String title = Algorithms.isEmpty(lang) ? a.getName() : a.getName(lang);
|
||||
LinearLayout ll = new LinearLayout(ctx);
|
||||
ll.setOrientation(LinearLayout.VERTICAL);
|
||||
|
||||
final Toolbar topBar = new Toolbar(ctx);
|
||||
topBar.setClickable(true);
|
||||
Drawable back = app.getIconsCache().getIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
|
||||
topBar.setNavigationIcon(back);
|
||||
topBar.setNavigationContentDescription(app.getString("access_shared_string_navigate_up"));
|
||||
topBar.setTitle(title);
|
||||
topBar.setBackgroundColor(ContextCompat.getColor(ctx, R.color.osmand_orange));
|
||||
topBar.setTitleTextColor(ContextCompat.getColor(ctx, R.color.color_white));
|
||||
|
||||
String lng = a.getContentSelected("content", preferredLang, "en");
|
||||
if (Algorithms.isEmpty(lng)) {
|
||||
lng = "en";
|
||||
}
|
||||
|
||||
final String langSelected = lng;
|
||||
String content = a.getDescription(langSelected);
|
||||
final Button bottomBar = new Button(ctx);
|
||||
bottomBar.setText(app.getString("read_full_article"));
|
||||
bottomBar.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
String article = "https://" + langSelected.toLowerCase() + ".wikipedia.org/wiki/" + title.replace(' ', '_');
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
i.setData(Uri.parse(article));
|
||||
ctx.startActivity(i);
|
||||
}
|
||||
});
|
||||
MenuItem mi = topBar.getMenu().add(langSelected.toUpperCase()).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||
@Override
|
||||
public boolean onMenuItemClick(final MenuItem item) {
|
||||
showPopupLangMenu(ctx, topBar, app, a, dialog, langSelected);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
MenuItemCompat.setShowAsAction(mi, MenuItem.SHOW_AS_ACTION_ALWAYS);
|
||||
topBar.setNavigationOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(final View v) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
final WebView wv = new WebView(ctx);
|
||||
WebSettings settings = wv.getSettings();
|
||||
settings.setDefaultTextEncodingName("utf-8");
|
||||
settings.setBuiltInZoomControls(true);
|
||||
settings.setDisplayZoomControls(false);
|
||||
settings.setSupportZoom(true);
|
||||
|
||||
wv.loadDataWithBaseURL(null, content, "text/html", "UTF-8", null);
|
||||
// wv.loadUrl(OsMoService.SIGN_IN_URL + app.getSettings().OSMO_DEVICE_KEY.get());
|
||||
ScrollView scrollView = new ScrollView(ctx);
|
||||
ll.addView(topBar);
|
||||
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);
|
||||
lp.weight = 1;
|
||||
ll.addView(scrollView, lp);
|
||||
ll.addView(bottomBar, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
|
||||
scrollView.addView(wv);
|
||||
dialog.setContentView(ll);
|
||||
wv.setFocusable(true);
|
||||
wv.setFocusableInTouchMode(true);
|
||||
wv.requestFocus(View.FOCUS_DOWN);
|
||||
wv.setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
case MotionEvent.ACTION_UP:
|
||||
if (!v.hasFocus()) {
|
||||
v.requestFocus();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
dialog.setCancelable(true);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
protected static void showPopupLangMenu(final Context ctx, Toolbar tb,
|
||||
final SampleApplication app, final Amenity a,
|
||||
final Dialog dialog, final String langSelected) {
|
||||
final PopupMenu optionsMenu = new PopupMenu(ctx, tb, Gravity.RIGHT);
|
||||
Set<String> namesSet = new TreeSet<>();
|
||||
namesSet.addAll(a.getNames("content", "en"));
|
||||
namesSet.addAll(a.getNames("description", "en"));
|
||||
|
||||
Map<String, String> names = new HashMap<>();
|
||||
for (String n : namesSet) {
|
||||
names.put(n, getLangName(ctx, n));
|
||||
}
|
||||
String selectedLangName = names.get(langSelected);
|
||||
if (selectedLangName != null) {
|
||||
names.remove(langSelected);
|
||||
}
|
||||
Map<String, String> sortedNames = AndroidUtils.sortByValue(names);
|
||||
|
||||
if (selectedLangName != null) {
|
||||
MenuItem item = optionsMenu.getMenu().add(selectedLangName);
|
||||
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
dialog.dismiss();
|
||||
showWiki(ctx, app, a, langSelected);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
for (final Map.Entry<String, String> e : sortedNames.entrySet()) {
|
||||
MenuItem item = optionsMenu.getMenu().add(e.getValue());
|
||||
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
dialog.dismiss();
|
||||
showWiki(ctx, app, a, e.getKey());
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
optionsMenu.show();
|
||||
}
|
||||
|
||||
public static String getLangName(Context ctx, String basename) {
|
||||
try {
|
||||
String nm = basename.replace('-', '_').replace(' ', '_');
|
||||
Field f = R.string.class.getField("lang_"+nm);
|
||||
if (f != null) {
|
||||
Integer in = (Integer) f.get(null);
|
||||
return ctx.getString(in);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println(e.getMessage());
|
||||
}
|
||||
return basename;
|
||||
}
|
||||
|
||||
private static void showText(final Context ctx, final SampleApplication app, final String text, String title) {
|
||||
final Dialog dialog = new Dialog(ctx);
|
||||
|
||||
LinearLayout ll = new LinearLayout(ctx);
|
||||
ll.setOrientation(LinearLayout.VERTICAL);
|
||||
|
||||
final Toolbar topBar = new Toolbar(ctx);
|
||||
topBar.setClickable(true);
|
||||
Drawable back = app.getIconsCache().getIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
|
||||
topBar.setNavigationIcon(back);
|
||||
topBar.setNavigationContentDescription(app.getString("access_shared_string_navigate_up"));
|
||||
topBar.setTitle(title);
|
||||
topBar.setBackgroundColor(ContextCompat.getColor(ctx, R.color.osmand_orange));
|
||||
topBar.setTitleTextColor(ContextCompat.getColor(ctx, R.color.color_white));
|
||||
topBar.setNavigationOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(final View v) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
final TextView textView = new TextView(ctx);
|
||||
LinearLayout.LayoutParams llTextParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
int textMargin = AndroidUtils.dpToPx(app, 10f);
|
||||
boolean light = true;
|
||||
textView.setLayoutParams(llTextParams);
|
||||
textView.setPadding(textMargin, textMargin, textMargin, textMargin);
|
||||
textView.setTextSize(16);
|
||||
textView.setTextColor(ContextCompat.getColor(app, light ? R.color.ctx_menu_info_text_light : R.color.ctx_menu_info_text_dark));
|
||||
textView.setAutoLinkMask(Linkify.ALL);
|
||||
textView.setLinksClickable(true);
|
||||
textView.setText(text);
|
||||
|
||||
ScrollView scrollView = new ScrollView(ctx);
|
||||
ll.addView(topBar);
|
||||
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);
|
||||
lp.weight = 1;
|
||||
ll.addView(scrollView, lp);
|
||||
scrollView.addView(textView);
|
||||
|
||||
dialog.setContentView(ll);
|
||||
dialog.setCancelable(true);
|
||||
dialog.show();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,556 @@
|
|||
package net.osmand.core.samples.android.sample1.mapcontextmenu;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import net.osmand.core.samples.android.sample1.MainActivity;
|
||||
import net.osmand.core.samples.android.sample1.data.PointDescription;
|
||||
import net.osmand.core.samples.android.sample1.mapcontextmenu.MenuController.MenuState;
|
||||
import net.osmand.core.samples.android.sample1.mapcontextmenu.MenuController.MenuType;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
public class MapContextMenu extends MenuTitleController {
|
||||
|
||||
private MainActivity mainActivity;
|
||||
private MapMultiSelectionMenu mapMultiSelectionMenu;
|
||||
|
||||
private boolean active;
|
||||
private LatLon latLon;
|
||||
private PointDescription pointDescription;
|
||||
private Object object;
|
||||
private MenuController menuController;
|
||||
|
||||
private LatLon mapCenter;
|
||||
private boolean centerMarker;
|
||||
private int mapZoom;
|
||||
|
||||
private LatLon myLocation;
|
||||
private Float heading;
|
||||
private boolean inLocationUpdate = false;
|
||||
private boolean autoHide;
|
||||
|
||||
private MenuAction searchDoneAction;
|
||||
|
||||
public MapContextMenu() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public MainActivity getMainActivity() {
|
||||
return mainActivity;
|
||||
}
|
||||
|
||||
public void setMainActivity(MainActivity mainActivity) {
|
||||
this.mainActivity = mainActivity;
|
||||
|
||||
if (mapMultiSelectionMenu == null) {
|
||||
mapMultiSelectionMenu = new MapMultiSelectionMenu(mainActivity);
|
||||
} else {
|
||||
mapMultiSelectionMenu.setMainActivity(mainActivity);
|
||||
}
|
||||
|
||||
if (active) {
|
||||
acquireMenuController(false);
|
||||
if (menuController != null) {
|
||||
menuController.addPlainMenuItems(typeStr, this.pointDescription, this.latLon);
|
||||
}
|
||||
if (searchDoneAction != null && searchDoneAction.dlg != null && searchDoneAction.dlg.getOwnerActivity() != mainActivity) {
|
||||
searchDoneAction.dlg = buildSearchActionDialog();
|
||||
searchDoneAction.dlg.show();
|
||||
}
|
||||
} else {
|
||||
menuController = null;
|
||||
}
|
||||
}
|
||||
|
||||
public MapMultiSelectionMenu getMultiSelectionMenu() {
|
||||
return mapMultiSelectionMenu;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
public boolean isVisible() {
|
||||
return findMenuFragment() != null;
|
||||
}
|
||||
|
||||
public void hideMenues() {
|
||||
if (isVisible()) {
|
||||
hide();
|
||||
} else if (mapMultiSelectionMenu.isVisible()) {
|
||||
mapMultiSelectionMenu.hide();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public LatLon getLatLon() {
|
||||
return latLon;
|
||||
}
|
||||
|
||||
public LatLon getMapCenter() {
|
||||
return mapCenter;
|
||||
}
|
||||
|
||||
public void setMapCenter(LatLon mapCenter) {
|
||||
this.mapCenter = mapCenter;
|
||||
}
|
||||
|
||||
public void setCenterMarker(boolean centerMarker) {
|
||||
this.centerMarker = centerMarker;
|
||||
}
|
||||
|
||||
public int getMapZoom() {
|
||||
return mapZoom;
|
||||
}
|
||||
|
||||
public void setMapZoom(int mapZoom) {
|
||||
this.mapZoom = mapZoom;
|
||||
}
|
||||
|
||||
public void updateMapCenter(LatLon mapCenter) {
|
||||
WeakReference<MapContextMenuFragment> fragmentRef = findMenuFragment();
|
||||
if (fragmentRef != null) {
|
||||
fragmentRef.get().updateMapCenter(mapCenter);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PointDescription getPointDescription() {
|
||||
return pointDescription;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
public boolean isExtended() {
|
||||
return menuController != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MenuController getMenuController() {
|
||||
return menuController;
|
||||
}
|
||||
|
||||
public boolean init(@NonNull LatLon latLon,
|
||||
@Nullable PointDescription pointDescription,
|
||||
@Nullable Object object) {
|
||||
return init(latLon, pointDescription, object, false, false);
|
||||
}
|
||||
|
||||
public boolean init(@NonNull LatLon latLon,
|
||||
@Nullable PointDescription pointDescription,
|
||||
@Nullable Object object,
|
||||
boolean update, boolean restorePrevious) {
|
||||
|
||||
if (myLocation == null) {
|
||||
myLocation = mainActivity.getMyApplication().getLocationProvider().getLastKnownLocationLatLon();
|
||||
}
|
||||
|
||||
if (!update && isVisible()) {
|
||||
if (this.object == null || !this.object.equals(object)) {
|
||||
hide();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (pointDescription == null) {
|
||||
this.pointDescription = new PointDescription(latLon.getLatitude(), latLon.getLongitude());
|
||||
} else {
|
||||
this.pointDescription = pointDescription;
|
||||
}
|
||||
|
||||
boolean needAcquireMenuController = menuController == null
|
||||
|| !update
|
||||
|| this.object == null && object != null
|
||||
|| this.object != null && object == null
|
||||
|| (this.object != null && object != null && !this.object.getClass().equals(object.getClass()));
|
||||
|
||||
this.latLon = latLon;
|
||||
this.object = object;
|
||||
|
||||
active = true;
|
||||
|
||||
if (needAcquireMenuController) {
|
||||
acquireMenuController(restorePrevious);
|
||||
} else {
|
||||
menuController.update(pointDescription, object);
|
||||
}
|
||||
initTitle();
|
||||
|
||||
if (menuController != null) {
|
||||
menuController.clearPlainMenuItems();
|
||||
menuController.addPlainMenuItems(typeStr, this.pointDescription, this.latLon);
|
||||
}
|
||||
|
||||
mainActivity.refreshMap();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void show() {
|
||||
if (!isVisible()) {
|
||||
if (!MapContextMenuFragment.showInstance(this, mainActivity, true)) {
|
||||
active = false;
|
||||
}
|
||||
} else {
|
||||
WeakReference<MapContextMenuFragment> fragmentRef = findMenuFragment();
|
||||
if (fragmentRef != null) {
|
||||
fragmentRef.get().centerMarkerLocation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void show(@NonNull LatLon latLon,
|
||||
@Nullable PointDescription pointDescription,
|
||||
@Nullable Object object) {
|
||||
if (init(latLon, pointDescription, object)) {
|
||||
showInternal();
|
||||
}
|
||||
}
|
||||
|
||||
private void showInternal() {
|
||||
if (!MapContextMenuFragment.showInstance(this, mainActivity, centerMarker)) {
|
||||
active = false;
|
||||
} else {
|
||||
if (menuController != null) {
|
||||
menuController.onShow();
|
||||
}
|
||||
}
|
||||
centerMarker = false;
|
||||
autoHide = false;
|
||||
}
|
||||
|
||||
public void update(LatLon latLon, PointDescription pointDescription, Object object) {
|
||||
WeakReference<MapContextMenuFragment> fragmentRef = findMenuFragment();
|
||||
init(latLon, pointDescription, object, true, false);
|
||||
if (fragmentRef != null) {
|
||||
fragmentRef.get().rebuildMenu();
|
||||
}
|
||||
}
|
||||
|
||||
public void showOrUpdate(LatLon latLon, PointDescription pointDescription, Object object) {
|
||||
if (isVisible() && this.object != null && this.object.equals(object)) {
|
||||
update(latLon, pointDescription, object);
|
||||
} else {
|
||||
show(latLon, pointDescription, object);
|
||||
}
|
||||
}
|
||||
|
||||
public void showMinimized(LatLon latLon, PointDescription pointDescription, Object object) {
|
||||
init(latLon, pointDescription, object);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if (active) {
|
||||
active = false;
|
||||
if (menuController != null) {
|
||||
menuController.onClose();
|
||||
}
|
||||
hide();
|
||||
if (menuController != null) {
|
||||
menuController.setActive(false);
|
||||
}
|
||||
mainActivity.refreshMap();
|
||||
}
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
if (menuController != null) {
|
||||
menuController.onHide();
|
||||
}
|
||||
WeakReference<MapContextMenuFragment> fragmentRef = findMenuFragment();
|
||||
if (fragmentRef != null) {
|
||||
fragmentRef.get().dismissMenu();
|
||||
}
|
||||
}
|
||||
|
||||
// timeout in msec
|
||||
public void hideWithTimeout(long timeout) {
|
||||
autoHide = true;
|
||||
mainActivity.getMyApplication().runInUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (autoHide) {
|
||||
hide();
|
||||
}
|
||||
}
|
||||
}, timeout);
|
||||
}
|
||||
|
||||
public void updateMenuUI() {
|
||||
WeakReference<MapContextMenuFragment> fragmentRef = findMenuFragment();
|
||||
if (fragmentRef != null) {
|
||||
fragmentRef.get().updateMenu();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTitle(String address) {
|
||||
nameStr = address;
|
||||
pointDescription.setName(address);
|
||||
WeakReference<MapContextMenuFragment> fragmentRef = findMenuFragment();
|
||||
if (fragmentRef != null)
|
||||
fragmentRef.get().refreshTitle();
|
||||
}
|
||||
|
||||
private void acquireMenuController(boolean restorePrevious) {
|
||||
if (menuController != null) {
|
||||
menuController.onAcquireNewController(pointDescription, object);
|
||||
}
|
||||
menuController = MenuController.getMenuController(mainActivity, latLon, pointDescription, object, MenuType.STANDARD);
|
||||
menuController.setActive(true);
|
||||
}
|
||||
|
||||
public void onSingleTapOnMap() {
|
||||
if (menuController == null || !menuController.handleSingleTapOnMap()) {
|
||||
hide();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSearchAddressDone() {
|
||||
WeakReference<MapContextMenuFragment> fragmentRef = findMenuFragment();
|
||||
if (fragmentRef != null)
|
||||
fragmentRef.get().refreshTitle();
|
||||
|
||||
if (searchDoneAction != null) {
|
||||
if (searchDoneAction.dlg != null) {
|
||||
try {
|
||||
searchDoneAction.dlg.dismiss();
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
} finally {
|
||||
searchDoneAction.dlg = null;
|
||||
}
|
||||
}
|
||||
searchDoneAction.run();
|
||||
searchDoneAction = null;
|
||||
}
|
||||
}
|
||||
|
||||
public WeakReference<MapContextMenuFragment> findMenuFragment() {
|
||||
Fragment fragment = mainActivity.getSupportFragmentManager().findFragmentByTag(MapContextMenuFragment.TAG);
|
||||
if (fragment != null && !fragment.isDetached()) {
|
||||
return new WeakReference<>((MapContextMenuFragment) fragment);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void callMenuAction(boolean waitForAddressLookup, MenuAction menuAction) {
|
||||
if (searchingAddress() && waitForAddressLookup) {
|
||||
menuAction.dlg = buildSearchActionDialog();
|
||||
menuAction.dlg.show();
|
||||
searchDoneAction = menuAction;
|
||||
} else {
|
||||
menuAction.run();
|
||||
}
|
||||
}
|
||||
|
||||
private ProgressDialog buildSearchActionDialog() {
|
||||
ProgressDialog dlg = new ProgressDialog(mainActivity);
|
||||
dlg.setTitle("");
|
||||
dlg.setMessage(searchAddressStr);
|
||||
dlg.setButton(Dialog.BUTTON_NEGATIVE, mainActivity.getMyApplication().getString("shared_string_skip"), new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
cancelSearchAddress();
|
||||
}
|
||||
});
|
||||
return dlg;
|
||||
}
|
||||
|
||||
public void setBaseFragmentVisibility(boolean visible) {
|
||||
WeakReference<MapContextMenuFragment> fragmentRef = findMenuFragment();
|
||||
if (fragmentRef != null) {
|
||||
fragmentRef.get().setFragmentVisibility(visible);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isLandscapeLayout() {
|
||||
return menuController != null && menuController.isLandscapeLayout();
|
||||
}
|
||||
|
||||
public int getLandscapeWidthPx() {
|
||||
if (menuController != null) {
|
||||
return menuController.getLandscapeWidthPx();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void openMenuFullScreen() {
|
||||
WeakReference<MapContextMenuFragment> fragmentRef = findMenuFragment();
|
||||
if (fragmentRef != null)
|
||||
fragmentRef.get().openMenuFullScreen();
|
||||
}
|
||||
|
||||
public boolean slideUp() {
|
||||
return menuController != null && menuController.slideUp();
|
||||
}
|
||||
|
||||
public boolean slideDown() {
|
||||
return menuController != null && menuController.slideDown();
|
||||
}
|
||||
|
||||
public void build(View rootView) {
|
||||
if (menuController != null) {
|
||||
menuController.build(rootView);
|
||||
}
|
||||
}
|
||||
|
||||
public int getCurrentMenuState() {
|
||||
if (menuController != null) {
|
||||
return menuController.getCurrentMenuState();
|
||||
} else {
|
||||
return MenuState.HEADER_ONLY;
|
||||
}
|
||||
}
|
||||
|
||||
public float getHalfScreenMaxHeightKoef() {
|
||||
if (menuController != null) {
|
||||
return menuController.getHalfScreenMaxHeightKoef();
|
||||
} else {
|
||||
return 0f;
|
||||
}
|
||||
}
|
||||
|
||||
public int getSlideInAnimation() {
|
||||
if (menuController != null) {
|
||||
return menuController.getSlideInAnimation();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public int getSlideOutAnimation() {
|
||||
if (menuController != null) {
|
||||
return menuController.getSlideOutAnimation();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public MenuController.TitleButtonController getLeftTitleButtonController() {
|
||||
if (menuController != null) {
|
||||
return menuController.getLeftTitleButtonController();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public MenuController.TitleButtonController getRightTitleButtonController() {
|
||||
if (menuController != null) {
|
||||
return menuController.getRightTitleButtonController();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public MenuController.TitleButtonController getTopRightTitleButtonController() {
|
||||
if (menuController != null) {
|
||||
return menuController.getTopRightTitleButtonController();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean supportZoomIn() {
|
||||
return menuController == null || menuController.supportZoomIn();
|
||||
}
|
||||
|
||||
public boolean fabVisible() {
|
||||
return menuController == null || menuController.fabVisible();
|
||||
}
|
||||
|
||||
public boolean buttonsVisible() {
|
||||
return menuController == null || menuController.buttonsVisible();
|
||||
}
|
||||
|
||||
public boolean displayDistanceDirection() {
|
||||
return menuController != null && menuController.displayDistanceDirection();
|
||||
}
|
||||
|
||||
public boolean hasCustomAddressLine() {
|
||||
return menuController != null && menuController.hasCustomAddressLine();
|
||||
}
|
||||
|
||||
public void buildCustomAddressLine(LinearLayout ll) {
|
||||
if (menuController != null) {
|
||||
menuController.buildCustomAddressLine(ll);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isNightMode() {
|
||||
if (menuController != null) {
|
||||
return !menuController.isLight();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasHiddenBottomInfo() {
|
||||
return getCurrentMenuState() == MenuState.HEADER_ONLY;
|
||||
}
|
||||
|
||||
public LatLon getMyLocation() {
|
||||
return myLocation;
|
||||
}
|
||||
|
||||
public Float getHeading() {
|
||||
return heading;
|
||||
}
|
||||
|
||||
public void updateMyLocation(net.osmand.Location location) {
|
||||
if (location != null && active && displayDistanceDirection()) {
|
||||
myLocation = new LatLon(location.getLatitude(), location.getLongitude());
|
||||
updateLocation(false, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateCompassValue(float value) {
|
||||
if (active && displayDistanceDirection()) {
|
||||
// 99 in next line used to one-time initialize arrows (with reference vs. fixed-north direction)
|
||||
// on non-compass devices
|
||||
float lastHeading = heading != null ? heading : 99;
|
||||
heading = value;
|
||||
if (Math.abs(MapUtils.degreesDiff(lastHeading, heading)) > 5) {
|
||||
updateLocation(false, false, true);
|
||||
} else {
|
||||
heading = lastHeading;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateLocation(final boolean centerChanged, final boolean locationChanged,
|
||||
final boolean compassChanged) {
|
||||
if (inLocationUpdate) {
|
||||
return;
|
||||
}
|
||||
inLocationUpdate = true;
|
||||
mainActivity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
inLocationUpdate = false;
|
||||
WeakReference<MapContextMenuFragment> fragmentRef = findMenuFragment();
|
||||
if (fragmentRef != null) {
|
||||
fragmentRef.get().updateLocation(centerChanged, locationChanged, compassChanged);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private abstract class MenuAction implements Runnable {
|
||||
protected ProgressDialog dlg;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,165 @@
|
|||
package net.osmand.core.samples.android.sample1.mapcontextmenu;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.Fragment;
|
||||
|
||||
import net.osmand.core.samples.android.sample1.MainActivity;
|
||||
import net.osmand.core.samples.android.sample1.data.PointDescription;
|
||||
import net.osmand.data.LatLon;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class MapMultiSelectionMenu extends BaseMenuController {
|
||||
|
||||
private LatLon latLon;
|
||||
private LinkedList<MenuObject> objects = new LinkedList<>();
|
||||
|
||||
public static class MenuObject extends MenuTitleController {
|
||||
|
||||
private LatLon latLon;
|
||||
private PointDescription pointDescription;
|
||||
private Object object;
|
||||
private int order;
|
||||
|
||||
private MainActivity mainActivity;
|
||||
private MenuController controller;
|
||||
|
||||
public MenuObject(LatLon latLon, PointDescription pointDescription, Object object, MainActivity mainActivity) {
|
||||
this.latLon = latLon;
|
||||
this.pointDescription = pointDescription;
|
||||
this.object = object;
|
||||
this.mainActivity = mainActivity;
|
||||
init();
|
||||
}
|
||||
|
||||
protected void init() {
|
||||
controller = MenuController.getMenuController(mainActivity, latLon, pointDescription, object, MenuController.MenuType.MULTI_LINE);
|
||||
controller.setActive(true);
|
||||
initTitle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LatLon getLatLon() {
|
||||
return latLon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PointDescription getPointDescription() {
|
||||
return pointDescription;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getObject() {
|
||||
return object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MainActivity getMainActivity() {
|
||||
return mainActivity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MenuController getMenuController() {
|
||||
return controller;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean needStreetName() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public MapMultiSelectionMenu(MainActivity mainActivity) {
|
||||
super(mainActivity);
|
||||
}
|
||||
|
||||
public void setMainActivity(MainActivity mainActivity) {
|
||||
super.setMainActivity(mainActivity);
|
||||
for (MenuObject o : objects) {
|
||||
o.mainActivity = mainActivity;
|
||||
o.init();
|
||||
}
|
||||
}
|
||||
|
||||
public List<MenuObject> getObjects() {
|
||||
return objects;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getHalfScreenMaxHeightKoef() {
|
||||
return 0.5f;
|
||||
}
|
||||
|
||||
private void createCollection(List<Object> selectedObjects) {
|
||||
objects.clear();
|
||||
for (Object selectedObj : selectedObjects) {
|
||||
LatLon ll = MenuController.getObjectLocation(selectedObj);
|
||||
PointDescription pointDescription = MenuController.getObjectName(selectedObj);
|
||||
|
||||
if (ll == null) {
|
||||
ll = latLon;
|
||||
}
|
||||
if (pointDescription == null) {
|
||||
pointDescription = new PointDescription(latLon.getLatitude(), latLon.getLongitude());
|
||||
}
|
||||
|
||||
MenuObject menuObject = new MenuObject(ll, pointDescription, selectedObj, getMainActivity());
|
||||
menuObject.order = MenuController.getObjectPriority(selectedObj);
|
||||
objects.add(menuObject);
|
||||
}
|
||||
|
||||
Collections.sort(objects, new Comparator<MenuObject>() {
|
||||
@Override
|
||||
public int compare(MenuObject obj1, MenuObject obj2) {
|
||||
if (obj1.order == obj2.order) {
|
||||
return obj1.getTitleStr().compareToIgnoreCase(obj2.getTitleStr());
|
||||
} else {
|
||||
return obj1.order - obj2.order;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void clearMenu() {
|
||||
objects.clear();
|
||||
getMainActivity().refreshMap();
|
||||
}
|
||||
|
||||
public void show(LatLon latLon, List<Object> selectedObjects) {
|
||||
if (isVisible()) {
|
||||
hide();
|
||||
}
|
||||
|
||||
this.latLon = latLon;
|
||||
createCollection(selectedObjects);
|
||||
updateNightMode();
|
||||
MapMultiSelectionMenuFragment.showInstance(getMainActivity());
|
||||
getMainActivity().refreshMap();
|
||||
}
|
||||
|
||||
public boolean isVisible() {
|
||||
Fragment fragment = getMainActivity().getSupportFragmentManager().findFragmentByTag(MapMultiSelectionMenuFragment.TAG);
|
||||
return fragment != null;
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
clearMenu();
|
||||
Fragment fragment = getMainActivity().getSupportFragmentManager().findFragmentByTag(MapMultiSelectionMenuFragment.TAG);
|
||||
if (fragment != null) {
|
||||
MapMultiSelectionMenuFragment menuFragment = (MapMultiSelectionMenuFragment) fragment;
|
||||
menuFragment.dismissMenu();
|
||||
}
|
||||
}
|
||||
|
||||
public void onStop() {
|
||||
}
|
||||
|
||||
public void openContextMenu(@NonNull MenuObject menuObject) {
|
||||
hide();
|
||||
getMainActivity().showContextMenu(
|
||||
menuObject.getLatLon(), menuObject.getPointDescription(), menuObject.getObject());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,207 @@
|
|||
package net.osmand.core.samples.android.sample1.mapcontextmenu;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.TypedValue;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.core.samples.android.sample1.IconsCache;
|
||||
import net.osmand.core.samples.android.sample1.MainActivity;
|
||||
import net.osmand.core.samples.android.sample1.R;
|
||||
import net.osmand.core.samples.android.sample1.mapcontextmenu.MapMultiSelectionMenu.MenuObject;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import static android.util.TypedValue.COMPLEX_UNIT_DIP;
|
||||
|
||||
public class MapMultiSelectionMenuFragment extends Fragment implements AdapterView.OnItemClickListener {
|
||||
public static final String TAG = "MapMultiSelectionMenuFragment";
|
||||
|
||||
private View view;
|
||||
private ArrayAdapter<MenuObject> listAdapter;
|
||||
private MapMultiSelectionMenu menu;
|
||||
private boolean dismissing = false;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
|
||||
menu = ((MainActivity) getActivity()).getContextMenu().getMultiSelectionMenu();
|
||||
|
||||
view = inflater.inflate(R.layout.menu_obj_selection_fragment, container, false);
|
||||
if (menu.isLandscapeLayout()) {
|
||||
AndroidUtils.setBackground(view.getContext(), view, !menu.isLight(),
|
||||
R.drawable.bg_left_menu_light, 0);
|
||||
} else {
|
||||
AndroidUtils.setBackground(view.getContext(), view, !menu.isLight(),
|
||||
R.drawable.bg_bottom_menu_light, 0);
|
||||
}
|
||||
|
||||
ListView listView = (ListView) view.findViewById(R.id.list);
|
||||
listAdapter = createAdapter();
|
||||
listView.setAdapter(listAdapter);
|
||||
listView.setOnItemClickListener(this);
|
||||
|
||||
if (!oldAndroid()) {
|
||||
runLayoutListener();
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
menu.getMainActivity().getContextMenu().setBaseFragmentVisibility(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
if (!dismissing) {
|
||||
menu.onStop();
|
||||
}
|
||||
menu.getMainActivity().getContextMenu().setBaseFragmentVisibility(true);
|
||||
}
|
||||
|
||||
public static void showInstance(final MainActivity mainActivity) {
|
||||
|
||||
MapMultiSelectionMenu menu = mainActivity.getContextMenu().getMultiSelectionMenu();
|
||||
|
||||
int slideInAnim = menu.getSlideInAnimation();
|
||||
int slideOutAnim = menu.getSlideOutAnimation();
|
||||
|
||||
MapMultiSelectionMenuFragment fragment = new MapMultiSelectionMenuFragment();
|
||||
menu.getMainActivity().getSupportFragmentManager().beginTransaction()
|
||||
.setCustomAnimations(slideInAnim, slideOutAnim, slideInAnim, slideOutAnim)
|
||||
.add(R.id.fragmentContainer, fragment, TAG)
|
||||
.addToBackStack(TAG).commitAllowingStateLoss();
|
||||
}
|
||||
|
||||
private void runLayoutListener() {
|
||||
ViewTreeObserver vto = view.getViewTreeObserver();
|
||||
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
|
||||
|
||||
@Override
|
||||
public void onGlobalLayout() {
|
||||
|
||||
int maxHeight = (int) (getScreenHeight() * menu.getHalfScreenMaxHeightKoef());
|
||||
int height = view.findViewById(R.id.main_view).getHeight();
|
||||
|
||||
ViewTreeObserver obs = view.getViewTreeObserver();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
obs.removeOnGlobalLayoutListener(this);
|
||||
} else {
|
||||
obs.removeGlobalOnLayoutListener(this);
|
||||
}
|
||||
|
||||
if (!menu.isLandscapeLayout() && height > maxHeight) {
|
||||
ViewGroup.LayoutParams lp = view.getLayoutParams();
|
||||
lp.height = maxHeight;
|
||||
view.setLayoutParams(lp);
|
||||
view.requestLayout();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private ArrayAdapter<MenuObject> createAdapter() {
|
||||
final List<MenuObject> items = new LinkedList<>(menu.getObjects());
|
||||
return new ArrayAdapter<MenuObject>(menu.getMainActivity(), R.layout.menu_obj_list_item, items) {
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
@Override
|
||||
public View getView(final int position, View convertView, ViewGroup parent) {
|
||||
View v = convertView;
|
||||
if (v == null) {
|
||||
v = menu.getMainActivity().getLayoutInflater().inflate(R.layout.menu_obj_list_item, null);
|
||||
}
|
||||
final MenuObject item = getItem(position);
|
||||
buildHeader(v, item, menu.getMainActivity());
|
||||
return v;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void buildHeader(View view, MenuObject item, MainActivity mainActivity) {
|
||||
|
||||
AndroidUtils.setBackground(mainActivity, view, !menu.isLight(), R.drawable.expandable_list_item_background_light, 0);
|
||||
IconsCache iconsCache = mainActivity.getMyApplication().getIconsCache();
|
||||
final View iconLayout = view.findViewById(R.id.context_menu_icon_layout);
|
||||
final ImageView iconView = (ImageView) view.findViewById(R.id.context_menu_icon_view);
|
||||
Drawable icon = item.getLeftIcon();
|
||||
int iconId = item.getLeftIconId();
|
||||
if (icon != null) {
|
||||
iconView.setImageDrawable(icon);
|
||||
iconLayout.setVisibility(View.VISIBLE);
|
||||
} else if (iconId != 0) {
|
||||
iconView.setImageDrawable(iconsCache.getOsmandIcon(iconId,
|
||||
menu.isLight() ? R.color.osmand_orange : R.color.osmand_orange_dark));
|
||||
iconLayout.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
iconLayout.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
// Text line 1
|
||||
TextView line1 = (TextView) view.findViewById(R.id.context_menu_line1);
|
||||
AndroidUtils.setTextPrimaryColor(mainActivity, line1, !menu.isLight());
|
||||
line1.setText(item.getTitleStr());
|
||||
|
||||
// Text line 2
|
||||
TextView line2 = (TextView) view.findViewById(R.id.context_menu_line2);
|
||||
AndroidUtils.setTextSecondaryColor(mainActivity, line2, !menu.isLight());
|
||||
line2.setText(item.getTypeStr());
|
||||
Drawable slIcon = item.getTypeIcon();
|
||||
line2.setCompoundDrawablesWithIntrinsicBounds(slIcon, null, null, null);
|
||||
line2.setCompoundDrawablePadding(dpToPx(5f));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
menu.openContextMenu(listAdapter.getItem(position));
|
||||
}
|
||||
|
||||
public void dismissMenu() {
|
||||
dismissing = true;
|
||||
if (menu.getMainActivity().getContextMenu().isVisible()) {
|
||||
menu.getMainActivity().getContextMenu().hide();
|
||||
} else {
|
||||
menu.getMainActivity().getSupportFragmentManager().popBackStack();
|
||||
}
|
||||
}
|
||||
|
||||
private int dpToPx(float dp) {
|
||||
Resources r = getActivity().getResources();
|
||||
return (int) TypedValue.applyDimension(
|
||||
COMPLEX_UNIT_DIP,
|
||||
dp,
|
||||
r.getDisplayMetrics()
|
||||
);
|
||||
}
|
||||
|
||||
private int getScreenHeight() {
|
||||
DisplayMetrics dm = new DisplayMetrics();
|
||||
getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
|
||||
return dm.heightPixels;
|
||||
}
|
||||
|
||||
private boolean oldAndroid() {
|
||||
return (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,322 @@
|
|||
package net.osmand.core.samples.android.sample1.mapcontextmenu;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.text.ClipboardManager;
|
||||
import android.text.util.Linkify;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import net.osmand.core.samples.android.sample1.IconsCache;
|
||||
import net.osmand.core.samples.android.sample1.MainActivity;
|
||||
import net.osmand.core.samples.android.sample1.OsmandResources;
|
||||
import net.osmand.core.samples.android.sample1.R;
|
||||
import net.osmand.core.samples.android.sample1.SampleApplication;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
import static android.util.TypedValue.COMPLEX_UNIT_DIP;
|
||||
|
||||
public class MenuBuilder {
|
||||
|
||||
public static final float SHADOW_HEIGHT_TOP_DP = 17f;
|
||||
|
||||
protected MainActivity mainActivity;
|
||||
protected SampleApplication app;
|
||||
protected LinkedList<PlainMenuItem> plainMenuItems;
|
||||
private boolean firstRow;
|
||||
protected boolean light;
|
||||
|
||||
public class PlainMenuItem {
|
||||
private int iconId;
|
||||
private String text;
|
||||
private boolean needLinks;
|
||||
private boolean url;
|
||||
private OnClickListener onClickListener;
|
||||
|
||||
public PlainMenuItem(int iconId, String text, boolean needLinks, boolean url, OnClickListener onClickListener) {
|
||||
this.iconId = iconId;
|
||||
this.text = text;
|
||||
this.needLinks = needLinks;
|
||||
this.url = url;
|
||||
this.onClickListener = onClickListener;
|
||||
}
|
||||
|
||||
public int getIconId() {
|
||||
return iconId;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public boolean isNeedLinks() {
|
||||
return needLinks;
|
||||
}
|
||||
|
||||
public boolean isUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public OnClickListener getOnClickListener() {
|
||||
return onClickListener;
|
||||
}
|
||||
}
|
||||
|
||||
public MenuBuilder(MainActivity mainActivity) {
|
||||
this.mainActivity = mainActivity;
|
||||
this.app = mainActivity.getMyApplication();
|
||||
plainMenuItems = new LinkedList<>();
|
||||
}
|
||||
|
||||
public void setLight(boolean light) {
|
||||
this.light = light;
|
||||
}
|
||||
|
||||
public void build(View view) {
|
||||
firstRow = true;
|
||||
if (needBuildPlainMenuItems()) {
|
||||
buildPlainMenuItems(view);
|
||||
}
|
||||
buildInternal(view);
|
||||
buildAfter(view);
|
||||
}
|
||||
|
||||
protected void buildPlainMenuItems(View view) {
|
||||
for (PlainMenuItem item : plainMenuItems) {
|
||||
buildRow(view, item.getIconId(), item.getText(), 0, item.isNeedLinks(), 0, item.isUrl(), item.getOnClickListener());
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean needBuildPlainMenuItems() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void buildInternal(View view) {
|
||||
}
|
||||
|
||||
protected void buildAfter(View view) {
|
||||
buildRowDivider(view, false);
|
||||
}
|
||||
|
||||
protected boolean isFirstRow() {
|
||||
return firstRow;
|
||||
}
|
||||
|
||||
public void rowBuilt() {
|
||||
firstRow = false;
|
||||
}
|
||||
|
||||
protected View buildRow(View view, int iconId, String text, int textColor, boolean needLinks, int textLinesLimit, boolean isUrl, OnClickListener onClickListener) {
|
||||
return buildRow(view, getRowIcon(iconId), text, textColor, needLinks, textLinesLimit, isUrl, onClickListener);
|
||||
}
|
||||
|
||||
protected View buildRow(final View view, Drawable icon, final String text, int textColor, boolean needLinks, int textLinesLimit, boolean isUrl, OnClickListener onClickListener) {
|
||||
|
||||
if (!isFirstRow()) {
|
||||
buildRowDivider(view, false);
|
||||
}
|
||||
|
||||
LinearLayout ll = new LinearLayout(view.getContext());
|
||||
ll.setOrientation(LinearLayout.HORIZONTAL);
|
||||
LinearLayout.LayoutParams llParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
ll.setLayoutParams(llParams);
|
||||
ll.setBackgroundResource(resolveAttribute(view.getContext(), android.R.attr.selectableItemBackground));
|
||||
ll.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
copyToClipboard(text, view.getContext());
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// Icon
|
||||
LinearLayout llIcon = new LinearLayout(view.getContext());
|
||||
llIcon.setOrientation(LinearLayout.HORIZONTAL);
|
||||
llIcon.setLayoutParams(new LinearLayout.LayoutParams(dpToPx(72f), dpToPx(48f)));
|
||||
llIcon.setGravity(Gravity.CENTER_VERTICAL);
|
||||
ll.addView(llIcon);
|
||||
|
||||
ImageView iconView = new ImageView(view.getContext());
|
||||
LinearLayout.LayoutParams llIconParams = new LinearLayout.LayoutParams(dpToPx(24f), dpToPx(24f));
|
||||
llIconParams.setMargins(dpToPx(16f), dpToPx(12f), dpToPx(32f), dpToPx(12f));
|
||||
llIconParams.gravity = Gravity.CENTER_VERTICAL;
|
||||
iconView.setLayoutParams(llIconParams);
|
||||
iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
|
||||
iconView.setImageDrawable(icon);
|
||||
llIcon.addView(iconView);
|
||||
|
||||
// Text
|
||||
LinearLayout llText = new LinearLayout(view.getContext());
|
||||
llText.setOrientation(LinearLayout.VERTICAL);
|
||||
ll.addView(llText);
|
||||
|
||||
TextView textView = new TextView(view.getContext());
|
||||
LinearLayout.LayoutParams llTextParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
llTextParams.setMargins(0, dpToPx(8f), 0, dpToPx(8f));
|
||||
textView.setLayoutParams(llTextParams);
|
||||
textView.setTextSize(16);
|
||||
textView.setTextColor(app.getResources().getColor(light ? R.color.ctx_menu_info_text_light : R.color.ctx_menu_info_text_dark));
|
||||
|
||||
if (isUrl) {
|
||||
textView.setTextColor(textView.getLinkTextColors());
|
||||
} else if (needLinks) {
|
||||
textView.setAutoLinkMask(Linkify.ALL);
|
||||
textView.setLinksClickable(true);
|
||||
}
|
||||
if (textLinesLimit > 0) {
|
||||
textView.setMinLines(1);
|
||||
textView.setMaxLines(textLinesLimit);
|
||||
}
|
||||
textView.setText(text);
|
||||
if (textColor > 0) {
|
||||
textView.setTextColor(view.getResources().getColor(textColor));
|
||||
}
|
||||
|
||||
LinearLayout.LayoutParams llTextViewParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
llTextViewParams.setMargins(0, 0, dpToPx(10f), 0);
|
||||
llTextViewParams.gravity = Gravity.CENTER_VERTICAL;
|
||||
llText.setLayoutParams(llTextViewParams);
|
||||
llText.addView(textView);
|
||||
|
||||
if (onClickListener != null) {
|
||||
ll.setOnClickListener(onClickListener);
|
||||
} else if (isUrl) {
|
||||
ll.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setData(Uri.parse(text));
|
||||
v.getContext().startActivity(intent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
((LinearLayout) view).addView(ll);
|
||||
|
||||
rowBuilt();
|
||||
|
||||
return ll;
|
||||
}
|
||||
|
||||
protected void copyToClipboard(String text, Context ctx) {
|
||||
((ClipboardManager) app.getSystemService(Activity.CLIPBOARD_SERVICE)).setText(text);
|
||||
Toast.makeText(ctx,
|
||||
app.getString("copied_to_clipboard") + ":\n" + text,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
protected void buildButtonRow(final View view, Drawable buttonIcon, String text, OnClickListener onClickListener) {
|
||||
LinearLayout ll = new LinearLayout(view.getContext());
|
||||
ll.setOrientation(LinearLayout.HORIZONTAL);
|
||||
LinearLayout.LayoutParams llParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
ll.setLayoutParams(llParams);
|
||||
ll.setBackgroundResource(resolveAttribute(view.getContext(), android.R.attr.selectableItemBackground));
|
||||
|
||||
// Empty
|
||||
LinearLayout llIcon = new LinearLayout(view.getContext());
|
||||
llIcon.setOrientation(LinearLayout.HORIZONTAL);
|
||||
llIcon.setLayoutParams(new LinearLayout.LayoutParams(dpToPx(62f), dpToPx(58f)));
|
||||
llIcon.setGravity(Gravity.CENTER_VERTICAL);
|
||||
ll.addView(llIcon);
|
||||
|
||||
|
||||
// Button
|
||||
LinearLayout llButton = new LinearLayout(view.getContext());
|
||||
llButton.setOrientation(LinearLayout.VERTICAL);
|
||||
ll.addView(llButton);
|
||||
|
||||
Button buttonView = new Button(view.getContext());
|
||||
LinearLayout.LayoutParams llBtnParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
buttonView.setLayoutParams(llBtnParams);
|
||||
buttonView.setPadding(dpToPx(10f), 0, dpToPx(10f), 0);
|
||||
buttonView.setGravity(Gravity.START | Gravity.CENTER_VERTICAL);
|
||||
//buttonView.setTextSize(view.getResources().getDimension(resolveAttribute(view.getContext(), R.dimen.default_desc_text_size)));
|
||||
buttonView.setTextColor(view.getResources().getColor(resolveAttribute(view.getContext(), R.attr.contextMenuButtonColor)));
|
||||
buttonView.setText(text);
|
||||
|
||||
if (buttonIcon != null) {
|
||||
buttonView.setCompoundDrawablesWithIntrinsicBounds(buttonIcon, null, null, null);
|
||||
buttonView.setCompoundDrawablePadding(dpToPx(8f));
|
||||
}
|
||||
llButton.addView(buttonView);
|
||||
|
||||
((LinearLayout) view).addView(ll);
|
||||
|
||||
ll.setOnClickListener(onClickListener);
|
||||
|
||||
rowBuilt();
|
||||
}
|
||||
|
||||
protected void buildRowDivider(View view, boolean matchWidth) {
|
||||
View horizontalLine = new View(view.getContext());
|
||||
LinearLayout.LayoutParams llHorLineParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dpToPx(1f));
|
||||
llHorLineParams.gravity = Gravity.BOTTOM;
|
||||
if (!matchWidth) {
|
||||
llHorLineParams.setMargins(dpToPx(72f), 0, 0, 0);
|
||||
}
|
||||
horizontalLine.setLayoutParams(llHorLineParams);
|
||||
horizontalLine.setBackgroundColor(app.getResources().getColor(light ? R.color.ctx_menu_info_divider_light : R.color.ctx_menu_info_divider_dark));
|
||||
((LinearLayout) view).addView(horizontalLine);
|
||||
}
|
||||
|
||||
public boolean hasCustomAddressLine() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void buildCustomAddressLine(LinearLayout ll) {
|
||||
}
|
||||
|
||||
public void addPlainMenuItem(int iconId, String text, boolean needLinks, boolean isUrl, OnClickListener onClickListener) {
|
||||
plainMenuItems.add(new PlainMenuItem(iconId, text, needLinks, isUrl, onClickListener));
|
||||
}
|
||||
|
||||
public void clearPlainMenuItems() {
|
||||
plainMenuItems.clear();
|
||||
}
|
||||
|
||||
public Drawable getRowIcon(int iconId) {
|
||||
IconsCache iconsCache = app.getIconsCache();
|
||||
return iconsCache.getOsmandIcon(iconId,
|
||||
light ? R.color.icon_color : R.color.icon_color_light);
|
||||
}
|
||||
|
||||
public Drawable getRowIcon(Context ctx, String fileName) {
|
||||
Drawable d = OsmandResources.getBigDrawable(fileName);
|
||||
if (d != null) {
|
||||
d.setColorFilter(app.getResources()
|
||||
.getColor(light ? R.color.icon_color : R.color.icon_color_light), PorterDuff.Mode.SRC_IN);
|
||||
return d;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public int resolveAttribute(Context ctx, int attribute) {
|
||||
TypedValue outValue = new TypedValue();
|
||||
ctx.getTheme().resolveAttribute(attribute, outValue, true);
|
||||
return outValue.resourceId;
|
||||
}
|
||||
|
||||
public int dpToPx(float dp) {
|
||||
Resources r = app.getResources();
|
||||
return (int) TypedValue.applyDimension(
|
||||
COMPLEX_UNIT_DIP,
|
||||
dp,
|
||||
r.getDisplayMetrics()
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,355 @@
|
|||
package net.osmand.core.samples.android.sample1.mapcontextmenu;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import net.osmand.core.samples.android.sample1.MainActivity;
|
||||
import net.osmand.core.samples.android.sample1.OsmandResources;
|
||||
import net.osmand.core.samples.android.sample1.R;
|
||||
import net.osmand.core.samples.android.sample1.SampleApplication;
|
||||
import net.osmand.core.samples.android.sample1.SampleUtils;
|
||||
import net.osmand.core.samples.android.sample1.data.PointDescription;
|
||||
import net.osmand.core.samples.android.sample1.mapcontextmenu.controllers.AmenityMenuController;
|
||||
import net.osmand.core.samples.android.sample1.mapcontextmenu.controllers.MyLocationMenuController;
|
||||
import net.osmand.core.samples.android.sample1.mapcontextmenu.controllers.PointDescriptionMenuController;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.data.LatLon;
|
||||
|
||||
public abstract class MenuController extends BaseMenuController {
|
||||
|
||||
public static class MenuState {
|
||||
public static final int HEADER_ONLY = 1;
|
||||
public static final int HALF_SCREEN = 2;
|
||||
public static final int FULL_SCREEN = 4;
|
||||
}
|
||||
|
||||
public enum MenuType {
|
||||
STANDARD,
|
||||
MULTI_LINE
|
||||
}
|
||||
|
||||
protected MenuBuilder builder;
|
||||
private int currentMenuState;
|
||||
private MenuType menuType = MenuType.STANDARD;
|
||||
private PointDescription pointDescription;
|
||||
private LatLon latLon;
|
||||
private boolean active;
|
||||
|
||||
protected TitleButtonController leftTitleButtonController;
|
||||
protected TitleButtonController rightTitleButtonController;
|
||||
protected TitleButtonController topRightTitleButtonController;
|
||||
|
||||
//protected TopToolbarController toolbarController;
|
||||
|
||||
public MenuController(MenuBuilder builder, PointDescription pointDescription, MainActivity mainActivity) {
|
||||
super(mainActivity);
|
||||
this.pointDescription = pointDescription;
|
||||
this.builder = builder;
|
||||
this.currentMenuState = getInitialMenuState();
|
||||
this.builder.setLight(isLight());
|
||||
}
|
||||
|
||||
public void build(View rootView) {
|
||||
builder.build(rootView);
|
||||
}
|
||||
|
||||
public static MenuController getMenuController(MainActivity mainActivity,
|
||||
LatLon latLon, PointDescription pointDescription, Object object,
|
||||
MenuType menuType) {
|
||||
SampleApplication app = mainActivity.getMyApplication();
|
||||
MenuController menuController = null;
|
||||
if (object != null) {
|
||||
if (object instanceof Amenity) {
|
||||
menuController = new AmenityMenuController(mainActivity, pointDescription, (Amenity) object);
|
||||
} else if (object instanceof LatLon) {
|
||||
if (pointDescription.isMyLocation()) {
|
||||
menuController = new MyLocationMenuController(mainActivity, pointDescription);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (menuController == null) {
|
||||
menuController = new PointDescriptionMenuController(mainActivity, pointDescription);
|
||||
}
|
||||
menuController.menuType = menuType;
|
||||
menuController.setLatLon(latLon);
|
||||
return menuController;
|
||||
}
|
||||
|
||||
public void update(PointDescription pointDescription, Object object) {
|
||||
setPointDescription(pointDescription);
|
||||
setObject(object);
|
||||
}
|
||||
|
||||
protected void setPointDescription(PointDescription pointDescription) {
|
||||
this.pointDescription = pointDescription;
|
||||
}
|
||||
|
||||
protected abstract void setObject(Object object);
|
||||
|
||||
protected abstract Object getObject();
|
||||
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
public void setActive(boolean active) {
|
||||
this.active = active;
|
||||
}
|
||||
|
||||
public void addPlainMenuItem(int iconId, String text, boolean needLinks, boolean isUrl, OnClickListener onClickListener) {
|
||||
builder.addPlainMenuItem(iconId, text, needLinks, isUrl, onClickListener);
|
||||
}
|
||||
|
||||
public void clearPlainMenuItems() {
|
||||
builder.clearPlainMenuItems();
|
||||
}
|
||||
|
||||
public void addPlainMenuItems(String typeStr, PointDescription pointDescription, LatLon latLon) {
|
||||
addMyLocationToPlainItems(latLon);
|
||||
}
|
||||
|
||||
protected void addMyLocationToPlainItems(LatLon latLon) {
|
||||
addPlainMenuItem(OsmandResources.getDrawableId("ic_action_get_my_location"), PointDescription.getLocationName(getMainActivity().getMyApplication(),
|
||||
latLon.getLatitude(), latLon.getLongitude(), true).replaceAll("\n", " "), false, false, null);
|
||||
}
|
||||
|
||||
public PointDescription getPointDescription() {
|
||||
return pointDescription;
|
||||
}
|
||||
|
||||
public int getInitialMenuState() {
|
||||
if (isLandscapeLayout()) {
|
||||
return MenuState.FULL_SCREEN;
|
||||
} else {
|
||||
return getInitialMenuStatePortrait();
|
||||
}
|
||||
}
|
||||
|
||||
public int getSupportedMenuStates() {
|
||||
if (isLandscapeLayout()) {
|
||||
return MenuState.FULL_SCREEN;
|
||||
} else {
|
||||
return getSupportedMenuStatesPortrait();
|
||||
}
|
||||
}
|
||||
|
||||
protected int getInitialMenuStatePortrait() {
|
||||
return MenuState.HEADER_ONLY;
|
||||
}
|
||||
|
||||
protected int getSupportedMenuStatesPortrait() {
|
||||
return MenuState.HEADER_ONLY | MenuState.HALF_SCREEN | MenuState.FULL_SCREEN;
|
||||
}
|
||||
|
||||
public int getCurrentMenuState() {
|
||||
return currentMenuState;
|
||||
}
|
||||
|
||||
public MenuType getMenuType() {
|
||||
return menuType;
|
||||
}
|
||||
|
||||
public boolean slideUp() {
|
||||
int v = currentMenuState;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
v = v << 1;
|
||||
if ((v & getSupportedMenuStates()) != 0) {
|
||||
currentMenuState = v;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean slideDown() {
|
||||
int v = currentMenuState;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
v = v >> 1;
|
||||
if ((v & getSupportedMenuStates()) != 0) {
|
||||
currentMenuState = v;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setCurrentMenuState(int currentMenuState) {
|
||||
this.currentMenuState = currentMenuState;
|
||||
}
|
||||
|
||||
public TitleButtonController getLeftTitleButtonController() {
|
||||
return leftTitleButtonController;
|
||||
}
|
||||
|
||||
public TitleButtonController getRightTitleButtonController() {
|
||||
return rightTitleButtonController;
|
||||
}
|
||||
|
||||
public TitleButtonController getTopRightTitleButtonController() {
|
||||
return topRightTitleButtonController;
|
||||
}
|
||||
|
||||
/*
|
||||
public TopToolbarController getToolbarController() {
|
||||
return toolbarController;
|
||||
}
|
||||
|
||||
public boolean hasBackAction() {
|
||||
return toolbarController != null;
|
||||
}
|
||||
*/
|
||||
|
||||
public LatLon getLatLon() {
|
||||
return latLon;
|
||||
}
|
||||
|
||||
public boolean supportZoomIn() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean fabVisible() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean buttonsVisible() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean handleSingleTapOnMap() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean needStreetName() {
|
||||
return !displayDistanceDirection();
|
||||
}
|
||||
|
||||
public boolean needTypeStr() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean displayStreetNameInTitle() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean displayDistanceDirection() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getLeftIconId() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Drawable getLeftIcon() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Drawable getSecondLineTypeIcon() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getTypeStr() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public String getCommonTypeStr() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public String getNameStr() {
|
||||
return pointDescription.getName();
|
||||
}
|
||||
|
||||
public boolean hasCustomAddressLine() {
|
||||
return builder.hasCustomAddressLine();
|
||||
}
|
||||
|
||||
public void buildCustomAddressLine(LinearLayout ll) {
|
||||
builder.buildCustomAddressLine(ll);
|
||||
}
|
||||
|
||||
public abstract class TitleButtonController {
|
||||
public String caption = "";
|
||||
public int leftIconId = 0;
|
||||
public boolean needRightText = false;
|
||||
public String rightTextCaption = "";
|
||||
public boolean visible = true;
|
||||
|
||||
public Drawable getLeftIcon() {
|
||||
if (leftIconId != 0) {
|
||||
return getIcon(leftIconId, isLight() ? R.color.map_widget_blue : R.color.osmand_orange);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void buttonPressed();
|
||||
}
|
||||
|
||||
public void onShow() {
|
||||
/*
|
||||
if (toolbarController != null) {
|
||||
getMainActivity().showTopToolbar(toolbarController);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
public void onHide() {
|
||||
}
|
||||
|
||||
public void onClose() {
|
||||
/*
|
||||
if (toolbarController != null) {
|
||||
getMainActivity().hideTopToolbar(toolbarController);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
public void onAcquireNewController(PointDescription pointDescription, Object object) {
|
||||
}
|
||||
|
||||
public void setLatLon(@NonNull LatLon latLon) {
|
||||
this.latLon = latLon;
|
||||
}
|
||||
|
||||
/*
|
||||
public static class ContextMenuToolbarController extends TopToolbarController {
|
||||
|
||||
private MenuController menuController;
|
||||
|
||||
public ContextMenuToolbarController(MenuController menuController) {
|
||||
super(TopToolbarControllerType.CONTEXT_MENU);
|
||||
this.menuController = menuController;
|
||||
}
|
||||
|
||||
public MenuController getMenuController() {
|
||||
return menuController;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
public static int getObjectPriority(Object o) {
|
||||
if (o instanceof Amenity) {
|
||||
return 100;
|
||||
}
|
||||
return 1000;
|
||||
}
|
||||
|
||||
public static LatLon getObjectLocation(Object o) {
|
||||
if (o instanceof Amenity) {
|
||||
return ((Amenity) o).getLocation();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static PointDescription getObjectName(Object o) {
|
||||
if (o instanceof Amenity) {
|
||||
return new PointDescription(PointDescription.POINT_TYPE_POI, ((Amenity) o).getName(
|
||||
SampleApplication.LANGUAGE, SampleApplication.TRANSLITERATE));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,192 @@
|
|||
package net.osmand.core.samples.android.sample1.mapcontextmenu;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import net.osmand.core.samples.android.sample1.GeocodingLookupService;
|
||||
import net.osmand.core.samples.android.sample1.GeocodingLookupService.AddressLookupRequest;
|
||||
import net.osmand.core.samples.android.sample1.MainActivity;
|
||||
import net.osmand.core.samples.android.sample1.data.PointDescription;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
public abstract class MenuTitleController {
|
||||
|
||||
protected int leftIconId;
|
||||
protected Drawable leftIcon;
|
||||
protected String nameStr = "";
|
||||
protected String typeStr = "";
|
||||
protected String commonTypeStr = "";
|
||||
protected Drawable secondLineTypeIcon;
|
||||
protected String streetStr = "";
|
||||
|
||||
private AddressLookupRequest addressLookupRequest;
|
||||
|
||||
protected String searchAddressStr;
|
||||
protected String addressNotFoundStr;
|
||||
|
||||
public abstract MainActivity getMainActivity();
|
||||
|
||||
public abstract LatLon getLatLon();
|
||||
|
||||
public abstract PointDescription getPointDescription();
|
||||
|
||||
public abstract Object getObject();
|
||||
|
||||
public abstract MenuController getMenuController();
|
||||
|
||||
public String getTitleStr() {
|
||||
if (displayStreetNameInTitle() && searchingAddress()) {
|
||||
return searchAddressStr;
|
||||
} else {
|
||||
return nameStr;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean searchingAddress() {
|
||||
return addressLookupRequest != null;
|
||||
}
|
||||
|
||||
public void cancelSearchAddress() {
|
||||
if (addressLookupRequest != null) {
|
||||
getMainActivity().getMyApplication().getGeocodingLookupService().cancel(addressLookupRequest);
|
||||
addressLookupRequest = null;
|
||||
onSearchAddressDone();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean displayStreetNameInTitle() {
|
||||
MenuController menuController = getMenuController();
|
||||
return menuController != null && menuController.displayStreetNameInTitle();
|
||||
}
|
||||
|
||||
// Has title which does not equal to "Looking up address" and "No address determined"
|
||||
public boolean hasValidTitle() {
|
||||
String title = getTitleStr();
|
||||
return !addressNotFoundStr.equals(title) && !searchAddressStr.equals(title);
|
||||
}
|
||||
|
||||
public int getLeftIconId() {
|
||||
return leftIconId;
|
||||
}
|
||||
|
||||
public Drawable getLeftIcon() {
|
||||
return leftIcon;
|
||||
}
|
||||
|
||||
public Drawable getTypeIcon() {
|
||||
return secondLineTypeIcon;
|
||||
}
|
||||
|
||||
public String getTypeStr() {
|
||||
MenuController menuController = getMenuController();
|
||||
if (menuController != null && menuController.needTypeStr()) {
|
||||
return typeStr;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public String getStreetStr() {
|
||||
if (needStreetName()) {
|
||||
if (searchingAddress()) {
|
||||
return searchAddressStr;
|
||||
} else {
|
||||
return streetStr;
|
||||
}
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
protected void initTitle() {
|
||||
searchAddressStr = PointDescription.getSearchAddressStr(getMainActivity().getMyApplication());
|
||||
addressNotFoundStr = PointDescription.getAddressNotFoundStr(getMainActivity().getMyApplication());
|
||||
|
||||
if (searchingAddress()) {
|
||||
cancelSearchAddress();
|
||||
}
|
||||
|
||||
acquireIcons();
|
||||
acquireNameAndType();
|
||||
if (needStreetName()) {
|
||||
acquireStreetName();
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean needStreetName() {
|
||||
MenuController menuController = getMenuController();
|
||||
boolean res = getObject() != null || Algorithms.isEmpty(getPointDescription().getName());
|
||||
if (res && menuController != null) {
|
||||
res = menuController.needStreetName();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
protected void acquireIcons() {
|
||||
MenuController menuController = getMenuController();
|
||||
|
||||
leftIconId = 0;
|
||||
leftIcon = null;
|
||||
secondLineTypeIcon = null;
|
||||
|
||||
if (menuController != null) {
|
||||
leftIconId = menuController.getLeftIconId();
|
||||
leftIcon = menuController.getLeftIcon();
|
||||
secondLineTypeIcon = menuController.getSecondLineTypeIcon();
|
||||
}
|
||||
}
|
||||
|
||||
protected void acquireNameAndType() {
|
||||
nameStr = "";
|
||||
typeStr = "";
|
||||
commonTypeStr = "";
|
||||
streetStr = "";
|
||||
|
||||
MenuController menuController = getMenuController();
|
||||
if (menuController != null) {
|
||||
nameStr = menuController.getNameStr();
|
||||
typeStr = menuController.getTypeStr();
|
||||
commonTypeStr = menuController.getCommonTypeStr();
|
||||
}
|
||||
|
||||
if (Algorithms.isEmpty(nameStr)) {
|
||||
nameStr = typeStr;
|
||||
typeStr = commonTypeStr;
|
||||
} else if (Algorithms.isEmpty(typeStr)) {
|
||||
typeStr = commonTypeStr;
|
||||
}
|
||||
}
|
||||
|
||||
protected void acquireStreetName() {
|
||||
addressLookupRequest = new AddressLookupRequest(getLatLon(), new GeocodingLookupService.OnAddressLookupResult() {
|
||||
@Override
|
||||
public void geocodingDone(String address) {
|
||||
if (addressLookupRequest != null) {
|
||||
addressLookupRequest = null;
|
||||
if (Algorithms.isEmpty(address)) {
|
||||
streetStr = PointDescription.getAddressNotFoundStr(getMainActivity().getMyApplication());
|
||||
} else {
|
||||
streetStr = address;
|
||||
}
|
||||
|
||||
if (displayStreetNameInTitle()) {
|
||||
nameStr = streetStr;
|
||||
getPointDescription().setName(nameStr);
|
||||
}
|
||||
onSearchAddressDone();
|
||||
}
|
||||
}
|
||||
}, new GeocodingLookupService.OnAddressLookupProgress() {
|
||||
@Override
|
||||
public void geocodingInProgress() {
|
||||
// animate three dots
|
||||
}
|
||||
});
|
||||
|
||||
getMainActivity().getMyApplication().getGeocodingLookupService().lookupAddress(addressLookupRequest);
|
||||
}
|
||||
|
||||
protected void onSearchAddressDone() {
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,625 @@
|
|||
package net.osmand.core.samples.android.sample1.mapcontextmenu.builders;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.view.ContextThemeWrapper;
|
||||
import android.support.v7.widget.AppCompatButton;
|
||||
import android.text.Html;
|
||||
import android.text.SpannableString;
|
||||
import android.text.TextUtils;
|
||||
import android.text.style.URLSpan;
|
||||
import android.text.util.Linkify;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.core.samples.android.sample1.MainActivity;
|
||||
import net.osmand.core.samples.android.sample1.OsmandResources;
|
||||
import net.osmand.core.samples.android.sample1.R;
|
||||
import net.osmand.core.samples.android.sample1.SampleApplication;
|
||||
import net.osmand.core.samples.android.sample1.data.PointDescription;
|
||||
import net.osmand.core.samples.android.sample1.mapcontextmenu.ContextMenuHelper;
|
||||
import net.osmand.core.samples.android.sample1.mapcontextmenu.MenuBuilder;
|
||||
import net.osmand.core.samples.android.sample1.mapcontextmenu.MenuController;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.QuadRect;
|
||||
import net.osmand.osm.AbstractPoiType;
|
||||
import net.osmand.osm.MapPoiTypes;
|
||||
import net.osmand.osm.PoiType;
|
||||
import net.osmand.util.Algorithms;
|
||||
import net.osmand.util.MapUtils;
|
||||
import net.osmand.util.OpeningHoursParser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class AmenityMenuBuilder extends MenuBuilder {
|
||||
|
||||
private final Amenity amenity;
|
||||
private List<Amenity> nearestWiki = new ArrayList<>();
|
||||
|
||||
public AmenityMenuBuilder(MainActivity mainActivity, final Amenity amenity) {
|
||||
super(mainActivity);
|
||||
this.amenity = amenity;
|
||||
processNearstWiki();
|
||||
}
|
||||
|
||||
private void buildRow(View view, int iconId, String text, String textPrefix,
|
||||
boolean collapsable, final View collapsableView,
|
||||
int textColor, boolean isWiki, boolean isText, boolean needLinks,
|
||||
boolean isPhoneNumber, boolean isUrl) {
|
||||
buildRow(view, getRowIcon(iconId), text, textPrefix, collapsable, collapsableView, textColor,
|
||||
isWiki, isText, needLinks, isPhoneNumber, isUrl);
|
||||
}
|
||||
|
||||
protected void buildRow(final View view, Drawable icon, final String text, final String textPrefix,
|
||||
boolean collapsable, final View collapsableView,
|
||||
int textColor, boolean isWiki, boolean isText, boolean needLinks,
|
||||
boolean isPhoneNumber, boolean isUrl) {
|
||||
|
||||
if (!isFirstRow()) {
|
||||
buildRowDivider(view, false);
|
||||
}
|
||||
|
||||
final String txt;
|
||||
if (!Algorithms.isEmpty(textPrefix)) {
|
||||
txt = textPrefix + ": " + text;
|
||||
} else {
|
||||
txt = text;
|
||||
}
|
||||
|
||||
LinearLayout baseView = new LinearLayout(view.getContext());
|
||||
baseView.setOrientation(LinearLayout.VERTICAL);
|
||||
LinearLayout.LayoutParams llBaseViewParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
baseView.setLayoutParams(llBaseViewParams);
|
||||
|
||||
LinearLayout ll = new LinearLayout(view.getContext());
|
||||
ll.setOrientation(LinearLayout.HORIZONTAL);
|
||||
LinearLayout.LayoutParams llParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
ll.setLayoutParams(llParams);
|
||||
ll.setBackgroundResource(resolveAttribute(view.getContext(), android.R.attr.selectableItemBackground));
|
||||
ll.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
copyToClipboard(txt, view.getContext());
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
baseView.addView(ll);
|
||||
|
||||
// Icon
|
||||
LinearLayout llIcon = new LinearLayout(view.getContext());
|
||||
llIcon.setOrientation(LinearLayout.HORIZONTAL);
|
||||
llIcon.setLayoutParams(new LinearLayout.LayoutParams(dpToPx(72f), dpToPx(48f)));
|
||||
llIcon.setGravity(Gravity.CENTER_VERTICAL);
|
||||
ll.addView(llIcon);
|
||||
|
||||
ImageView iconView = new ImageView(view.getContext());
|
||||
LinearLayout.LayoutParams llIconParams = new LinearLayout.LayoutParams(dpToPx(24f), dpToPx(24f));
|
||||
llIconParams.setMargins(dpToPx(16f), dpToPx(12f), dpToPx(32f), dpToPx(12f));
|
||||
llIconParams.gravity = Gravity.CENTER_VERTICAL;
|
||||
iconView.setLayoutParams(llIconParams);
|
||||
iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
|
||||
iconView.setImageDrawable(icon);
|
||||
llIcon.addView(iconView);
|
||||
|
||||
// Text
|
||||
LinearLayout llText = new LinearLayout(view.getContext());
|
||||
llText.setOrientation(LinearLayout.VERTICAL);
|
||||
ll.addView(llText);
|
||||
|
||||
TextView textView = new TextView(view.getContext());
|
||||
LinearLayout.LayoutParams llTextParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
llTextParams.setMargins(0, collapsable ? dpToPx(13f) : dpToPx(8f), 0, collapsable ? dpToPx(13f) : dpToPx(8f));
|
||||
textView.setLayoutParams(llTextParams);
|
||||
textView.setTextSize(16);
|
||||
textView.setTextColor(app.getResources().getColor(light ? R.color.ctx_menu_info_text_light : R.color.ctx_menu_info_text_dark));
|
||||
|
||||
boolean textDefined = false;
|
||||
if (isPhoneNumber || isUrl) {
|
||||
if (!Algorithms.isEmpty(textPrefix)) {
|
||||
SpannableString spannableString = new SpannableString(txt);
|
||||
spannableString.setSpan(new URLSpan(txt), textPrefix.length() + 2, txt.length(), 0);
|
||||
textView.setText(spannableString);
|
||||
textDefined = true;
|
||||
} else {
|
||||
textView.setTextColor(textView.getLinkTextColors());
|
||||
}
|
||||
} else if (needLinks) {
|
||||
textView.setAutoLinkMask(Linkify.ALL);
|
||||
textView.setLinksClickable(true);
|
||||
}
|
||||
textView.setEllipsize(TextUtils.TruncateAt.END);
|
||||
if (isWiki) {
|
||||
textView.setMinLines(1);
|
||||
textView.setMaxLines(15);
|
||||
} else if (isText) {
|
||||
textView.setMinLines(1);
|
||||
textView.setMaxLines(10);
|
||||
}
|
||||
if (!textDefined) {
|
||||
textView.setText(txt);
|
||||
}
|
||||
if (textColor > 0) {
|
||||
textView.setTextColor(view.getResources().getColor(textColor));
|
||||
}
|
||||
|
||||
LinearLayout.LayoutParams llTextViewParams = new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
llTextViewParams.weight = 1f;
|
||||
llTextViewParams.setMargins(0, 0, dpToPx(10f), 0);
|
||||
llTextViewParams.gravity = Gravity.CENTER_VERTICAL;
|
||||
llText.setLayoutParams(llTextViewParams);
|
||||
llText.addView(textView);
|
||||
|
||||
final ImageView iconViewCollapse = new ImageView(view.getContext());
|
||||
if (collapsable && collapsableView != null) {
|
||||
// Icon
|
||||
LinearLayout llIconCollapse = new LinearLayout(view.getContext());
|
||||
llIconCollapse.setLayoutParams(new LinearLayout.LayoutParams(dpToPx(40f), dpToPx(48f)));
|
||||
llIconCollapse.setOrientation(LinearLayout.HORIZONTAL);
|
||||
llIconCollapse.setGravity(Gravity.CENTER_VERTICAL);
|
||||
ll.addView(llIconCollapse);
|
||||
|
||||
LinearLayout.LayoutParams llIconCollapseParams = new LinearLayout.LayoutParams(dpToPx(24f), dpToPx(24f));
|
||||
llIconCollapseParams.setMargins(0, dpToPx(12f), dpToPx(32f), dpToPx(12f));
|
||||
llIconCollapseParams.gravity = Gravity.CENTER_VERTICAL;
|
||||
iconViewCollapse.setLayoutParams(llIconCollapseParams);
|
||||
iconViewCollapse.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
|
||||
iconViewCollapse.setImageDrawable(app.getIconsCache().getThemedIcon(collapsableView.getVisibility() == View.GONE ?
|
||||
"ic_action_arrow_down" : "ic_action_arrow_up"));
|
||||
llIconCollapse.addView(iconViewCollapse);
|
||||
ll.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (collapsableView.getVisibility() == View.VISIBLE) {
|
||||
collapsableView.setVisibility(View.GONE);
|
||||
iconViewCollapse.setImageDrawable(app.getIconsCache().getThemedIcon("ic_action_arrow_down"));
|
||||
} else {
|
||||
collapsableView.setVisibility(View.VISIBLE);
|
||||
iconViewCollapse.setImageDrawable(app.getIconsCache().getThemedIcon("ic_action_arrow_up"));
|
||||
}
|
||||
}
|
||||
});
|
||||
baseView.addView(collapsableView);
|
||||
}
|
||||
|
||||
if (isWiki) {
|
||||
AppCompatButton wikiButton = new AppCompatButton(view.getContext());
|
||||
LinearLayout.LayoutParams llWikiButtonParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
llWikiButtonParams.setMargins(0, dpToPx(10f), dpToPx(2f), dpToPx(10f));
|
||||
wikiButton.setLayoutParams(llWikiButtonParams);
|
||||
wikiButton.setPadding(dpToPx(14f), 0, dpToPx(14f), 0);
|
||||
wikiButton.setBackgroundResource(R.drawable.blue_button_drawable);
|
||||
wikiButton.setTextColor(Color.WHITE);
|
||||
wikiButton.setText(app.getString("read_more"));
|
||||
wikiButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
ContextMenuHelper.showWikipediaDialog(view.getContext(), app, amenity);
|
||||
}
|
||||
});
|
||||
llText.addView(wikiButton);
|
||||
}
|
||||
|
||||
((LinearLayout) view).addView(baseView);
|
||||
|
||||
if (isPhoneNumber) {
|
||||
ll.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(final View v) {
|
||||
final String[] phones = text.split(",|;");
|
||||
if (phones.length > 1) {
|
||||
AlertDialog.Builder dlg = new AlertDialog.Builder(v.getContext());
|
||||
dlg.setNegativeButton(R.string.shared_string_cancel, null);
|
||||
dlg.setItems(phones, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
Intent intent = new Intent(Intent.ACTION_DIAL);
|
||||
intent.setData(Uri.parse("tel:" + phones[which]));
|
||||
v.getContext().startActivity(intent);
|
||||
}
|
||||
});
|
||||
dlg.show();
|
||||
} else {
|
||||
Intent intent = new Intent(Intent.ACTION_DIAL);
|
||||
intent.setData(Uri.parse("tel:" + text));
|
||||
v.getContext().startActivity(intent);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if (isUrl) {
|
||||
ll.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setData(Uri.parse(text));
|
||||
v.getContext().startActivity(intent);
|
||||
}
|
||||
});
|
||||
} else if (isWiki) {
|
||||
ll.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
ContextMenuHelper.showWikipediaDialog(view.getContext(), app, amenity);
|
||||
}
|
||||
});
|
||||
} else if (isText && text.length() > 200) {
|
||||
ll.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
ContextMenuHelper.showDescriptionDialog(view.getContext(), app, text, textPrefix);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
rowBuilt();
|
||||
}
|
||||
|
||||
private View getCollapsableTextView(Context context, boolean collapsed, String text) {
|
||||
final TextView textView = new TextView(context);
|
||||
textView.setVisibility(collapsed ? View.GONE : View.VISIBLE);
|
||||
LinearLayout.LayoutParams llTextDescParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
llTextDescParams.setMargins(dpToPx(72f), 0, dpToPx(40f), dpToPx(13f));
|
||||
textView.setLayoutParams(llTextDescParams);
|
||||
textView.setTextSize(16);
|
||||
textView.setTextColor(app.getResources().getColor(light ? R.color.ctx_menu_info_text_light : R.color.ctx_menu_info_text_dark));
|
||||
textView.setText(text);
|
||||
return textView;
|
||||
}
|
||||
|
||||
private View getCollapsableWikiView(Context context, boolean collapsed) {
|
||||
final LinearLayout view = new LinearLayout(context);
|
||||
view.setOrientation(LinearLayout.VERTICAL);
|
||||
view.setVisibility(collapsed ? View.GONE : View.VISIBLE);
|
||||
LinearLayout.LayoutParams llParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
llParams.setMargins(dpToPx(68f), 0, dpToPx(12f), dpToPx(13f));
|
||||
view.setLayoutParams(llParams);
|
||||
|
||||
for (final Amenity wiki : nearestWiki) {
|
||||
AppCompatButton wikiButton = new AppCompatButton(
|
||||
new ContextThemeWrapper(view.getContext(), R.style.AppTheme));
|
||||
LinearLayout.LayoutParams llWikiButtonParams =
|
||||
new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
wikiButton.setLayoutParams(llWikiButtonParams);
|
||||
wikiButton.setPadding(dpToPx(14f), 0, dpToPx(14f), 0);
|
||||
wikiButton.setTextColor(app.getResources()
|
||||
.getColor(light ? R.color.color_dialog_buttons_light : R.color.color_dialog_buttons_dark));
|
||||
wikiButton.setText(wiki.getName());
|
||||
|
||||
wikiButton.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
|
||||
wikiButton.setSingleLine(true);
|
||||
wikiButton.setEllipsize(TextUtils.TruncateAt.END);
|
||||
wikiButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
PointDescription pointDescription = MenuController.getObjectName(wiki);
|
||||
mainActivity.getContextMenu().show(
|
||||
new LatLon(wiki.getLocation().getLatitude(), wiki.getLocation().getLongitude()),
|
||||
pointDescription, wiki);
|
||||
}
|
||||
});
|
||||
view.addView(wikiButton);
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildInternal(View view) {
|
||||
boolean hasWiki = false;
|
||||
MapPoiTypes poiTypes = app.getPoiTypes();
|
||||
String preferredLang = SampleApplication.LANGUAGE;
|
||||
List<AmenityInfoRow> infoRows = new LinkedList<>();
|
||||
List<AmenityInfoRow> descriptions = new LinkedList<>();
|
||||
|
||||
for (Map.Entry<String, String> e : amenity.getAdditionalInfo().entrySet()) {
|
||||
int iconId;
|
||||
Drawable icon = null;
|
||||
int textColor = 0;
|
||||
String key = e.getKey();
|
||||
String vl = e.getValue();
|
||||
|
||||
String textPrefix = "";
|
||||
View collapsableView = null;
|
||||
boolean collapsable = false;
|
||||
boolean isWiki = false;
|
||||
boolean isText = false;
|
||||
boolean isDescription = false;
|
||||
boolean needLinks = !"population".equals(key);
|
||||
boolean isPhoneNumber = false;
|
||||
boolean isUrl = false;
|
||||
int poiTypeOrder = 0;
|
||||
String poiTypeKeyName = "";
|
||||
|
||||
AbstractPoiType pt = poiTypes.getAnyPoiAdditionalTypeByKey(key);
|
||||
if (pt == null && !Algorithms.isEmpty(vl) && vl.length() < 50) {
|
||||
pt = poiTypes.getAnyPoiAdditionalTypeByKey(key + "_" + vl);
|
||||
}
|
||||
PoiType pType = null;
|
||||
if (pt != null) {
|
||||
pType = (PoiType) pt;
|
||||
if (pType.isFilterOnly()) {
|
||||
continue;
|
||||
}
|
||||
poiTypeOrder = pType.getOrder();
|
||||
poiTypeKeyName = pType.getKeyName();
|
||||
}
|
||||
|
||||
if (amenity.getType().isWiki()) {
|
||||
if (!hasWiki) {
|
||||
iconId = OsmandResources.getDrawableId("ic_action_note_dark");
|
||||
String lng = amenity.getContentSelected("content", preferredLang, "en");
|
||||
if (Algorithms.isEmpty(lng)) {
|
||||
lng = "en";
|
||||
}
|
||||
|
||||
final String langSelected = lng;
|
||||
String content = amenity.getDescription(langSelected);
|
||||
vl = Html.fromHtml(content).toString();
|
||||
if (vl.length() > 300) {
|
||||
vl = vl.substring(0, 300);
|
||||
}
|
||||
hasWiki = true;
|
||||
isWiki = true;
|
||||
needLinks = false;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
} else if (key.startsWith("name:")) {
|
||||
continue;
|
||||
} else if (Amenity.OPENING_HOURS.equals(key)) {
|
||||
iconId = OsmandResources.getDrawableId("ic_action_time");
|
||||
collapsableView = getCollapsableTextView(view.getContext(), true, amenity.getOpeningHours());
|
||||
collapsable = true;
|
||||
OpeningHoursParser.OpeningHours rs = OpeningHoursParser.parseOpenedHours(amenity.getOpeningHours());
|
||||
if (rs != null) {
|
||||
vl = rs.toLocalString();
|
||||
Calendar inst = Calendar.getInstance();
|
||||
inst.setTimeInMillis(System.currentTimeMillis());
|
||||
boolean opened = rs.isOpenedForTime(inst);
|
||||
if (opened) {
|
||||
textColor = R.color.color_ok;
|
||||
} else {
|
||||
textColor = R.color.color_invalid;
|
||||
}
|
||||
}
|
||||
needLinks = false;
|
||||
|
||||
} else if (Amenity.PHONE.equals(key)) {
|
||||
iconId = OsmandResources.getDrawableId("ic_action_call_dark");
|
||||
isPhoneNumber = true;
|
||||
} else if (Amenity.WEBSITE.equals(key)) {
|
||||
iconId = OsmandResources.getDrawableId("ic_world_globe_dark");
|
||||
isUrl = true;
|
||||
} else if (Amenity.CUISINE.equals(key)) {
|
||||
iconId = OsmandResources.getDrawableId("ic_action_cuisine");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String c : e.getValue().split(";")) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append(", ");
|
||||
} else {
|
||||
sb.append(app.getString("poi_cuisine")).append(": ");
|
||||
}
|
||||
sb.append(poiTypes.getPoiTranslation("cuisine_" + c).toLowerCase());
|
||||
}
|
||||
vl = sb.toString();
|
||||
} else {
|
||||
if (key.contains(Amenity.DESCRIPTION)) {
|
||||
iconId = OsmandResources.getDrawableId("ic_action_note_dark");
|
||||
} else {
|
||||
iconId = OsmandResources.getDrawableId("ic_action_info_dark");
|
||||
}
|
||||
if (pType != null) {
|
||||
poiTypeOrder = pType.getOrder();
|
||||
poiTypeKeyName = pType.getKeyName();
|
||||
if (pType.getParentType() != null && pType.getParentType() instanceof PoiType) {
|
||||
icon = getRowIcon(view.getContext(), ((PoiType) pType.getParentType()).getOsmTag() + "_" + pType.getOsmTag().replace(':', '_') + "_" + pType.getOsmValue());
|
||||
}
|
||||
if (!pType.isText()) {
|
||||
if (!Algorithms.isEmpty(pType.getPoiAdditionalCategory())) {
|
||||
vl = pType.getPoiAdditionalCategoryTranslation() + ": " + pType.getTranslation().toLowerCase();
|
||||
} else {
|
||||
vl = pType.getTranslation();
|
||||
}
|
||||
} else {
|
||||
isText = true;
|
||||
isDescription = iconId == OsmandResources.getDrawableId("ic_action_note_dark");
|
||||
textPrefix = pType.getTranslation();
|
||||
vl = amenity.unzipContent(e.getValue());
|
||||
}
|
||||
if (!isDescription && icon == null) {
|
||||
icon = getRowIcon(view.getContext(), pType.getIconKeyName());
|
||||
if (isText && icon != null) {
|
||||
textPrefix = "";
|
||||
}
|
||||
}
|
||||
if (icon == null && isText) {
|
||||
iconId = OsmandResources.getDrawableId("ic_action_note_dark");
|
||||
}
|
||||
} else {
|
||||
textPrefix = Algorithms.capitalizeFirstLetterAndLowercase(e.getKey());
|
||||
vl = amenity.unzipContent(e.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
if (vl.startsWith("http://") || vl.startsWith("https://") || vl.startsWith("HTTP://") || vl.startsWith("HTTPS://")) {
|
||||
isUrl = true;
|
||||
}
|
||||
|
||||
if (isDescription) {
|
||||
descriptions.add(new AmenityInfoRow(key, OsmandResources.getDrawableId("ic_action_note_dark"), textPrefix,
|
||||
vl, collapsable, collapsableView, 0, false, true, true, 0, "", false, false));
|
||||
} else if (icon != null) {
|
||||
infoRows.add(new AmenityInfoRow(key, icon, textPrefix, vl, collapsable, collapsableView,
|
||||
textColor, isWiki, isText, needLinks, poiTypeOrder, poiTypeKeyName, isPhoneNumber, isUrl));
|
||||
} else {
|
||||
infoRows.add(new AmenityInfoRow(key, iconId, textPrefix, vl, collapsable, collapsableView,
|
||||
textColor, isWiki, isText, needLinks, poiTypeOrder, poiTypeKeyName, isPhoneNumber, isUrl));
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(infoRows, new Comparator<AmenityInfoRow>() {
|
||||
@Override
|
||||
public int compare(AmenityInfoRow row1, AmenityInfoRow row2) {
|
||||
if (row1.order < row2.order) {
|
||||
return -1;
|
||||
} else if (row1.order == row2.order) {
|
||||
return row1.name.compareTo(row2.name);
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
for (AmenityInfoRow info : infoRows) {
|
||||
buildAmenityRow(view, info);
|
||||
}
|
||||
|
||||
String langSuffix = ":" + preferredLang;
|
||||
AmenityInfoRow descInPrefLang = null;
|
||||
for (AmenityInfoRow desc : descriptions) {
|
||||
if (desc.key.length() > langSuffix.length()
|
||||
&& desc.key.substring(desc.key.length() - langSuffix.length(), desc.key.length()).equals(langSuffix)) {
|
||||
descInPrefLang = desc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (descInPrefLang != null) {
|
||||
descriptions.remove(descInPrefLang);
|
||||
descriptions.add(0, descInPrefLang);
|
||||
}
|
||||
|
||||
for (AmenityInfoRow info : descriptions) {
|
||||
buildAmenityRow(view, info);
|
||||
}
|
||||
|
||||
if (nearestWiki.size() > 0) {
|
||||
AmenityInfoRow wikiInfo = new AmenityInfoRow(
|
||||
"nearest_wiki", OsmandResources.getDrawableId("ic_action_wikipedia"), null, app.getString("wiki_around") + " (" + nearestWiki.size()+")", true,
|
||||
getCollapsableWikiView(view.getContext(), true),
|
||||
0, false, false, false, 1000, null, false, false);
|
||||
buildAmenityRow(view, wikiInfo);
|
||||
}
|
||||
|
||||
buildRow(view, OsmandResources.getDrawableId("ic_action_get_my_location"), PointDescription.getLocationName(app,
|
||||
amenity.getLocation().getLatitude(), amenity.getLocation().getLongitude(), true)
|
||||
.replaceAll("\n", " "), 0, false, 0, false, null);
|
||||
}
|
||||
|
||||
public void buildAmenityRow(View view, AmenityInfoRow info) {
|
||||
if (info.icon != null) {
|
||||
buildRow(view, info.icon, info.text, info.textPrefix, info.collapsable, info.collapsableView,
|
||||
info.textColor, info.isWiki, info.isText, info.needLinks, info.isPhoneNumber, info.isUrl);
|
||||
} else if (info.iconId != 0) {
|
||||
buildRow(view, info.iconId, info.text, info.textPrefix, info.collapsable, info.collapsableView,
|
||||
info.textColor, info.isWiki, info.isText, info.needLinks, info.isPhoneNumber, info.isUrl);
|
||||
}
|
||||
}
|
||||
|
||||
private void processNearstWiki() {
|
||||
QuadRect rect = MapUtils.calculateLatLonBbox(
|
||||
amenity.getLocation().getLatitude(), amenity.getLocation().getLongitude(), 250);
|
||||
/* todo
|
||||
nearestWiki = app.getResourceManager().searchAmenities(
|
||||
new BinaryMapIndexReader.SearchPoiTypeFilter() {
|
||||
@Override
|
||||
public boolean accept(PoiCategory type, String subcategory) {
|
||||
return type.isWiki();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return false;
|
||||
}
|
||||
}, rect.top, rect.left, rect.bottom, rect.right, -1, null);
|
||||
Collections.sort(nearestWiki, new Comparator<Amenity>() {
|
||||
|
||||
@Override
|
||||
public int compare(Amenity o1, Amenity o2) {
|
||||
double d1 = MapUtils.getDistance(amenity.getLocation(), o1.getLocation());
|
||||
double d2 = MapUtils.getDistance(amenity.getLocation(), o2.getLocation());
|
||||
return Double.compare(d1, d2);
|
||||
}
|
||||
});
|
||||
for (Amenity wiki : nearestWiki) {
|
||||
if (wiki.getId().equals(amenity.getId())) {
|
||||
nearestWiki.remove(wiki);
|
||||
break;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
private static class AmenityInfoRow {
|
||||
private String key;
|
||||
private Drawable icon;
|
||||
private int iconId;
|
||||
private String textPrefix;
|
||||
private String text;
|
||||
private View collapsableView;
|
||||
private boolean collapsable;
|
||||
private int textColor;
|
||||
private boolean isWiki;
|
||||
private boolean isText;
|
||||
private boolean needLinks;
|
||||
private boolean isPhoneNumber;
|
||||
private boolean isUrl;
|
||||
private int order;
|
||||
private String name;
|
||||
|
||||
public AmenityInfoRow(String key, Drawable icon, String textPrefix, String text,
|
||||
boolean collapsable, View collapsableView,
|
||||
int textColor, boolean isWiki, boolean isText, boolean needLinks,
|
||||
int order, String name, boolean isPhoneNumber, boolean isUrl) {
|
||||
this.key = key;
|
||||
this.icon = icon;
|
||||
this.textPrefix = textPrefix;
|
||||
this.text = text;
|
||||
this.collapsable = collapsable;
|
||||
this.collapsableView = collapsableView;
|
||||
this.textColor = textColor;
|
||||
this.isWiki = isWiki;
|
||||
this.isText = isText;
|
||||
this.needLinks = needLinks;
|
||||
this.order = order;
|
||||
this.name = name;
|
||||
this.isPhoneNumber = isPhoneNumber;
|
||||
this.isUrl = isUrl;
|
||||
}
|
||||
|
||||
public AmenityInfoRow(String key, int iconId, String textPrefix, String text,
|
||||
boolean collapsable, View collapsableView,
|
||||
int textColor, boolean isWiki, boolean isText, boolean needLinks,
|
||||
int order, String name, boolean isPhoneNumber, boolean isUrl) {
|
||||
this.key = key;
|
||||
this.iconId = iconId;
|
||||
this.textPrefix = textPrefix;
|
||||
this.text = text;
|
||||
this.collapsable = collapsable;
|
||||
this.collapsableView = collapsableView;
|
||||
this.textColor = textColor;
|
||||
this.isWiki = isWiki;
|
||||
this.isText = isText;
|
||||
this.needLinks = needLinks;
|
||||
this.order = order;
|
||||
this.name = name;
|
||||
this.isPhoneNumber = isPhoneNumber;
|
||||
this.isUrl = isUrl;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
package net.osmand.core.samples.android.sample1.mapcontextmenu.controllers;
|
||||
|
||||
import net.osmand.core.samples.android.sample1.MainActivity;
|
||||
import net.osmand.core.samples.android.sample1.OsmandResources;
|
||||
import net.osmand.core.samples.android.sample1.data.PointDescription;
|
||||
import net.osmand.core.samples.android.sample1.mapcontextmenu.MenuBuilder;
|
||||
import net.osmand.core.samples.android.sample1.mapcontextmenu.MenuController;
|
||||
import net.osmand.core.samples.android.sample1.mapcontextmenu.builders.AmenityMenuBuilder;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.osm.PoiCategory;
|
||||
import net.osmand.osm.PoiType;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
public class AmenityMenuController extends MenuController {
|
||||
|
||||
private Amenity amenity;
|
||||
|
||||
public AmenityMenuController(MainActivity mainActivity, PointDescription pointDescription, Amenity amenity) {
|
||||
super(new AmenityMenuBuilder(mainActivity, amenity), pointDescription, mainActivity);
|
||||
this.amenity = amenity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setObject(Object object) {
|
||||
if (object instanceof Amenity) {
|
||||
this.amenity = (Amenity) object;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getObject() {
|
||||
return amenity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSupportedMenuStatesPortrait() {
|
||||
return MenuState.HEADER_ONLY | MenuState.HALF_SCREEN | MenuState.FULL_SCREEN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needStreetName() {
|
||||
if (amenity.getSubType() != null && amenity.getType() != null) {
|
||||
PoiType pt = amenity.getType().getPoiTypeByKeyName(amenity.getSubType());
|
||||
if (pt != null && pt.getOsmTag() != null && pt.getOsmTag().equals("place")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLeftIconId() {
|
||||
return getLeftIconId(amenity);
|
||||
}
|
||||
|
||||
public static int getLeftIconId(Amenity amenity) {
|
||||
int id = 0;
|
||||
PoiType st = amenity.getType().getPoiTypeByKeyName(amenity.getSubType());
|
||||
if (st != null) {
|
||||
id = OsmandResources.getBigDrawableId(st.getIconKeyName());
|
||||
if (id == 0) {
|
||||
id = OsmandResources.getBigDrawableId(st.getOsmTag() + "_" + st.getOsmValue());
|
||||
}
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean displayDistanceDirection() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeStr() {
|
||||
return getTypeStr(amenity);
|
||||
}
|
||||
|
||||
public static String getTypeStr(Amenity amenity) {
|
||||
PoiCategory pc = amenity.getType();
|
||||
PoiType pt = pc.getPoiTypeByKeyName(amenity.getSubType());
|
||||
String typeStr = amenity.getSubType();
|
||||
if (pt != null) {
|
||||
typeStr = pt.getTranslation();
|
||||
} else if (typeStr != null) {
|
||||
typeStr = Algorithms.capitalizeFirstLetterAndLowercase(typeStr.replace('_', ' '));
|
||||
}
|
||||
return typeStr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommonTypeStr() {
|
||||
PoiCategory pc = amenity.getType();
|
||||
return pc.getTranslation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPlainMenuItems(String typeStr, PointDescription pointDescription, LatLon latLon) {
|
||||
addPlainMenuItems(amenity, typeStr, builder);
|
||||
}
|
||||
|
||||
public static void addPlainMenuItems(Amenity amenity, String typeStr, MenuBuilder builder) {
|
||||
if (!Algorithms.isEmpty(typeStr)) {
|
||||
int resId = getLeftIconId(amenity);
|
||||
if (resId == 0) {
|
||||
PoiCategory pc = amenity.getType();
|
||||
resId = OsmandResources.getBigDrawableId(pc.getIconKeyName());
|
||||
}
|
||||
if (resId == 0) {
|
||||
resId = OsmandResources.getDrawableId("ic_action_folder_stroke");
|
||||
}
|
||||
builder.addPlainMenuItem(resId, typeStr, false, false, null);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package net.osmand.core.samples.android.sample1.mapcontextmenu.controllers;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import net.osmand.core.samples.android.sample1.MainActivity;
|
||||
import net.osmand.core.samples.android.sample1.OsmandResources;
|
||||
import net.osmand.core.samples.android.sample1.data.PointDescription;
|
||||
import net.osmand.core.samples.android.sample1.mapcontextmenu.MenuBuilder;
|
||||
import net.osmand.core.samples.android.sample1.mapcontextmenu.MenuController;
|
||||
|
||||
|
||||
public class MyLocationMenuController extends MenuController {
|
||||
|
||||
public MyLocationMenuController(MainActivity mainActivity, PointDescription pointDescription) {
|
||||
super(new MenuBuilder(mainActivity), pointDescription, mainActivity);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setObject(Object object) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getObject() {
|
||||
return getLatLon();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSupportedMenuStatesPortrait() {
|
||||
return MenuState.HEADER_ONLY | MenuState.HALF_SCREEN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeStr() {
|
||||
return getPointDescription().getTypeName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommonTypeStr() {
|
||||
return getMainActivity().getMyApplication().getString("shared_string_location");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needStreetName() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getLeftIcon() {
|
||||
return OsmandResources.getDrawable("map_pedestrian_location");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
package net.osmand.core.samples.android.sample1.mapcontextmenu.controllers;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import net.osmand.core.samples.android.sample1.MainActivity;
|
||||
import net.osmand.core.samples.android.sample1.OsmandResources;
|
||||
import net.osmand.core.samples.android.sample1.data.PointDescription;
|
||||
import net.osmand.core.samples.android.sample1.mapcontextmenu.MenuBuilder;
|
||||
import net.osmand.core.samples.android.sample1.mapcontextmenu.MenuController;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
public class PointDescriptionMenuController extends MenuController {
|
||||
|
||||
private boolean hasTypeInDescription;
|
||||
|
||||
public PointDescriptionMenuController(MainActivity mainActivity, final PointDescription pointDescription) {
|
||||
super(new MenuBuilder(mainActivity), pointDescription, mainActivity);
|
||||
initData();
|
||||
}
|
||||
|
||||
private void initData() {
|
||||
hasTypeInDescription = !Algorithms.isEmpty(getPointDescription().getTypeName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setObject(Object object) {
|
||||
initData();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getObject() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSupportedMenuStatesPortrait() {
|
||||
return MenuState.HEADER_ONLY | MenuState.HALF_SCREEN | MenuState.FULL_SCREEN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean displayStreetNameInTitle() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean displayDistanceDirection() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getLeftIcon() {
|
||||
return getIcon(getPointDescription().getIconId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getSecondLineTypeIcon() {
|
||||
if (hasTypeInDescription) {
|
||||
return getIcon(OsmandResources.getDrawableId("ic_small_group"));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeStr() {
|
||||
if (hasTypeInDescription) {
|
||||
return getPointDescription().getTypeName();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommonTypeStr() {
|
||||
return getMainActivity().getMyApplication().getString("shared_string_location");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needStreetName() {
|
||||
return !getPointDescription().isAddress();
|
||||
}
|
||||
}
|
|
@ -23,7 +23,7 @@ public class QuickSearchHelper {
|
|||
|
||||
public QuickSearchHelper(SampleApplication app) {
|
||||
this.app = app;
|
||||
core = new SearchUICore(app.getPoiTypes(), SampleApplication.LANGUAGE, false);
|
||||
core = new SearchUICore(app.getPoiTypes(), SampleApplication.LANGUAGE, SampleApplication.TRANSLITERATE);
|
||||
}
|
||||
|
||||
public SearchUICore getCore() {
|
||||
|
|
|
@ -198,13 +198,7 @@ public abstract class QuickSearchListFragment extends ListFragment {
|
|||
dialogFragment.hide();
|
||||
|
||||
getMainActivity().showOnMap(searchResult.location, searchResult.preferredZoom);
|
||||
/* todo
|
||||
getMyApplication().getSettings().setMapLocationToShow(
|
||||
searchResult.location.getLatitude(), searchResult.location.getLongitude(),
|
||||
searchResult.preferredZoom, pointDescription, true, object);
|
||||
|
||||
MapActivity.launchMapActivityMoveToTop(getActivity());
|
||||
*/
|
||||
getMainActivity().getContextMenu().show(searchResult.location, pointDescription, object);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -202,11 +202,11 @@ public class QuickSearchListItem {
|
|||
}
|
||||
|
||||
public static int getPoiTypeIconId(SampleApplication app, AbstractPoiType abstractPoiType) {
|
||||
int res = OsmandResources.getDrawableId("mx_" + abstractPoiType.getIconKeyName());
|
||||
int res = OsmandResources.getBigDrawableId(abstractPoiType.getIconKeyName());
|
||||
if (res != 0) {
|
||||
return res;
|
||||
} else if (abstractPoiType instanceof PoiType) {
|
||||
res = OsmandResources.getDrawableId("mx_" + ((PoiType) abstractPoiType).getOsmTag()
|
||||
res = OsmandResources.getBigDrawableId(((PoiType) abstractPoiType).getOsmTag()
|
||||
+ "_" + ((PoiType) abstractPoiType).getOsmValue());
|
||||
if (res != 0) {
|
||||
return res;
|
||||
|
@ -222,9 +222,9 @@ public class QuickSearchListItem {
|
|||
int res = 0;
|
||||
PoiType st = amenity.getType().getPoiTypeByKeyName(amenity.getSubType());
|
||||
if (st != null) {
|
||||
res = OsmandResources.getDrawableId("mx_" + st.getIconKeyName());
|
||||
res = OsmandResources.getBigDrawableId(st.getIconKeyName());
|
||||
if (res == 0) {
|
||||
res = OsmandResources.getDrawableId("mx_" + st.getOsmTag() + "_" + st.getOsmValue());
|
||||
res = OsmandResources.getBigDrawableId(st.getOsmTag() + "_" + st.getOsmValue());
|
||||
}
|
||||
}
|
||||
return res;
|
||||
|
@ -234,9 +234,9 @@ public class QuickSearchListItem {
|
|||
PoiType st = amenity.getType().getPoiTypeByKeyName(amenity.getSubType());
|
||||
if (st != null) {
|
||||
String id = st.getIconKeyName();
|
||||
if (OsmandResources.getDrawableId("mx_" + id) == 0) {
|
||||
if (OsmandResources.getBigDrawableId(id) == 0) {
|
||||
id = st.getOsmTag() + "_" + st.getOsmValue();
|
||||
if (OsmandResources.getDrawableId("mx_" + id) != 0) {
|
||||
if (OsmandResources.getBigDrawableId(id) != 0) {
|
||||
return id;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
package net.osmand.core.samples.android.sample1.view;
|
||||
|
||||
import android.view.GestureDetector;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
public class SingleTapConfirm implements GestureDetector.OnGestureListener {
|
||||
|
||||
@Override
|
||||
public boolean onDown(MotionEvent e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShowPress(MotionEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSingleTapUp(MotionEvent e) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongPress(MotionEvent e) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
||||
return false;
|
||||
}
|
||||
}
|