From e440a1301f75c5b738890fbd019578cccf574626 Mon Sep 17 00:00:00 2001 From: Chumva Date: Fri, 6 Apr 2018 19:06:04 +0300 Subject: [PATCH] add contents for anchor links --- .../fragment_wikivoyage_article_dialog.xml | 109 +++++++- ...wikivoyage_contents_expandablelistview.xml | 15 ++ .../wikivoyage_contents_group_list_item.xml | 25 ++ OsmAnd/res/values/strings.xml | 1 + .../WikivoyageArticleDialogFragment.java | 56 +++- ...icleContentsBottomSheetDialogFragment.java | 248 ++++++++++++++++++ 6 files changed, 443 insertions(+), 11 deletions(-) create mode 100644 OsmAnd/res/layout/wikivoyage_contents_expandablelistview.xml create mode 100644 OsmAnd/res/layout/wikivoyage_contents_group_list_item.xml create mode 100644 OsmAnd/src/net/osmand/plus/wikivoyage/data/WikivoyageArticleContentsBottomSheetDialogFragment.java diff --git a/OsmAnd/res/layout/fragment_wikivoyage_article_dialog.xml b/OsmAnd/res/layout/fragment_wikivoyage_article_dialog.xml index 5874c973f8..3af14ad36f 100644 --- a/OsmAnd/res/layout/fragment_wikivoyage_article_dialog.xml +++ b/OsmAnd/res/layout/fragment_wikivoyage_article_dialog.xml @@ -1,12 +1,16 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/wikivoyage_contents_expandablelistview.xml b/OsmAnd/res/layout/wikivoyage_contents_expandablelistview.xml new file mode 100644 index 0000000000..3bf81ee2e5 --- /dev/null +++ b/OsmAnd/res/layout/wikivoyage_contents_expandablelistview.xml @@ -0,0 +1,15 @@ + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/wikivoyage_contents_group_list_item.xml b/OsmAnd/res/layout/wikivoyage_contents_group_list_item.xml new file mode 100644 index 0000000000..98a4b4f794 --- /dev/null +++ b/OsmAnd/res/layout/wikivoyage_contents_group_list_item.xml @@ -0,0 +1,25 @@ + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index f919413655..f4b6b44aa0 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -12,6 +12,7 @@ Read Saved articles Explore + Contents Result Use two digits longitude Travel diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageArticleDialogFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageArticleDialogFragment.java index b8a6f168f7..783154f996 100644 --- a/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageArticleDialogFragment.java +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/WikivoyageArticleDialogFragment.java @@ -1,5 +1,6 @@ package net.osmand.plus.wikivoyage; +import android.content.Intent; import android.content.res.ColorStateList; import android.graphics.drawable.Drawable; import android.os.Build; @@ -21,9 +22,11 @@ import android.widget.TextView; import net.osmand.AndroidUtils; import net.osmand.IndexConstants; import net.osmand.plus.R; +import net.osmand.plus.widgets.TextViewEx; import net.osmand.plus.wikivoyage.data.WikivoyageArticle; import net.osmand.plus.wikivoyage.data.WikivoyageLocalDataHelper; import net.osmand.util.Algorithms; +import net.osmand.plus.wikivoyage.data.WikivoyageArticleContentsBottomSheetDialogFragment; import java.io.File; import java.util.ArrayList; @@ -42,15 +45,18 @@ public class WikivoyageArticleDialogFragment extends WikivoyageBaseDialogFragmen "\n" + "\n" + "\n" + - "\n"; + "\n" + ""; private static final String FOOTER_INNER = ""; private long cityId = NO_VALUE; private ArrayList langs; private String selectedLang; + private String contentsJson; private TextView selectedLangTv; private WebView contentWebView; + private WikivoyageArticleDialogFragment thiss; @Nullable @Override @@ -58,7 +64,7 @@ public class WikivoyageArticleDialogFragment extends WikivoyageBaseDialogFragmen if (savedInstanceState != null) { selectedLang = savedInstanceState.getString(SELECTED_LANG_KEY); } - + thiss = this; final View mainView = inflate(R.layout.fragment_wikivoyage_article_dialog, container); setupToolbar((Toolbar) mainView.findViewById(R.id.toolbar)); @@ -81,6 +87,36 @@ public class WikivoyageArticleDialogFragment extends WikivoyageBaseDialogFragmen } }); + final View buttomBar = mainView.findViewById(R.id.bottom_bar); + + buttomBar.setBackgroundColor(getResolvedColor(isNightMode(false) ? R.color.status_bar_wikivoyage_article_dark : R.color.ctx_menu_card_btn_light)); + + TextViewEx contentsButton = mainView.findViewById(R.id.contents_button); + TextViewEx saveButton = (TextViewEx) mainView.findViewById(R.id.save_text_button); + + saveButton.setCompoundDrawablesWithIntrinsicBounds(null, + null, getMyApplication().getIconsCache() + .getIcon(R.drawable.ic_action_read_later, isNightMode(false) ? + R.color.wikivoyage_active_dark : R.color.ctx_menu_bottom_buttons_text_color_light), null); + + contentsButton.setCompoundDrawablesWithIntrinsicBounds(getIcon(R.drawable.ic_action_list_header, + isNightMode(false) ? R.color.wikivoyage_active_dark : R.color.ctx_menu_bottom_buttons_text_color_light), + null, null, null); + + contentsButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + FragmentManager fm = getActivity().getSupportFragmentManager(); + Bundle args = new Bundle(); + args.putString("CONTENTS_JSON", contentsJson); + WikivoyageArticleContentsBottomSheetDialogFragment fragment = new WikivoyageArticleContentsBottomSheetDialogFragment(); + fragment.setUsedOnMap(false); + fragment.setArguments(args); + fragment.setTargetFragment(thiss, 0); + fragment.show(fm, WikivoyageArticleContentsBottomSheetDialogFragment.TAG); + } + }); + contentWebView = (WebView) mainView.findViewById(R.id.content_web_view); return mainView; @@ -97,6 +133,15 @@ public class WikivoyageArticleDialogFragment extends WikivoyageBaseDialogFragmen outState.putString(SELECTED_LANG_KEY, selectedLang); } + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == 0) { + String link = data.getStringExtra("test"); + moveAnchor(link); + } + } + @Override protected int getStatusBarColor() { return nightMode ? R.color.status_bar_wikivoyage_article_dark : R.color.status_bar_wikivoyage_article_light; @@ -147,12 +192,17 @@ public class WikivoyageArticleDialogFragment extends WikivoyageBaseDialogFragmen if (article == null) { return; } - + contentsJson = article.getContentsJson(); WikivoyageLocalDataHelper.getInstance(getMyApplication()).addToHistory(article); + contentWebView.getSettings().setJavaScriptEnabled(true); contentWebView.loadDataWithBaseURL(getBaseUrl(), createHtmlContent(article), "text/html", "UTF-8", null); } + public void moveAnchor(String id) { + contentWebView.loadUrl("javascript:scrollAnchor(\"" + id + "\")"); + } + @NonNull private String createHtmlContent(@NonNull WikivoyageArticle article) { StringBuilder sb = new StringBuilder(HEADER_INNER); diff --git a/OsmAnd/src/net/osmand/plus/wikivoyage/data/WikivoyageArticleContentsBottomSheetDialogFragment.java b/OsmAnd/src/net/osmand/plus/wikivoyage/data/WikivoyageArticleContentsBottomSheetDialogFragment.java new file mode 100644 index 0000000000..7f49760403 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/wikivoyage/data/WikivoyageArticleContentsBottomSheetDialogFragment.java @@ -0,0 +1,248 @@ +package net.osmand.plus.wikivoyage.data; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.util.DisplayMetrics; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseExpandableListAdapter; +import android.widget.ExpandableListView; +import android.widget.ExpandableListView.OnGroupClickListener; +import android.widget.TextView; +import android.widget.Toast; + +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.base.MenuBottomSheetDialogFragment; +import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; +import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem; +import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; + +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 WikivoyageArticleContentsBottomSheetDialogFragment extends MenuBottomSheetDialogFragment { + + public final static String TAG = "WikivoyageArticleContentsBottomSheetDialogFragment"; + private LinkedHashMap map; + private String link; + private OsmandApplication app; + + @Override + public void createMenuItems(Bundle savedInstanceState) { + Bundle args = getArguments(); + String contentsJson; + if (args != null) { + contentsJson = args.getString("CONTENTS_JSON"); + } else { + return; + } + app = getMyApplication(); + final ArrayList listDataHeader = new ArrayList(); + final LinkedHashMap> listDataChild = new LinkedHashMap>(); + + map = new LinkedHashMap<>(); + JSONObject reader = null; + try { + reader = new JSONObject(contentsJson); + } catch (JSONException e) { + e.printStackTrace(); + return; + } + List 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(); + } + } + + items.add(new TitleItem(getString(R.string.article_contents_title))); + LayoutInflater li = LayoutInflater.from(getContext()); + View view = li.inflate(R.layout.wikivoyage_contents_expandablelistview, null); + ExpandableListView expListView = view.findViewById(R.id.expandableListView); + + ExpandableListAdapter listAdapter = new ExpandableListAdapter(getContext(), listDataHeader, listDataChild); + 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(0); + dismiss(); + return false; + } + }); + DisplayMetrics diaplayMetrics; + int width; + diaplayMetrics = new DisplayMetrics(); + getActivity().getWindowManager().getDefaultDisplay().getMetrics(diaplayMetrics); + width = diaplayMetrics.widthPixels; + if (android.os.Build.VERSION.SDK_INT < 18) { + expListView.setIndicatorBounds(width - ((int) (50 * getResources().getDisplayMetrics().density + 0.5f)), width - ((int) (10 * getResources().getDisplayMetrics().density + 0.5f))); + } else { + expListView.setIndicatorBoundsRelative(width - ((int) (50 * getResources().getDisplayMetrics().density + 0.5f)), width - ((int) (10 * getResources().getDisplayMetrics().density + 0.5f))); + } + expListView.setIndicatorBounds(200, 50); + expListView.setOnGroupClickListener(new OnGroupClickListener() { + @Override + public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) { + link = map.get(listDataHeader.get(groupPosition)); + sendResult(0); + if (listDataChild.get(listDataHeader.get(groupPosition)) == null) { + dismiss(); + } + return false; + } + }); + expListView.setAdapter(listAdapter); + BaseBottomSheetItem favoritesItem = new SimpleBottomSheetItem.Builder() + .setCustomView(view) + .create(); + items.add(favoritesItem); + + } + + private void sendResult(int REQUEST_CODE) { + Intent intent = new Intent(); + intent.putExtra("test", link); + getTargetFragment().onActivityResult( + getTargetRequestCode(), REQUEST_CODE, intent); + } + + @Override + protected boolean useScrollableItemsContainer() { + return false; + } + + class ExpandableListAdapter extends BaseExpandableListAdapter { + + private Context _context; + private List _listDataHeader; + private LinkedHashMap> _listDataChild; + + public ExpandableListAdapter(Context context, List listDataHeader, + LinkedHashMap> listChildData) { + this._context = context; + this._listDataHeader = listDataHeader; + this._listDataChild = listChildData; + } + + @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) { + + final 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_group_list_item, null); + } + + TextView txtListChild = (TextView) convertView.findViewById(R.id.group_label); + + txtListChild.setText(childText); + txtListChild.setTextColor(getResolvedColor(isNightMode() ? R.color.wikivoyage_active_dark : R.color.wikivoyage_active_light)); + txtListChild.setCompoundDrawablesWithIntrinsicBounds(app.getIconsCache() + .getIcon(R.drawable.ic_action_list_bullet, isNightMode() ? + R.color.route_info_unchecked_mode_icon_color : R.color.ctx_menu_nearby_routes_text_color_dark), + null, null, null); + + return convertView; + } + + @Override + public int getChildrenCount(int groupPosition) { + if (this._listDataChild.get(this._listDataHeader.get(groupPosition)) != null) { + return this._listDataChild.get(this._listDataHeader.get(groupPosition)).size(); + } else { + return 0; + } + } + + @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_group_list_item, null); + } + + TextView lblListHeader = (TextView) convertView.findViewById(R.id.group_label); + lblListHeader.setText(headerTitle); + lblListHeader.setTextColor(getResolvedColor(isNightMode() ? R.color.wikivoyage_active_dark : R.color.wikivoyage_active_light)); + lblListHeader.setCompoundDrawablesWithIntrinsicBounds(app.getIconsCache() + .getIcon(R.drawable.ic_action_list_sort, isNightMode() ? + R.color.wikivoyage_active_dark : R.color.wikivoyage_active_light), + null, null, null); + + return convertView; + } + + @Override + public boolean hasStableIds() { + return false; + } + + @Override + public boolean isChildSelectable(int groupPosition, int childPosition) { + return true; + } + } +} \ No newline at end of file