UI Improvement for Place Description Display #10087
2 changed files with 161 additions and 27 deletions
|
@ -1,13 +1,16 @@
|
|||
package app.organicmaps.widget.placepage;
|
||||
|
||||
import android.content.res.Configuration;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import app.organicmaps.R;
|
||||
import app.organicmaps.base.BaseMwmFragment;
|
||||
|
@ -16,33 +19,161 @@ import app.organicmaps.util.WindowInsetUtils;
|
|||
|
||||
import java.util.Objects;
|
||||
|
||||
public class PlaceDescriptionFragment extends BaseMwmFragment
|
||||
{
|
||||
public static final String EXTRA_DESCRIPTION = "description";
|
||||
private static final String SOURCE_SUFFIX = "<p><b>wikipedia.org</b></p>";
|
||||
public class PlaceDescriptionFragment extends BaseMwmFragment {
|
||||
public static final String EXTRA_DESCRIPTION = "description";
|
||||
private String getSourceSuffix() {
|
||||
return "<p>" + getString(R.string.article_from_wikipedia) + "</p>";
|
||||
}
|
||||
|
||||
@SuppressWarnings("NullableProblems")
|
||||
@NonNull
|
||||
private String mDescription;
|
||||
private WebView webView;
|
||||
|
||||
@SuppressWarnings("NullableProblems")
|
||||
@NonNull
|
||||
private String mDescription;
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
mDescription = Objects.requireNonNull(requireArguments()
|
||||
.getString(EXTRA_DESCRIPTION));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
mDescription = Objects.requireNonNull(requireArguments()
|
||||
.getString(EXTRA_DESCRIPTION));
|
||||
}
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View root = inflater.inflate(R.layout.fragment_place_description, container, false);
|
||||
webView = root.findViewById(R.id.webview);
|
||||
|
||||
setupWebView();
|
||||
loadDescriptionWithAdaptiveStyling();
|
||||
|
||||
ViewCompat.setOnApplyWindowInsetsListener(root, WindowInsetUtils.PaddingInsetsListener.excludeTop());
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
View root = inflater.inflate(R.layout.fragment_place_description, container, false);
|
||||
WebView webView = root.findViewById(R.id.webview);
|
||||
webView.loadData(mDescription + SOURCE_SUFFIX, Utils.TEXT_HTML, Utils.UTF_8);
|
||||
webView.setVerticalScrollBarEnabled(true);
|
||||
ViewCompat.setOnApplyWindowInsetsListener(root, WindowInsetUtils.PaddingInsetsListener.excludeTop());
|
||||
return root;
|
||||
}
|
||||
}
|
||||
private void setupWebView() {
|
||||
webView.setVerticalScrollBarEnabled(true);
|
||||
webView.setWebViewClient(new WebViewClient());
|
||||
webView.getSettings().setDefaultTextEncodingName("utf-8");
|
||||
webView.setBackgroundColor(getResources().getColor(android.R.color.transparent));
|
||||
}
|
||||
|
||||
private void loadDescriptionWithAdaptiveStyling() {
|
||||
|
||||
// Determine current theme (light/dark)
|
||||
int nightModeFlags = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
|
||||
boolean isDarkMode = nightModeFlags == Configuration.UI_MODE_NIGHT_YES;
|
||||
|
||||
// Adaptive color scheme
|
||||
String textColor = String.format("#%06X", (0xFFFFFF & ContextCompat.getColor(requireContext(),
|
||||
isDarkMode ? R.color.text_light : R.color.text_dark)));
|
||||
|
||||
String backgroundColor = String.format("#%06X", (0xFFFFFF & ContextCompat.getColor(requireContext(),
|
||||
isDarkMode ? R.color.bg_window_night : R.color.bg_window)));
|
||||
|
||||
String headingColor = String.format("#%06X", (0xFFFFFF & ContextCompat.getColor(requireContext(),
|
||||
isDarkMode ? R.color.text_light : R.color.text_dark)));
|
||||
|
||||
String linkColor = String.format("#%06X", (0xFFFFFF & ContextCompat.getColor(requireContext(),
|
||||
isDarkMode ? R.color.base_accent_night : R.color.base_accent)));
|
||||
|
||||
// Comprehensive HTML and CSS
|
||||
String htmlContent = "<!DOCTYPE html>" +
|
||||
"<html>" +
|
||||
"<head>" +
|
||||
"<meta charset='utf-8'>" +
|
||||
"<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no'>" +
|
||||
"<style>" +
|
||||
"* {" +
|
||||
" box-sizing: border-box;" +
|
||||
" margin: 0;" +
|
||||
" padding: 0;" +
|
||||
"}" +
|
||||
"html, body {" +
|
||||
" width: 100%;" +
|
||||
" max-width: 100%;" +
|
||||
" overflow-x: hidden;" +
|
||||
"}" +
|
||||
"body {" +
|
||||
" width: 90%;" +
|
||||
" max-width: 800px;" +
|
||||
" margin: 0 auto;" +
|
||||
" padding: 5% 2.5%;" +
|
||||
" font-family: Roboto, sans-serif;" +
|
||||
" line-height: 1.6;" +
|
||||
" font-size: calc(14px + 0.5vw);" +
|
||||
" color: " + textColor + ";" +
|
||||
" background-color: " + backgroundColor + ";" +
|
||||
"}" +
|
||||
"h2, h3 {" +
|
||||
" width: 100%;" +
|
||||
" text-align: left;" +
|
||||
" color: " + headingColor + ";" +
|
||||
" margin: 3% 0 1% 0;" +
|
||||
" padding-bottom: 0.5%;" +
|
||||
" font-weight: 600;" +
|
||||
"}" +
|
||||
"h2 {" +
|
||||
" font-size: calc(1.5em + 0.5vw);" +
|
||||
" margin-top: 4%;" +
|
||||
"}" +
|
||||
"h3 {" +
|
||||
" font-size: calc(1.2em + 0.4vw);" +
|
||||
" margin-top: 2%;" +
|
||||
"}" +
|
||||
"p {" +
|
||||
" margin-bottom: 3%;" +
|
||||
" text-align: justify;" +
|
||||
" hyphens: auto;" +
|
||||
" width: 100%;" +
|
||||
"}" +
|
||||
"ul, ol {" +
|
||||
" margin-bottom: 3%;" +
|
||||
" padding-left: 5%;" +
|
||||
" width: 100%;" +
|
||||
"}" +
|
||||
"li {" +
|
||||
" margin-bottom: 1.5%;" +
|
||||
"}" +
|
||||
"a {" +
|
||||
" color: " + linkColor + ";" +
|
||||
" text-decoration: none;" +
|
||||
"}" +
|
||||
"b {" +
|
||||
" font-weight: 600;" +
|
||||
"}" +
|
||||
"sup {" +
|
||||
" font-size: 0.6em;" +
|
||||
" vertical-align: super;" +
|
||||
"}" +
|
||||
"@media screen and (max-width: 600px) {" +
|
||||
" body {" +
|
||||
" width: 95%;" +
|
||||
" padding: 3% 2.5%;" +
|
||||
" font-size: calc(12px + 0.5vw);" +
|
||||
" }" +
|
||||
" h2 {" +
|
||||
" font-size: calc(1.3em + 0.5vw);" +
|
||||
" }" +
|
||||
" h3 {" +
|
||||
" font-size: calc(1em + 0.4vw);" +
|
||||
" }" +
|
||||
"}" +
|
||||
"</style>" +
|
||||
"</head>" +
|
||||
"<body>" +
|
||||
mDescription +
|
||||
getSourceSuffix() +
|
||||
"</body>" +
|
||||
"</html>";
|
||||
|
||||
webView.loadDataWithBaseURL(null, htmlContent, "text/html", "UTF-8", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(@NonNull Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
loadDescriptionWithAdaptiveStyling();
|
||||
}
|
||||
}
|
|
@ -428,6 +428,8 @@
|
|||
<string name="clear_search">Clear Search History</string>
|
||||
<!-- Place Page link to Wikipedia article (if map object has it). -->
|
||||
<string name="read_in_wikipedia">Wikipedia</string>
|
||||
<!-- Source attribution for Wikipedia articles -->
|
||||
<string name="article_from_wikipedia">Article from wikipedia.org</string>
|
||||
<!-- Place Page link to Wikimedia Commons. -->
|
||||
<string name="wikimedia_commons">Wikimedia Commons</string>
|
||||
<string name="p2p_your_location">Your Location</string>
|
||||
|
@ -2289,4 +2291,5 @@
|
|||
<string name="type.amenity.dojo">Dojo</string>
|
||||
<!-- https://wiki.openstreetmap.org/wiki/Tag:leisure=sports_hall -->
|
||||
<string name="type.leisure.sports_hall">Sports hall</string>
|
||||
|
||||
</resources>
|
||||
|
|
Reference in a new issue