Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
f871888a76
19 changed files with 769 additions and 54 deletions
|
@ -1,14 +1,17 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:gravity="center"
|
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
<android.support.v7.widget.RecyclerView
|
||||||
android:layout_width="wrap_content"
|
android:id="@+id/recycler_view"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:text="@string/saved_articles"/>
|
android:layout_height="match_parent"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:paddingBottom="@dimen/map_markers_recycler_view_padding_bottom"
|
||||||
|
tools:listitem="@layout/wikivoyage_article_card"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
|
@ -1,58 +1,142 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout
|
<FrameLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
android:background="?attr/wikivoyage_bg_color"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<android.support.v7.widget.Toolbar
|
<LinearLayout
|
||||||
android:id="@+id/toolbar"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/toolbar_height"
|
android:layout_height="match_parent"
|
||||||
android:background="?attr/wikivoyage_app_bar_color"
|
android:background="?attr/wikivoyage_bg_color"
|
||||||
android:gravity="center_vertical"
|
android:orientation="vertical">
|
||||||
android:minHeight="@dimen/toolbar_height"
|
|
||||||
osmand:contentInsetLeft="54dp"
|
<android.support.v7.widget.Toolbar
|
||||||
osmand:contentInsetStart="54dp">
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/toolbar_height"
|
||||||
|
android:background="?attr/wikivoyage_app_bar_color"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:minHeight="@dimen/toolbar_height"
|
||||||
|
osmand:contentInsetLeft="54dp"
|
||||||
|
osmand:contentInsetStart="54dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_weight="1"/>
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:id="@+id/select_language_text_view"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginBottom="@dimen/content_padding_small"
|
||||||
|
android:layout_marginLeft="@dimen/context_menu_padding_margin_small"
|
||||||
|
android:layout_marginRight="@dimen/context_menu_padding_margin_small"
|
||||||
|
android:layout_marginTop="@dimen/content_padding_small"
|
||||||
|
android:drawablePadding="@dimen/context_menu_padding_margin_small"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:letterSpacing="@dimen/text_button_letter_spacing"
|
||||||
|
android:padding="@dimen/context_menu_padding_margin_tiny"
|
||||||
|
android:textSize="@dimen/default_desc_text_size"
|
||||||
|
osmand:typeface="@string/font_roboto_medium"
|
||||||
|
tools:background="@drawable/wikipedia_select_lang_bg_dark_n"
|
||||||
|
tools:drawableLeft="@drawable/ic_action_map_language"
|
||||||
|
tools:ignore="UnusedAttribute"
|
||||||
|
tools:text="En"
|
||||||
|
tools:textColor="?attr/wikivoyage_active_color"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</android.support.v7.widget.Toolbar>
|
||||||
|
|
||||||
|
<WebView
|
||||||
|
android:id="@+id/content_web_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/bottom_bar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/bottom_sheet_cancel_button_height"
|
||||||
|
android:layout_gravity="bottom|center_horizontal"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/bottom_row_divider"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="?attr/wikivoyage_bottom_bar_divider_color"/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
android:background="?attr/wikivoyage_bottom_bar_bg_color">
|
||||||
<View
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_weight="1"/>
|
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
android:id="@+id/select_language_text_view"
|
android:id="@+id/contents_button"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginBottom="@dimen/content_padding_small"
|
android:layout_gravity="center_vertical"
|
||||||
android:layout_marginLeft="@dimen/context_menu_padding_margin_small"
|
android:layout_weight="0.5"
|
||||||
android:layout_marginRight="@dimen/context_menu_padding_margin_small"
|
android:background="?attr/selectableItemBackground"
|
||||||
android:layout_marginTop="@dimen/content_padding_small"
|
android:drawablePadding="@dimen/bottom_sheet_content_padding_small"
|
||||||
android:drawablePadding="@dimen/context_menu_padding_margin_small"
|
android:ellipsize="end"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:letterSpacing="@dimen/text_button_letter_spacing"
|
android:letterSpacing="@dimen/text_button_letter_spacing"
|
||||||
android:padding="@dimen/context_menu_padding_margin_tiny"
|
android:maxLines="1"
|
||||||
|
android:paddingBottom="@dimen/context_menu_padding_margin_tiny"
|
||||||
|
android:paddingLeft="@dimen/bottom_sheet_content_padding_small"
|
||||||
|
android:paddingRight="@dimen/bottom_sheet_content_padding_small"
|
||||||
|
android:paddingTop="@dimen/context_menu_padding_margin_tiny"
|
||||||
|
android:text="@string/shared_string_contents"
|
||||||
|
android:textColor="?attr/wikivoyage_active_color"
|
||||||
android:textSize="@dimen/default_desc_text_size"
|
android:textSize="@dimen/default_desc_text_size"
|
||||||
osmand:typeface="@string/font_roboto_medium"
|
osmand:typeface="@string/font_roboto_medium"
|
||||||
tools:background="@drawable/wikipedia_select_lang_bg_dark_n"
|
tools:drawableLeft="@drawable/ic_action_list_header"
|
||||||
tools:drawableLeft="@drawable/ic_action_map_language"
|
tools:drawableTint="?attr/wikivoyage_active_color"
|
||||||
tools:text="En"
|
tools:ignore="UnusedAttribute"/>
|
||||||
tools:textColor="?attr/wikivoyage_active_color"/>
|
|
||||||
|
<View
|
||||||
|
android:id="@+id/bottom_buttons_divider"
|
||||||
|
android:layout_width="1dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="?attr/wikivoyage_bottom_bar_divider_color"
|
||||||
|
android:visibility="visible"/>
|
||||||
|
|
||||||
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
|
android:id="@+id/save_button"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_gravity="center_vertical|end"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="?attr/selectableItemBackground"
|
||||||
|
android:drawablePadding="@dimen/bottom_sheet_content_padding_small"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:gravity="center_vertical|end"
|
||||||
|
android:letterSpacing="@dimen/text_button_letter_spacing"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:paddingBottom="@dimen/context_menu_padding_margin_tiny"
|
||||||
|
android:paddingLeft="@dimen/bottom_sheet_content_padding_small"
|
||||||
|
android:paddingRight="@dimen/bottom_sheet_content_padding_small"
|
||||||
|
android:paddingTop="@dimen/context_menu_padding_margin_tiny"
|
||||||
|
android:text="@string/shared_string_save"
|
||||||
|
android:textColor="?attr/wikivoyage_active_color"
|
||||||
|
android:textSize="@dimen/default_desc_text_size"
|
||||||
|
osmand:typeface="@string/font_roboto_medium"
|
||||||
|
tools:drawableRight="@drawable/ic_action_read_later_fill"
|
||||||
|
tools:drawableTint="?attr/wikivoyage_active_color"
|
||||||
|
tools:ignore="UnusedAttribute"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</android.support.v7.widget.Toolbar>
|
</LinearLayout>
|
||||||
|
|
||||||
<WebView
|
</FrameLayout>
|
||||||
android:id="@+id/content_web_view"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
|
@ -84,7 +84,7 @@
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
android:id="@+id/read_button"
|
android:id="@+id/left_button"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="@dimen/bottom_sheet_content_padding_small"
|
android:layout_marginLeft="@dimen/bottom_sheet_content_padding_small"
|
||||||
|
@ -99,13 +99,13 @@
|
||||||
android:paddingLeft="@dimen/bottom_sheet_content_padding_small"
|
android:paddingLeft="@dimen/bottom_sheet_content_padding_small"
|
||||||
android:paddingRight="@dimen/bottom_sheet_content_padding_small"
|
android:paddingRight="@dimen/bottom_sheet_content_padding_small"
|
||||||
android:paddingTop="@dimen/context_menu_padding_margin_tiny"
|
android:paddingTop="@dimen/context_menu_padding_margin_tiny"
|
||||||
android:text="@string/shared_string_read"
|
|
||||||
android:textColor="?attr/wikivoyage_active_color"
|
android:textColor="?attr/wikivoyage_active_color"
|
||||||
android:textSize="@dimen/default_desc_text_size"
|
android:textSize="@dimen/default_desc_text_size"
|
||||||
osmand:typeface="@string/font_roboto_medium"
|
osmand:typeface="@string/font_roboto_medium"
|
||||||
tools:drawableLeft="@drawable/ic_action_read_article"
|
tools:drawableLeft="@drawable/ic_action_read_article"
|
||||||
tools:drawableTint="?attr/wikivoyage_active_color"
|
tools:drawableTint="?attr/wikivoyage_active_color"
|
||||||
tools:ignore="UnusedAttribute"/>
|
tools:ignore="UnusedAttribute"
|
||||||
|
tools:text="Read"/>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
|
@ -113,7 +113,7 @@
|
||||||
android:layout_weight="1"/>
|
android:layout_weight="1"/>
|
||||||
|
|
||||||
<net.osmand.plus.widgets.TextViewEx
|
<net.osmand.plus.widgets.TextViewEx
|
||||||
android:id="@+id/delete_button"
|
android:id="@+id/right_button"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="@dimen/bottom_sheet_content_padding_small"
|
android:layout_marginEnd="@dimen/bottom_sheet_content_padding_small"
|
||||||
|
@ -128,13 +128,13 @@
|
||||||
android:paddingLeft="@dimen/bottom_sheet_content_padding_small"
|
android:paddingLeft="@dimen/bottom_sheet_content_padding_small"
|
||||||
android:paddingRight="@dimen/bottom_sheet_content_padding_small"
|
android:paddingRight="@dimen/bottom_sheet_content_padding_small"
|
||||||
android:paddingTop="@dimen/context_menu_padding_margin_tiny"
|
android:paddingTop="@dimen/context_menu_padding_margin_tiny"
|
||||||
android:text="@string/shared_string_delete"
|
|
||||||
android:textColor="?attr/wikivoyage_active_color"
|
android:textColor="?attr/wikivoyage_active_color"
|
||||||
android:textSize="@dimen/default_desc_text_size"
|
android:textSize="@dimen/default_desc_text_size"
|
||||||
osmand:typeface="@string/font_roboto_medium"
|
osmand:typeface="@string/font_roboto_medium"
|
||||||
tools:drawableRight="@drawable/ic_action_read_later_fill"
|
tools:drawableRight="@drawable/ic_action_read_later_fill"
|
||||||
tools:drawableTint="?attr/wikivoyage_active_color"
|
tools:drawableTint="?attr/wikivoyage_active_color"
|
||||||
tools:ignore="UnusedAttribute"/>
|
tools:ignore="UnusedAttribute"
|
||||||
|
tools:text="Delete"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
23
OsmAnd/res/layout/wikivoyage_contents_list_item.xml
Normal file
23
OsmAnd/res/layout/wikivoyage_contents_list_item.xml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/bottom_sheet_list_item_height"
|
||||||
|
android:background="?attr/expandable_list_item_background"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/item_label"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="@dimen/bottom_sheet_list_item_height"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:drawablePadding="@dimen/showAllButtonMarginRight"
|
||||||
|
android:gravity="center"
|
||||||
|
android:paddingLeft="@dimen/showAllButtonMarginRight"
|
||||||
|
android:textColor="?android:textColorPrimary"
|
||||||
|
android:textSize="@dimen/default_list_text_size"
|
||||||
|
tools:drawableStart="@drawable/ic_action_list_sort"
|
||||||
|
tools:text="@string/shared_string_contents"
|
||||||
|
tools:textStyle="bold" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
44
OsmAnd/res/layout/wikivoyage_list_header.xml
Normal file
44
OsmAnd/res/layout/wikivoyage_list_header.xml
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="8dp"/>
|
||||||
|
|
||||||
|
<include layout="@layout/card_top_divider"/>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/bottom_sheet_list_item_height"
|
||||||
|
android:background="?attr/wikivoyage_card_bg_color"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:paddingLeft="@dimen/content_padding"
|
||||||
|
android:paddingRight="@dimen/content_padding">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
tools:text="Saved articles"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/description"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="@dimen/content_padding"
|
||||||
|
android:layout_marginStart="@dimen/content_padding"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
tools:text="15"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -6,7 +6,11 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<include layout="@layout/list_item_divider"/>
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="8dp"/>
|
||||||
|
|
||||||
|
<include layout="@layout/card_top_divider"/>
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
@ -71,6 +71,8 @@
|
||||||
<attr name="wikivoyage_app_bar_color" format="reference"/>
|
<attr name="wikivoyage_app_bar_color" format="reference"/>
|
||||||
<attr name="wikivoyage_app_bar_text_color" format="reference"/>
|
<attr name="wikivoyage_app_bar_text_color" format="reference"/>
|
||||||
<attr name="wikivoyage_active_color" format="reference"/>
|
<attr name="wikivoyage_active_color" format="reference"/>
|
||||||
|
<attr name="wikivoyage_bottom_bar_bg_color" format="reference"/>
|
||||||
|
<attr name="wikivoyage_bottom_bar_divider_color" format="reference"/>
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
|
|
||||||
<declare-styleable name="PagerSlidingTabStrip">
|
<declare-styleable name="PagerSlidingTabStrip">
|
||||||
|
|
|
@ -400,5 +400,11 @@
|
||||||
<color name="wikivoyage_app_bar_dark">#222526</color>
|
<color name="wikivoyage_app_bar_dark">#222526</color>
|
||||||
<color name="wikivoyage_app_bar_text_light">#454545</color>
|
<color name="wikivoyage_app_bar_text_light">#454545</color>
|
||||||
<color name="wikivoyage_app_bar_text_dark">#ababab</color>
|
<color name="wikivoyage_app_bar_text_dark">#ababab</color>
|
||||||
|
<color name="wikivoyage_contents_icon_light">#536dfe</color>
|
||||||
|
<color name="wikivoyage_contents_icon_dark">#d28521</color>
|
||||||
|
<color name="wikivoyage_bottom_bar_bg_light">#f5f5f5</color>
|
||||||
|
<color name="wikivoyage_bottom_bar_bg_dark">#222526</color>
|
||||||
|
<color name="wikivoyage_bottom_bar_divider_light">#e3e3e3</color>
|
||||||
|
<color name="wikivoyage_bottom_bar_divider_dark">#2d3133</color>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
|
@ -13,6 +13,7 @@
|
||||||
<string name="shared_string_read">Read</string>
|
<string name="shared_string_read">Read</string>
|
||||||
<string name="saved_articles">Saved articles</string>
|
<string name="saved_articles">Saved articles</string>
|
||||||
<string name="shared_string_explore">Explore</string>
|
<string name="shared_string_explore">Explore</string>
|
||||||
|
<string name="shared_string_contents">Contents</string>
|
||||||
<string name="shared_string_result">Result</string>
|
<string name="shared_string_result">Result</string>
|
||||||
<string name="use_two_digits_longitude">Use two digits longitude</string>
|
<string name="use_two_digits_longitude">Use two digits longitude</string>
|
||||||
<string name="shared_string_travel">Travel</string>
|
<string name="shared_string_travel">Travel</string>
|
||||||
|
|
|
@ -203,6 +203,8 @@
|
||||||
<item name="wikivoyage_app_bar_color">@color/wikivoyage_app_bar_light</item>
|
<item name="wikivoyage_app_bar_color">@color/wikivoyage_app_bar_light</item>
|
||||||
<item name="wikivoyage_app_bar_text_color">@color/wikivoyage_app_bar_text_light</item>
|
<item name="wikivoyage_app_bar_text_color">@color/wikivoyage_app_bar_text_light</item>
|
||||||
<item name="wikivoyage_active_color">@color/wikivoyage_active_light</item>
|
<item name="wikivoyage_active_color">@color/wikivoyage_active_light</item>
|
||||||
|
<item name="wikivoyage_bottom_bar_bg_color">@color/wikivoyage_bottom_bar_bg_light</item>
|
||||||
|
<item name="wikivoyage_bottom_bar_divider_color">@color/wikivoyage_bottom_bar_divider_light</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="OverflowMenuButton" parent="@style/Widget.AppCompat.ActionButton.Overflow">
|
<style name="OverflowMenuButton" parent="@style/Widget.AppCompat.ActionButton.Overflow">
|
||||||
|
@ -394,6 +396,8 @@
|
||||||
<item name="wikivoyage_app_bar_color">@color/wikivoyage_app_bar_dark</item>
|
<item name="wikivoyage_app_bar_color">@color/wikivoyage_app_bar_dark</item>
|
||||||
<item name="wikivoyage_app_bar_text_color">@color/wikivoyage_app_bar_text_dark</item>
|
<item name="wikivoyage_app_bar_text_color">@color/wikivoyage_app_bar_text_dark</item>
|
||||||
<item name="wikivoyage_active_color">@color/wikivoyage_active_dark</item>
|
<item name="wikivoyage_active_color">@color/wikivoyage_active_dark</item>
|
||||||
|
<item name="wikivoyage_bottom_bar_bg_color">@color/wikivoyage_bottom_bar_bg_dark</item>
|
||||||
|
<item name="wikivoyage_bottom_bar_divider_color">@color/wikivoyage_bottom_bar_divider_dark</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="FreeVersionBanner" parent="OsmandDarkTheme">
|
<style name="FreeVersionBanner" parent="OsmandDarkTheme">
|
||||||
|
|
|
@ -311,6 +311,12 @@ public class AndroidUtils {
|
||||||
return dm.heightPixels;
|
return dm.heightPixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int getScreenWidth(Activity activity) {
|
||||||
|
DisplayMetrics dm = new DisplayMetrics();
|
||||||
|
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
|
||||||
|
return dm.widthPixels;
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isValidEmail(CharSequence target) {
|
public static boolean isValidEmail(CharSequence target) {
|
||||||
return !TextUtils.isEmpty(target) && android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches();
|
return !TextUtils.isEmpty(target) && android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,222 @@
|
||||||
|
package net.osmand.plus.wikivoyage;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ExpandableListView;
|
||||||
|
import android.widget.ExpandableListView.OnGroupClickListener;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import net.osmand.AndroidUtils;
|
||||||
|
import net.osmand.plus.R;
|
||||||
|
import net.osmand.plus.activities.OsmandBaseExpandableListAdapter;
|
||||||
|
import net.osmand.plus.base.MenuBottomSheetDialogFragment;
|
||||||
|
import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
|
||||||
|
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
|
||||||
|
import net.osmand.plus.wikivoyage.data.ContentsJsonParser;
|
||||||
|
import net.osmand.plus.wikivoyage.data.ContentsJsonParser.ContentsContainer;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class WikivoyageArticleContentsFragment extends MenuBottomSheetDialogFragment {
|
||||||
|
|
||||||
|
public static final String TAG = "WikivoyageArticleContentsFragment";
|
||||||
|
|
||||||
|
public static final String CONTENTS_JSON_KEY = "contents_json";
|
||||||
|
public static final String CONTENTS_LINK_KEY = "contents_link";
|
||||||
|
|
||||||
|
public static final int REQUEST_LINK_CODE = 0;
|
||||||
|
|
||||||
|
private LinkedHashMap<String, String> map;
|
||||||
|
private String link;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createMenuItems(Bundle savedInstanceState) {
|
||||||
|
Bundle args = getArguments();
|
||||||
|
if (args == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String contentsJson = args.getString(CONTENTS_JSON_KEY);
|
||||||
|
ContentsContainer contentsContainer = ContentsJsonParser.parseJsonContents(contentsJson);
|
||||||
|
if (contentsContainer == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final ArrayList<String> listDataHeader = contentsContainer.listDataHeader;
|
||||||
|
final LinkedHashMap<String, List<String>> listDataChild = contentsContainer.listDataChild;
|
||||||
|
|
||||||
|
map = contentsContainer.map;
|
||||||
|
|
||||||
|
items.add(new TitleItem(getString(R.string.shared_string_contents)));
|
||||||
|
|
||||||
|
ExpandableListView expListView = new ExpandableListView(getContext());
|
||||||
|
ExpandableListAdapter listAdapter = new ExpandableListAdapter(getContext(), listDataHeader, listDataChild);
|
||||||
|
|
||||||
|
expListView.setAdapter(listAdapter);
|
||||||
|
expListView.setChildDivider(ContextCompat.getDrawable(getContext(), R.color.color_transparent));
|
||||||
|
expListView.setLayoutParams(new LinearLayout.LayoutParams(
|
||||||
|
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||||
|
LinearLayout.LayoutParams.MATCH_PARENT)
|
||||||
|
);
|
||||||
|
|
||||||
|
expListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onChildClick(ExpandableListView parent, View v,
|
||||||
|
int groupPosition, int childPosition, long id) {
|
||||||
|
link = map.get(listDataChild.get(listDataHeader.get(groupPosition)).get(childPosition));
|
||||||
|
sendResult();
|
||||||
|
dismiss();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
int width = AndroidUtils.getScreenWidth(getActivity());
|
||||||
|
if (android.os.Build.VERSION.SDK_INT < 18) {
|
||||||
|
expListView.setIndicatorBounds(width - (AndroidUtils.dpToPx(getContext(), 50)),
|
||||||
|
width - (AndroidUtils.dpToPx(getContext(), 10)));
|
||||||
|
} else {
|
||||||
|
expListView.setIndicatorBoundsRelative(width - (AndroidUtils.dpToPx(getContext(), 50)),
|
||||||
|
width - (AndroidUtils.dpToPx(getContext(), 10)));
|
||||||
|
}
|
||||||
|
expListView.setOnGroupClickListener(new OnGroupClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
|
||||||
|
link = map.get(listDataHeader.get(groupPosition));
|
||||||
|
sendResult();
|
||||||
|
if (listDataChild.get(listDataHeader.get(groupPosition)) == null) {
|
||||||
|
dismiss();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
LinearLayout container = new LinearLayout(getContext());
|
||||||
|
container.addView(expListView);
|
||||||
|
|
||||||
|
items.add(new SimpleBottomSheetItem.Builder().setCustomView(container).create());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendResult() {
|
||||||
|
Intent intent = new Intent();
|
||||||
|
intent.putExtra(CONTENTS_LINK_KEY, link);
|
||||||
|
Fragment fragment = getTargetFragment();
|
||||||
|
if (fragment != null) {
|
||||||
|
fragment.onActivityResult(getTargetRequestCode(), REQUEST_LINK_CODE, intent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean useScrollableItemsContainer() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ExpandableListAdapter extends OsmandBaseExpandableListAdapter {
|
||||||
|
|
||||||
|
private Context context;
|
||||||
|
|
||||||
|
private List<String> listDataHeader;
|
||||||
|
private LinkedHashMap<String, List<String>> listDataChild;
|
||||||
|
|
||||||
|
private Drawable itemGroupIcon;
|
||||||
|
private Drawable itemChildIcon;
|
||||||
|
|
||||||
|
ExpandableListAdapter(Context context, List<String> listDataHeader,
|
||||||
|
LinkedHashMap<String, List<String>> listChildData) {
|
||||||
|
this.context = context;
|
||||||
|
this.listDataHeader = listDataHeader;
|
||||||
|
this.listDataChild = listChildData;
|
||||||
|
|
||||||
|
itemGroupIcon = getIcon(R.drawable.ic_action_contents, nightMode
|
||||||
|
? R.color.wikivoyage_active_dark : R.color.wikivoyage_active_light);
|
||||||
|
itemChildIcon = getIcon(R.drawable.ic_action_list_bullet, nightMode
|
||||||
|
? R.color.route_info_unchecked_mode_icon_color
|
||||||
|
: R.color.ctx_menu_nearby_routes_text_color_dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getChild(int groupPosition, int childPosititon) {
|
||||||
|
return this.listDataChild.get(this.listDataHeader.get(groupPosition)).get(childPosititon);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getChildId(int groupPosition, int childPosition) {
|
||||||
|
return childPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getChildView(int groupPosition, final int childPosition,
|
||||||
|
boolean isLastChild, View convertView, ViewGroup parent) {
|
||||||
|
String childText = (String) getChild(groupPosition, childPosition);
|
||||||
|
if (convertView == null) {
|
||||||
|
LayoutInflater infalInflater = (LayoutInflater) this.context
|
||||||
|
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||||
|
convertView = infalInflater.inflate(R.layout.wikivoyage_contents_list_item, parent, false);
|
||||||
|
}
|
||||||
|
TextView txtListChild = (TextView) convertView.findViewById(R.id.item_label);
|
||||||
|
txtListChild.setText(childText);
|
||||||
|
txtListChild.setTextColor(getResolvedColor(nightMode
|
||||||
|
? R.color.wikivoyage_contents_icon_dark
|
||||||
|
: R.color.wikivoyage_contents_icon_light));
|
||||||
|
txtListChild.setCompoundDrawablesWithIntrinsicBounds(itemChildIcon, null, null, null);
|
||||||
|
|
||||||
|
return convertView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getChildrenCount(int groupPosition) {
|
||||||
|
List<String> list = listDataChild.get(listDataHeader.get(groupPosition));
|
||||||
|
return list == null ? 0 : list.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getGroup(int groupPosition) {
|
||||||
|
return this.listDataHeader.get(groupPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getGroupCount() {
|
||||||
|
return this.listDataHeader.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getGroupId(int groupPosition) {
|
||||||
|
return groupPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getGroupView(int groupPosition, boolean isExpanded,
|
||||||
|
View convertView, ViewGroup parent) {
|
||||||
|
String headerTitle = (String) getGroup(groupPosition);
|
||||||
|
if (convertView == null) {
|
||||||
|
LayoutInflater infalInflater = (LayoutInflater) this.context
|
||||||
|
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||||
|
convertView = infalInflater.inflate(R.layout.wikivoyage_contents_list_item, parent, false);
|
||||||
|
}
|
||||||
|
TextView lblListHeader = (TextView) convertView.findViewById(R.id.item_label);
|
||||||
|
lblListHeader.setText(headerTitle);
|
||||||
|
lblListHeader.setTextColor(getResolvedColor(isNightMode() ? R.color.wikivoyage_contents_icon_dark : R.color.wikivoyage_contents_icon_light));
|
||||||
|
lblListHeader.setCompoundDrawablesWithIntrinsicBounds(itemGroupIcon, null, null, null);
|
||||||
|
|
||||||
|
return convertView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasStableIds() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isChildSelectable(int groupPosition, int childPosition) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
package net.osmand.plus.wikivoyage;
|
package net.osmand.plus.wikivoyage;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.Intent;
|
||||||
import android.content.res.ColorStateList;
|
import android.content.res.ColorStateList;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
@ -42,16 +44,19 @@ public class WikivoyageArticleDialogFragment extends WikivoyageBaseDialogFragmen
|
||||||
"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n" +
|
"<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n" +
|
||||||
"<meta http-equiv=\"cleartype\" content=\"on\" />\n" +
|
"<meta http-equiv=\"cleartype\" content=\"on\" />\n" +
|
||||||
"<link href=\"article_style.css\" type=\"text/css\" rel=\"stylesheet\"/>\n" +
|
"<link href=\"article_style.css\" type=\"text/css\" rel=\"stylesheet\"/>\n" +
|
||||||
"</head><body>\n";
|
"</head><body>\n" + "<script>" + "function scrollAnchor(id) {" +
|
||||||
|
"window.location.hash = id;}</script>";
|
||||||
private static final String FOOTER_INNER = "</div></body></html>";
|
private static final String FOOTER_INNER = "</div></body></html>";
|
||||||
|
|
||||||
private long cityId = NO_VALUE;
|
private long cityId = NO_VALUE;
|
||||||
private ArrayList<String> langs;
|
private ArrayList<String> langs;
|
||||||
private String selectedLang;
|
private String selectedLang;
|
||||||
|
private String contentsJson;
|
||||||
|
|
||||||
private TextView selectedLangTv;
|
private TextView selectedLangTv;
|
||||||
private WebView contentWebView;
|
private WebView contentWebView;
|
||||||
|
|
||||||
|
@SuppressLint("SetJavaScriptEnabled")
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||||
|
@ -86,7 +91,30 @@ public class WikivoyageArticleDialogFragment extends WikivoyageBaseDialogFragmen
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
TextView contentsBtn = (TextView) mainView.findViewById(R.id.contents_button);
|
||||||
|
contentsBtn.setCompoundDrawablesWithIntrinsicBounds(
|
||||||
|
getActiveIcon(R.drawable.ic_action_list_header), null, null, null
|
||||||
|
);
|
||||||
|
contentsBtn.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putString(WikivoyageArticleContentsFragment.CONTENTS_JSON_KEY, contentsJson);
|
||||||
|
WikivoyageArticleContentsFragment fragment = new WikivoyageArticleContentsFragment();
|
||||||
|
fragment.setUsedOnMap(false);
|
||||||
|
fragment.setArguments(args);
|
||||||
|
fragment.setTargetFragment(WikivoyageArticleDialogFragment.this, 0);
|
||||||
|
fragment.show(getFragmentManager(), WikivoyageArticleContentsFragment.TAG);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
TextView saveBtn = (TextView) mainView.findViewById(R.id.save_button);
|
||||||
|
saveBtn.setCompoundDrawablesWithIntrinsicBounds(
|
||||||
|
null, null, getActiveIcon(R.drawable.ic_action_read_later), null
|
||||||
|
);
|
||||||
|
|
||||||
contentWebView = (WebView) mainView.findViewById(R.id.content_web_view);
|
contentWebView = (WebView) mainView.findViewById(R.id.content_web_view);
|
||||||
|
contentWebView.getSettings().setJavaScriptEnabled(true);
|
||||||
|
|
||||||
return mainView;
|
return mainView;
|
||||||
}
|
}
|
||||||
|
@ -102,6 +130,15 @@ public class WikivoyageArticleDialogFragment extends WikivoyageBaseDialogFragmen
|
||||||
outState.putString(SELECTED_LANG_KEY, selectedLang);
|
outState.putString(SELECTED_LANG_KEY, selectedLang);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
if (requestCode == WikivoyageArticleContentsFragment.REQUEST_LINK_CODE) {
|
||||||
|
String link = data.getStringExtra(WikivoyageArticleContentsFragment.CONTENTS_LINK_KEY);
|
||||||
|
moveToAnchor(link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getStatusBarColor() {
|
protected int getStatusBarColor() {
|
||||||
return nightMode ? R.color.status_bar_wikivoyage_article_dark : R.color.status_bar_wikivoyage_article_light;
|
return nightMode ? R.color.status_bar_wikivoyage_article_dark : R.color.status_bar_wikivoyage_article_light;
|
||||||
|
@ -153,11 +190,16 @@ public class WikivoyageArticleDialogFragment extends WikivoyageBaseDialogFragmen
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
contentsJson = article.getContentsJson();
|
||||||
WikivoyageLocalDataHelper.getInstance(getMyApplication()).addToHistory(article);
|
WikivoyageLocalDataHelper.getInstance(getMyApplication()).addToHistory(article);
|
||||||
|
|
||||||
contentWebView.loadDataWithBaseURL(getBaseUrl(), createHtmlContent(article), "text/html", "UTF-8", null);
|
contentWebView.loadDataWithBaseURL(getBaseUrl(), createHtmlContent(article), "text/html", "UTF-8", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void moveToAnchor(String id) {
|
||||||
|
contentWebView.loadUrl("javascript:scrollAnchor(\"" + id + "\")");
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private String createHtmlContent(@NonNull WikivoyageArticle article) {
|
private String createHtmlContent(@NonNull WikivoyageArticle article) {
|
||||||
StringBuilder sb = new StringBuilder(HEADER_INNER);
|
StringBuilder sb = new StringBuilder(HEADER_INNER);
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
package net.osmand.plus.wikivoyage.data;
|
||||||
|
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ContentsJsonParser {
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static ContentsContainer parseJsonContents(String contentsJson) {
|
||||||
|
LinkedHashMap<String, String> map = new LinkedHashMap<>();
|
||||||
|
ArrayList<String> listDataHeader = new ArrayList<>();
|
||||||
|
LinkedHashMap<String, List<String>> listDataChild = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
JSONObject reader;
|
||||||
|
try {
|
||||||
|
reader = new JSONObject(contentsJson);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
List<String> secondLevel = null;
|
||||||
|
JSONArray jArray = reader.names();
|
||||||
|
for (int i = 0; i < jArray.length(); i++) {
|
||||||
|
try {
|
||||||
|
JSONArray contacts = reader.getJSONArray(reader.names().getString(i));
|
||||||
|
String link = contacts.getString(1);
|
||||||
|
|
||||||
|
map.put(reader.names().getString(i), link);
|
||||||
|
|
||||||
|
int level = contacts.getInt(0);
|
||||||
|
|
||||||
|
if (level == 2) {
|
||||||
|
listDataHeader.add(reader.names().getString(i));
|
||||||
|
secondLevel = new ArrayList<>();
|
||||||
|
}
|
||||||
|
if (level == 3) {
|
||||||
|
if (secondLevel == null) {
|
||||||
|
secondLevel = new ArrayList<>();
|
||||||
|
}
|
||||||
|
secondLevel.add(reader.names().getString(i));
|
||||||
|
listDataChild.put(listDataHeader.get(listDataHeader.size() - 1), secondLevel);
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new ContentsContainer(map, listDataHeader, listDataChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ContentsContainer {
|
||||||
|
|
||||||
|
public LinkedHashMap<String, String> map;
|
||||||
|
public ArrayList<String> listDataHeader;
|
||||||
|
public LinkedHashMap<String, List<String>> listDataChild;
|
||||||
|
|
||||||
|
ContentsContainer(LinkedHashMap<String, String> map,
|
||||||
|
ArrayList<String> listDataHeader,
|
||||||
|
LinkedHashMap<String, List<String>> listChildData) {
|
||||||
|
this.map = map;
|
||||||
|
this.listDataHeader = listDataHeader;
|
||||||
|
this.listDataChild = listChildData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.annotation.Size;
|
import android.support.annotation.Size;
|
||||||
import android.text.Html;
|
import android.text.Html;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import net.osmand.plus.GPXUtilities.GPXFile;
|
import net.osmand.plus.GPXUtilities.GPXFile;
|
||||||
|
|
||||||
|
@ -98,21 +99,40 @@ public class WikivoyageArticle {
|
||||||
|
|
||||||
// 4 is the length of </p> tag
|
// 4 is the length of </p> tag
|
||||||
String firstParagraphHtml = content.substring(firstParagraphStart, firstParagraphEnd + 4);
|
String firstParagraphHtml = content.substring(firstParagraphStart, firstParagraphEnd + 4);
|
||||||
String firstParagraphText = Html.fromHtml(firstParagraphHtml).toString();
|
String firstParagraphText = Html.fromHtml(firstParagraphHtml).toString().trim();
|
||||||
String[] phrases = firstParagraphText.split("\\. ");
|
String[] phrases = firstParagraphText.split("\\. ");
|
||||||
|
|
||||||
StringBuilder res = new StringBuilder();
|
StringBuilder res = new StringBuilder();
|
||||||
int limit = Math.min(phrases.length, PARTIAL_CONTENT_PHRASES);
|
int limit = Math.min(phrases.length, PARTIAL_CONTENT_PHRASES);
|
||||||
for (int i = 0; i < limit; i++) {
|
for (int i = 0; i < limit; i++) {
|
||||||
res.append(phrases[i]).append(".");
|
res.append(phrases[i]);
|
||||||
if (i < limit - 1) {
|
if (i < limit - 1) {
|
||||||
res.append(" ");
|
res.append(". ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.toString();
|
return res.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public String getGeoDescription() {
|
||||||
|
if (TextUtils.isEmpty(aggregatedPartOf)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] parts = aggregatedPartOf.split(",");
|
||||||
|
if (parts.length > 0) {
|
||||||
|
StringBuilder res = new StringBuilder();
|
||||||
|
res.append(parts[parts.length - 1]);
|
||||||
|
if (parts.length > 1) {
|
||||||
|
res.append(" \u2022 ").append(parts[0]);
|
||||||
|
}
|
||||||
|
return res.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public static String getImageUrl(@NonNull String imageTitle, boolean thumbnail) {
|
public static String getImageUrl(@NonNull String imageTitle, boolean thumbnail) {
|
||||||
String[] hash = getHash(imageTitle);
|
String[] hash = getHash(imageTitle);
|
||||||
|
|
|
@ -83,6 +83,7 @@ public class WikivoyageLocalDataHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
public List<WikivoyageArticle> getSavedArticles() {
|
public List<WikivoyageArticle> getSavedArticles() {
|
||||||
return new ArrayList<>(savedArticles);
|
return new ArrayList<>(savedArticles);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,168 @@
|
||||||
|
package net.osmand.plus.wikivoyage.explore;
|
||||||
|
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import net.osmand.plus.IconsCache;
|
||||||
|
import net.osmand.plus.OsmandApplication;
|
||||||
|
import net.osmand.plus.R;
|
||||||
|
import net.osmand.plus.wikivoyage.data.WikivoyageArticle;
|
||||||
|
import net.osmand.plus.wikivoyage.data.WikivoyageLocalDataHelper;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class SavedArticlesRvAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||||
|
|
||||||
|
private static final int HEADER_TYPE = 0;
|
||||||
|
private static final int ITEM_TYPE = 1;
|
||||||
|
|
||||||
|
private final OsmandApplication app;
|
||||||
|
|
||||||
|
private final List<Object> items = new ArrayList<>();
|
||||||
|
|
||||||
|
private final Drawable readIcon;
|
||||||
|
private final Drawable deleteIcon;
|
||||||
|
|
||||||
|
public SavedArticlesRvAdapter(OsmandApplication app) {
|
||||||
|
this.app = app;
|
||||||
|
List<WikivoyageArticle> savedArticles = WikivoyageLocalDataHelper.getInstance(app).getSavedArticles();
|
||||||
|
if (!savedArticles.isEmpty()) {
|
||||||
|
items.add(app.getString(R.string.saved_articles));
|
||||||
|
items.addAll(savedArticles);
|
||||||
|
}
|
||||||
|
int colorId = app.getSettings().isLightContent()
|
||||||
|
? R.color.wikivoyage_active_light : R.color.wikivoyage_active_dark;
|
||||||
|
IconsCache ic = app.getIconsCache();
|
||||||
|
readIcon = ic.getIcon(R.drawable.ic_action_read_article, colorId);
|
||||||
|
deleteIcon = ic.getIcon(R.drawable.ic_action_read_later_fill, colorId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
boolean header = viewType == HEADER_TYPE;
|
||||||
|
int layoutId = header ? R.layout.wikivoyage_list_header : R.layout.wikivoyage_article_card;
|
||||||
|
View itemView = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false);
|
||||||
|
return header ? new HeaderVH(itemView) : new ItemVH(itemView);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
|
||||||
|
if (viewHolder instanceof HeaderVH) {
|
||||||
|
final HeaderVH holder = (HeaderVH) viewHolder;
|
||||||
|
holder.title.setText((String) getItem(position));
|
||||||
|
holder.description.setText(String.valueOf(items.size() - 1));
|
||||||
|
} else {
|
||||||
|
final ItemVH holder = (ItemVH) viewHolder;
|
||||||
|
WikivoyageArticle article = (WikivoyageArticle) getItem(position);
|
||||||
|
boolean lastItem = position == getItemCount() - 1;
|
||||||
|
|
||||||
|
holder.title.setText(article.getTitle());
|
||||||
|
holder.content.setText(article.getContent());
|
||||||
|
holder.partOf.setText(article.getGeoDescription());
|
||||||
|
holder.icon.setVisibility(View.GONE); // todo
|
||||||
|
holder.leftButton.setText(app.getString(R.string.shared_string_read));
|
||||||
|
holder.leftButton.setCompoundDrawablesWithIntrinsicBounds(readIcon, null, null, null);
|
||||||
|
holder.rightButton.setText(app.getString(R.string.shared_string_delete));
|
||||||
|
holder.rightButton.setCompoundDrawablesWithIntrinsicBounds(null, null, deleteIcon, null);
|
||||||
|
holder.divider.setVisibility(lastItem ? View.GONE : View.VISIBLE);
|
||||||
|
holder.shadow.setVisibility(lastItem ? View.VISIBLE : View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemViewType(int position) {
|
||||||
|
if (getItem(position) instanceof String) {
|
||||||
|
return HEADER_TYPE;
|
||||||
|
}
|
||||||
|
return ITEM_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return items.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object getItem(int position) {
|
||||||
|
return items.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class HeaderVH extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
|
final TextView title;
|
||||||
|
final TextView description;
|
||||||
|
|
||||||
|
HeaderVH(View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
title = (TextView) itemView.findViewById(R.id.title);
|
||||||
|
description = (TextView) itemView.findViewById(R.id.description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ItemVH extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
|
final TextView title;
|
||||||
|
final TextView content;
|
||||||
|
final TextView partOf;
|
||||||
|
final ImageView icon;
|
||||||
|
final TextView leftButton;
|
||||||
|
final TextView rightButton;
|
||||||
|
final View divider;
|
||||||
|
final View shadow;
|
||||||
|
|
||||||
|
ItemVH(View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
title = (TextView) itemView.findViewById(R.id.title);
|
||||||
|
content = (TextView) itemView.findViewById(R.id.content);
|
||||||
|
partOf = (TextView) itemView.findViewById(R.id.part_of);
|
||||||
|
icon = (ImageView) itemView.findViewById(R.id.icon);
|
||||||
|
leftButton = (TextView) itemView.findViewById(R.id.left_button);
|
||||||
|
rightButton = (TextView) itemView.findViewById(R.id.right_button);
|
||||||
|
divider = itemView.findViewById(R.id.divider);
|
||||||
|
shadow = itemView.findViewById(R.id.shadow);
|
||||||
|
|
||||||
|
View.OnClickListener readClickListener = new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
Object item = getItemByPosition();
|
||||||
|
if (item != null && item instanceof WikivoyageArticle) {
|
||||||
|
WikivoyageArticle article = (WikivoyageArticle) item;
|
||||||
|
Toast.makeText(app, "read: " + article.getTitle(), Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
itemView.setOnClickListener(readClickListener);
|
||||||
|
leftButton.setOnClickListener(readClickListener);
|
||||||
|
|
||||||
|
rightButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
Object item = getItemByPosition();
|
||||||
|
if (item != null && item instanceof WikivoyageArticle) {
|
||||||
|
WikivoyageArticle article = (WikivoyageArticle) item;
|
||||||
|
Toast.makeText(app, "delete: " + article.getTitle(), Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Object getItemByPosition() {
|
||||||
|
int pos = getAdapterPosition();
|
||||||
|
if (pos != RecyclerView.NO_POSITION) {
|
||||||
|
return getItem(pos);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,8 @@ package net.osmand.plus.wikivoyage.explore;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
@ -15,6 +17,12 @@ public class SavedArticlesTabFragment extends BaseOsmAndFragment {
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||||
return inflater.inflate(R.layout.fragment_saved_articles_tab, container, false);
|
final View mainView = inflater.inflate(R.layout.fragment_saved_articles_tab, container, false);
|
||||||
|
|
||||||
|
final RecyclerView rv = (RecyclerView) mainView.findViewById(R.id.recycler_view);
|
||||||
|
rv.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
|
rv.setAdapter(new SavedArticlesRvAdapter(getMyApplication()));
|
||||||
|
|
||||||
|
return mainView;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,6 +164,12 @@ public class AndroidUtils {
|
||||||
return dm.heightPixels;
|
return dm.heightPixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int getScreenWidth(Activity activity) {
|
||||||
|
DisplayMetrics dm = new DisplayMetrics();
|
||||||
|
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
|
||||||
|
return dm.widthPixels;
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isValidEmail(CharSequence target) {
|
public static boolean isValidEmail(CharSequence target) {
|
||||||
return !TextUtils.isEmpty(target) && android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches();
|
return !TextUtils.isEmpty(target) && android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue