From 89530eaabcfc52607806ccca447571d01b04682d Mon Sep 17 00:00:00 2001 From: Andrzej Hunt Date: Thu, 16 Feb 2017 18:42:46 -0800 Subject: [PATCH] Bug 1339520 - Keep existing TopPanel when cursor is swapped r=sebastian By default RecyclerView assumes any item change *might* need animation. It then creates a new copy of the item that has changed, and interpolates between the two to "animate" the change. We don't need that for topsites (the RecyclerView's we use inside each TopSitePanel already animate changes, the overall size doesn't change - moreover ViewPager state gets lost if you create a new panel), so we override this behaviour to retain the existing panel. This stops the previously visible horrible flickering. (Every time history changes, which can happen if sync is working, or even if a page finishes loading in the background, the DB is changed, and a reload is triggered. Prior to this commit, topsites would flicker horribly, and would reset back to the first topsites page. After this commit the page is retained, and the visible topsites are rearranged by the inner RecyclerView's animations. You can test this by pinning a site on the first page, the pinned site will shift to the front, the other sites smoothly move to the right.) MozReview-Commit-ID: CnocNfdQ2FS --HG-- extra : rebase_source : 3a4e1d86c786126aee1e08ab020b855056e4f921 --- .../home/activitystream/ActivityStream.java | 2 ++ .../activitystream/StreamItemAnimator.java | 30 +++++++++++++++++++ mobile/android/base/moz.build | 1 + 3 files changed, 33 insertions(+) create mode 100644 mobile/android/base/java/org/mozilla/gecko/home/activitystream/StreamItemAnimator.java diff --git a/mobile/android/base/java/org/mozilla/gecko/home/activitystream/ActivityStream.java b/mobile/android/base/java/org/mozilla/gecko/home/activitystream/ActivityStream.java index d0b9e4628170..a9ae5c77cb14 100644 --- a/mobile/android/base/java/org/mozilla/gecko/home/activitystream/ActivityStream.java +++ b/mobile/android/base/java/org/mozilla/gecko/home/activitystream/ActivityStream.java @@ -51,6 +51,8 @@ public class ActivityStream extends FrameLayout { rv.setAdapter(adapter); rv.setLayoutManager(new LinearLayoutManager(getContext())); rv.setHasFixedSize(true); + // Override item animations to avoid horrible topsites refreshing + rv.setItemAnimator(new StreamItemAnimator()); RecyclerViewClickSupport.addTo(rv) .setOnItemClickListener(adapter); diff --git a/mobile/android/base/java/org/mozilla/gecko/home/activitystream/StreamItemAnimator.java b/mobile/android/base/java/org/mozilla/gecko/home/activitystream/StreamItemAnimator.java new file mode 100644 index 000000000000..b17563cd8be9 --- /dev/null +++ b/mobile/android/base/java/org/mozilla/gecko/home/activitystream/StreamItemAnimator.java @@ -0,0 +1,30 @@ +/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +package org.mozilla.gecko.home.activitystream; + +import android.support.annotation.NonNull; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.RecyclerView; + +import org.mozilla.gecko.home.activitystream.stream.TopPanel; + +/** + * We need our own item animator override to avoid default RV-style animations for certain panels. + */ +public class StreamItemAnimator extends DefaultItemAnimator { + + @Override + public boolean canReuseUpdatedViewHolder(@NonNull RecyclerView.ViewHolder viewHolder) { + if (viewHolder.getItemViewType() == TopPanel.LAYOUT_ID) { + // The top panel doesn't ever change in size. We really don't want to reload it + // because it has its own state (i.e. the ViewPager state gets lost, and we + // also flicker when creating a new ViewHolder). Therefore we should try to + // keep the existing TopPanel whenever possible. + return true; + } + + return super.canReuseUpdatedViewHolder(viewHolder); + } +} diff --git a/mobile/android/base/moz.build b/mobile/android/base/moz.build index ddad86b9dfae..e171b45e1b99 100644 --- a/mobile/android/base/moz.build +++ b/mobile/android/base/moz.build @@ -473,6 +473,7 @@ gbjar.sources += ['java/org/mozilla/gecko/' + x for x in [ 'home/activitystream/stream/StreamItem.java', 'home/activitystream/stream/TopPanel.java', 'home/activitystream/stream/WelcomePanel.java', + 'home/activitystream/StreamItemAnimator.java', 'home/activitystream/StreamRecyclerAdapter.java', 'home/activitystream/topsites/CirclePageIndicator.java', 'home/activitystream/topsites/TopSitesCard.java',