Dbrant has uploaded a new change for review.
https://gerrit.wikimedia.org/r/170698
Change subject: Wikidata description under page title.
......................................................................
Wikidata description under page title.
- Created a more centralized cache of Wikidata descriptions, mapped to
q-numbers, and accessible from other classes.
- Updated the full-text search fragment to make use of this cache.
- Added description text under page title in lead image view.
- Added a nice animation to the page title when the description becomes
available.
Change-Id: I8136bd9a358231884e1e47b027f4ad6e95609570
---
M wikipedia/res/layout/fragment_page.xml
M wikipedia/src/main/java/org/wikipedia/WikipediaApp.java
M wikipedia/src/main/java/org/wikipedia/page/leadimages/LeadImagesHandler.java
M wikipedia/src/main/java/org/wikipedia/search/FullSearchFragment.java
A wikipedia/src/main/java/org/wikipedia/wikidata/WikidataCache.java
5 files changed, 203 insertions(+), 11 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/apps/android/wikipedia
refs/changes/98/170698/1
diff --git a/wikipedia/res/layout/fragment_page.xml
b/wikipedia/res/layout/fragment_page.xml
index 569be91..4caf62e 100644
--- a/wikipedia/res/layout/fragment_page.xml
+++ b/wikipedia/res/layout/fragment_page.xml
@@ -35,10 +35,11 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"/>
- <LinearLayout
+ <FrameLayout
android:id="@+id/page_title_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:orientation="vertical"
android:layout_gravity="bottom">
<TextView
android:id="@+id/page_title_text"
@@ -50,7 +51,18 @@
android:paddingRight="16dp"
android:paddingLeft="16dp"
android:lineSpacingMultiplier="0.9"/>
- </LinearLayout>
+ <TextView
+ android:id="@+id/page_description_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
+ android:visibility="invisible"
+ android:fontFamily="serif"
+ android:paddingBottom="16dp"
+ android:paddingRight="16dp"
+ android:paddingLeft="16dp"
+ android:lineSpacingMultiplier="0.9"/>
+ </FrameLayout>
</FrameLayout>
</FrameLayout>
diff --git a/wikipedia/src/main/java/org/wikipedia/WikipediaApp.java
b/wikipedia/src/main/java/org/wikipedia/WikipediaApp.java
index 46545f5..047dbdd 100644
--- a/wikipedia/src/main/java/org/wikipedia/WikipediaApp.java
+++ b/wikipedia/src/main/java/org/wikipedia/WikipediaApp.java
@@ -40,6 +40,7 @@
import org.wikipedia.search.RecentSearch;
import org.wikipedia.search.RecentSearchPersister;
import org.wikipedia.settings.PrefKeys;
+import org.wikipedia.wikidata.WikidataCache;
import org.wikipedia.zero.WikipediaZeroHandler;
import java.util.ArrayList;
import java.util.Arrays;
@@ -134,6 +135,11 @@
return zeroHandler;
}
+ private WikidataCache wikidataCache;
+ public WikidataCache getWikidataCache() {
+ return wikidataCache;
+ }
+
/**
* Preference manager for storing things like the app's install IDs for
EventLogging, theme,
* font size, etc.
@@ -190,6 +196,7 @@
}
zeroHandler = new WikipediaZeroHandler(this);
+ wikidataCache = new WikidataCache(this);
new PerformMigrationsTask().execute();
}
diff --git
a/wikipedia/src/main/java/org/wikipedia/page/leadimages/LeadImagesHandler.java
b/wikipedia/src/main/java/org/wikipedia/page/leadimages/LeadImagesHandler.java
index 5b782ba..795810f 100644
---
a/wikipedia/src/main/java/org/wikipedia/page/leadimages/LeadImagesHandler.java
+++
b/wikipedia/src/main/java/org/wikipedia/page/leadimages/LeadImagesHandler.java
@@ -6,6 +6,8 @@
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.view.animation.Transformation;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
@@ -17,10 +19,14 @@
import org.json.JSONObject;
import org.wikipedia.R;
import org.wikipedia.Utils;
+import org.wikipedia.ViewAnimations;
import org.wikipedia.WikipediaApp;
import org.wikipedia.bridge.CommunicationBridge;
import org.wikipedia.page.PageViewFragment;
import org.wikipedia.views.ObservableWebView;
+import org.wikipedia.wikidata.WikidataCache;
+
+import java.util.Map;
public class LeadImagesHandler implements
ObservableWebView.OnScrollChangeListener {
private final PageViewFragment parentFragment;
@@ -84,6 +90,7 @@
private ImageView image1;
private View pageTitleContainer;
private TextView pageTitleText;
+ private TextView pageDescriptionText;
private int displayHeight;
private float displayDensity;
@@ -102,6 +109,7 @@
image1 = (ImageView)imageContainer.findViewById(R.id.page_image_1);
pageTitleContainer =
imageContainer.findViewById(R.id.page_title_container);
pageTitleText =
(TextView)imageContainer.findViewById(R.id.page_title_text);
+ pageDescriptionText =
(TextView)imageContainer.findViewById(R.id.page_description_text);
webview.addOnScrollChangeListener(this);
// preload the display density, since it will be used in a lot of
places
@@ -155,6 +163,7 @@
* - Make the lead image view visible.
* - Fire a callback to the provided Listener indicating that the rest of
the WebView content
* can now be loaded.
+ * - Fetch and display the WikiData description for this page, if
available.
*
* Realistically, the whole process will happen very quickly, and almost
unnoticeably to the
* user. But it still needs to be asynchronous because we're dynamically
laying out views, and
@@ -242,6 +251,9 @@
* @param listener Listener that will receive an event when the layout is
completed.
*/
private void layoutViews(OnLeadImageLayoutListener listener) {
+ if (!parentFragment.isAdded()) {
+ return;
+ }
final int webViewPadding;
if (!leadImagesEnabled) {
// ok, we're not going to show lead images, so we need to make some
@@ -257,12 +269,17 @@
pageTitleText.setTextColor(parentFragment
.getResources()
.getColor(Utils.getThemedAttributeId(parentFragment.getActivity(),
R.attr.lead_disabled_text_color)));
+ // and give it no drop shadow
+ pageTitleText.setShadowLayer(0, 0, 0, 0);
+ // do the same for the description...
+ pageDescriptionText.setTextColor(parentFragment
+ .getResources()
+
.getColor(Utils.getThemedAttributeId(parentFragment.getActivity(),
R.attr.lead_disabled_text_color)));
+ pageDescriptionText.setShadowLayer(0, 0, 0, 0);
// remove any background from the title container
pageTitleContainer.setBackgroundColor(Color.TRANSPARENT);
// set the correct to padding on the container
pageTitleContainer.setPadding(0, 0, 0, 0);
- // and give it no drop shadow
- pageTitleText.setShadowLayer(0, 0, 0, 0);
} else {
// we're going to show the lead image, so make some adjustments to
the
// layout, in case we were previously not showing it:
@@ -274,12 +291,15 @@
image1.setVisibility(View.VISIBLE);
// set the color of the title
pageTitleText.setTextColor(parentFragment.getResources().getColor(R.color.lead_text_color));
+ // and give it a nice drop shadow!
+ pageTitleText.setShadowLayer(2, 1, 1,
parentFragment.getResources().getColor(R.color.lead_text_shadow));
+ // do the same for the description...
+
pageDescriptionText.setTextColor(parentFragment.getResources().getColor(R.color.lead_text_color));
+ pageDescriptionText.setShadowLayer(2, 1, 1,
parentFragment.getResources().getColor(R.color.lead_text_shadow));
// set the title container background to be a gradient
pageTitleContainer.setBackgroundResource(R.drawable.lead_title_gradient);
// set the correct padding on the container
pageTitleContainer.setPadding(0, (int) (TITLE_GRADIENT_HEIGHT_DP *
displayDensity), 0, 0);
- // and give it a nice drop shadow!
- pageTitleText.setShadowLayer(2, 1, 1,
parentFragment.getResources().getColor(R.color.lead_text_shadow));
}
// pad the webview contents, to account for the lead image view height
that we've
// ended up with
@@ -294,7 +314,85 @@
// make everything visible!
imageContainer.setVisibility(View.VISIBLE);
+ // tell our listener that it's ok to start loading the rest of the
WebView content
listener.onLayoutComplete();
+
+ // kick off loading of the WikiData description, if we have one
+ // (and only if the lead image is enabled)
+ if (leadImagesEnabled) {
+ fetchWikiDataDescription();
+ }
+ }
+
+ /**
+ * Start the task of fetching the WikiData description for our page, if it
has one.
+ * This should be done after the lead image view is laid out, but can be
done independently
+ * of loading the WebView contents.
+ */
+ private void fetchWikiDataDescription() {
+ final String wikiDataId =
parentFragment.getFragment().getPage().getPageProperties().getWikiDataId();
+
+ if (wikiDataId != null) {
+ WikipediaApp.getInstance().getWikidataCache().get(wikiDataId,
+ new WikidataCache.OnWikidataReceiveListener() {
+ @Override
+ public void onWikidataReceived(Map<String, String> result)
{
+ if (!parentFragment.isAdded()) {
+ return;
+ }
+ if (result.containsKey(wikiDataId)) {
+ layoutWikiDataDescription(result.get(wikiDataId));
+ }
+ }
+ @Override
+ public void onWikidataFailed(Throwable caught) {
+ // don't care
+ }
+ });
+ }
+ }
+
+ /**
+ * Final step in the WikiData description process: lay out the
description, and animate it
+ * into place, along with the page title.
+ * @param description WikiData description to be shown.
+ */
+ private void layoutWikiDataDescription(String description) {
+ // set the text of the description...
+ pageDescriptionText.setText(description);
+ // and wait for it to lay out, so that we know the height of the
description text.
+ pageDescriptionText.post(new Runnable() {
+ @Override
+ public void run() {
+ final int animDuration = 500;
+ final int newMargin = pageDescriptionText.getHeight();
+ // create an animation that will grow the bottom margin of the
Title text,
+ // pushing it upward, and creating sufficient space for the
Description.
+ Animation anim = new Animation() {
+ @Override
+ protected void applyTransformation(float interpolatedTime,
Transformation t) {
+ FrameLayout.LayoutParams params =
(FrameLayout.LayoutParams) pageTitleText.getLayoutParams();
+ params.bottomMargin = (int) (newMargin *
interpolatedTime);
+ pageTitleText.setLayoutParams(params);
+ }
+ };
+ anim.setDuration(animDuration);
+ anim.setAnimationListener(new Animation.AnimationListener() {
+ @Override
+ public void onAnimationStart(Animation animation) {
+ }
+ @Override
+ public void onAnimationRepeat(Animation animation) {
+ }
+ @Override
+ public void onAnimationEnd(Animation animation) {
+ // when the animation finishes, fade in the
description!
+ ViewAnimations.fadeIn(pageDescriptionText);
+ }
+ });
+ pageTitleText.startAnimation(anim);
+ }
+ });
}
}
diff --git
a/wikipedia/src/main/java/org/wikipedia/search/FullSearchFragment.java
b/wikipedia/src/main/java/org/wikipedia/search/FullSearchFragment.java
index fda5370..2685d45 100644
--- a/wikipedia/src/main/java/org/wikipedia/search/FullSearchFragment.java
+++ b/wikipedia/src/main/java/org/wikipedia/search/FullSearchFragment.java
@@ -52,8 +52,6 @@
private FullSearchArticlesTask.FullSearchResults lastResults;
private List<FullSearchResult> totalResults;
- private ParcelableLruCache<String> descriptionCache
- = new ParcelableLruCache<String>(MAX_CACHE_SIZE_DESCRIPTIONS,
String.class);
private ParcelableLruCache<String> pageImagesCache
= new ParcelableLruCache<String>(MAX_CACHE_SIZE_IMAGES,
String.class);
@@ -244,7 +242,7 @@
private void getWikidataDescriptions(List<FullSearchResult> results) {
List<String> idList = new ArrayList<String>();
for (FullSearchResult r : results) {
- if (descriptionCache.get(r.getTitle().getPrefixedText()) == null) {
+ if (app.getWikidataCache().get(r.getWikiBaseId()) == null) {
// not in our cache yet
idList.add(r.getWikiBaseId());
}
@@ -263,7 +261,7 @@
if (entry.getValue() == null) {
continue;
}
- descriptionCache.put(entry.getKey(), entry.getValue());
+ app.getWikidataCache().put(entry.getKey(),
entry.getValue());
}
((BaseAdapter)
searchResultsList.getAdapter()).notifyDataSetChanged();
}
@@ -353,7 +351,7 @@
String wikidataId = result.getWikiBaseId();
if (!TextUtils.isEmpty(wikidataId)) {
TextView descriptionText = (TextView)
convertView.findViewById(R.id.result_description);
- descriptionText.setText(descriptionCache.get(wikidataId));
+
descriptionText.setText(app.getWikidataCache().get(wikidataId));
}
ImageView imageView = (ImageView)
convertView.findViewById(R.id.result_image);
diff --git a/wikipedia/src/main/java/org/wikipedia/wikidata/WikidataCache.java
b/wikipedia/src/main/java/org/wikipedia/wikidata/WikidataCache.java
new file mode 100644
index 0000000..6250f3a
--- /dev/null
+++ b/wikipedia/src/main/java/org/wikipedia/wikidata/WikidataCache.java
@@ -0,0 +1,77 @@
+package org.wikipedia.wikidata;
+
+import org.wikipedia.ParcelableLruCache;
+import org.wikipedia.WikipediaApp;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class WikidataCache {
+ private static final int MAX_CACHE_SIZE_DESCRIPTIONS = 96;
+
+ private WikipediaApp app;
+ private ParcelableLruCache<String> descriptionCache
+ = new ParcelableLruCache<String>(MAX_CACHE_SIZE_DESCRIPTIONS,
String.class);
+
+ public WikidataCache(WikipediaApp app) {
+ this.app = app;
+ }
+
+ public void put(String key, String value) {
+ descriptionCache.put(key, value);
+ }
+
+ public String get(String id) {
+ return descriptionCache.get(id);
+ }
+
+ public void get(String id, OnWikidataReceiveListener listener) {
+ List<String> idList = new ArrayList<String>();
+ idList.add(id);
+ get(idList, listener);
+ }
+
+ public void get(List<String> ids, final OnWikidataReceiveListener
listener) {
+ final Map<String, String> results = new HashMap<String, String>();
+ List<String> idsToFetch = new ArrayList<String>();
+ for (String id : ids) {
+ if (descriptionCache.get(id) == null) {
+ // not in our cache yet
+ idsToFetch.add(id);
+ } else {
+ results.put(id, descriptionCache.get(id));
+ }
+ }
+ if (idsToFetch.size() > 0) {
+ (new WikidataDescriptionsTask(
+ app.getAPIForSite(new WikidataSite()),
+ app.getPrimaryLanguage(),
+ ids) {
+ @Override
+ public void onFinish(Map<String, String> result) {
+ for (Map.Entry<String, String> entry : result.entrySet()) {
+ if (entry.getValue() == null) {
+ continue;
+ }
+ descriptionCache.put(entry.getKey(), entry.getValue());
+ results.put(entry.getKey(), entry.getValue());
+ }
+ listener.onWikidataReceived(results);
+ }
+ @Override
+ public void onCatch(Throwable caught) {
+ listener.onWikidataFailed(caught);
+ }
+ }).execute();
+ } else {
+ listener.onWikidataReceived(results);
+ }
+ }
+
+ public interface OnWikidataReceiveListener {
+ public void onWikidataReceived(Map<String, String> result);
+ public void onWikidataFailed(Throwable caught);
+ }
+}
--
To view, visit https://gerrit.wikimedia.org/r/170698
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I8136bd9a358231884e1e47b027f4ad6e95609570
Gerrit-PatchSet: 1
Gerrit-Project: apps/android/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Dbrant <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits