Bug 1359363 - Apply diffutil to search list updates for smoother ui experience.;r=petru

Differential Revision: https://phabricator.services.mozilla.com/D37733

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Brad Arant 2019-07-22 06:58:29 +00:00
Родитель 617b075a9c
Коммит c049730cc6
2 изменённых файлов: 114 добавлений и 32 удалений

Просмотреть файл

@ -5,22 +5,26 @@
package org.mozilla.gecko.preferences;
import android.content.Context;
import android.preference.Preference;
import android.support.annotation.Nullable;
import android.support.v7.util.DiffUtil;
import android.support.v7.util.ListUpdateCallback;
import android.util.AttributeSet;
import android.util.Log;
import org.mozilla.gecko.EventDispatcher;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.Telemetry;
import org.mozilla.gecko.TelemetryContract;
import org.mozilla.gecko.TelemetryContract.Method;
import org.mozilla.gecko.search.SearchEngineDiffCallback;
import org.mozilla.gecko.util.BundleEventListener;
import org.mozilla.gecko.util.EventCallback;
import org.mozilla.gecko.util.GeckoBundle;
import org.mozilla.gecko.util.ThreadUtils;
public class SearchPreferenceCategory extends CustomListCategory implements BundleEventListener {
import java.util.ArrayList;
import java.util.List;
public class SearchPreferenceCategory extends CustomListCategory implements BundleEventListener, ListUpdateCallback {
public static final String LOGTAG = "SearchPrefCategory";
private List<SearchEnginePreference> enginesList = new ArrayList<>();
public SearchPreferenceCategory(Context context) {
super(context);
@ -74,44 +78,65 @@ public class SearchPreferenceCategory extends CustomListCategory implements Bund
public void handleMessage(final String event, final GeckoBundle data,
final EventCallback callback) {
if (event.equals("SearchEngines:Data")) {
// Parse engines array from bundle.
final GeckoBundle[] engines = data.getBundleArray("searchEngines");
// Parse engines array from bundle into ArrayList.
GeckoBundle[] engines = data.getBundleArray("searchEngines");
List<SearchEnginePreference> newEngineList = new ArrayList<>();
// Clear the preferences category from this thread.
this.removeAll();
// Create an element in this PreferenceCategory for each engine.
for (int i = 0; i < engines.length; i++) {
final GeckoBundle engine = engines[i];
final SearchEnginePreference enginePreference =
for (GeckoBundle engine: engines) {
SearchEnginePreference enginePreference =
new SearchEnginePreference(getContext(), this);
enginePreference.setSearchEngineFromBundle(engine);
enginePreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
SearchEnginePreference sPref = (SearchEnginePreference) preference;
// Display the configuration dialog associated with the tapped engine.
sPref.showDialog();
return true;
}
enginePreference.setOnPreferenceClickListener(preference -> {
SearchEnginePreference sPref = (SearchEnginePreference) preference;
// Display the configuration dialog associated with the tapped engine.
sPref.showDialog();
return true;
});
addPreference(enginePreference);
newEngineList.add(enginePreference);
}
if (i != 0) {
continue;
}
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new SearchEngineDiffCallback(enginesList, newEngineList));
enginesList = newEngineList;
diffResult.dispatchUpdatesTo(this);
}
}
// The first element in the array is the default engine.
// We set this here, not in setSearchEngineFromBundle, because it allows us to
// keep a reference to the default engine to use when the AlertDialog
// callbacks are used.
enginePreference.setIsDefault(true);
mDefaultReference = enginePreference;
@Override
public void onInserted(int pos, int count) {
for (int ix = pos; ix < (pos + count); ++ix) {
addPreference(enginesList.get(ix));
// The first element in the array is the default engine.
// We set this here, not in setSearchEngineFromBundle, because it allows us to
// keep a reference to the default engine to use when the AlertDialog
// callbacks are used.
if (ix == 0) {
enginesList.get(ix).setIsDefault(true);
mDefaultReference = enginesList.get(ix);
}
}
}
// The onRemoved, onMoved and onChanged entries are not used here as the list is never reordered
// by the clicking of the completion checkbox preference which activates this code.
@Override
public void onRemoved(int pos, int count) {
}
@Override
public void onMoved(int i, int i1) {
}
@Override
public void onChanged(int i, int i1, @Nullable Object o) {
}
/**
* Helper method to send a particular event string to Gecko with an associated engine name.
* @param event The type of event to send.

Просмотреть файл

@ -0,0 +1,57 @@
/* 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.search;
import android.support.annotation.Nullable;
import android.support.v7.util.DiffUtil;
import org.mozilla.gecko.preferences.SearchEnginePreference;
import java.util.List;
/**
* SearchEngineDiffCallback.java - class used by diffutils to maintain List differential array.
* @author Brad Arant
* @version
* @see SearchPreferenceCategory
*/
public class SearchEngineDiffCallback extends DiffUtil.Callback {
private List<SearchEnginePreference> oldList;
private List<SearchEnginePreference> newList;
public SearchEngineDiffCallback(List<SearchEnginePreference> oldList, List<SearchEnginePreference> newList) {
this.oldList = oldList;
this.newList = newList;
}
@Override
public int getOldListSize() {
return oldList.size();
}
@Override
public int getNewListSize() {
return newList.size();
}
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
return oldList.get(oldItemPosition).getIdentifier().equals(newList.get(newItemPosition).getIdentifier());
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
if (oldList.get(oldItemPosition).getTitle() != newList.get(newItemPosition).getTitle()) {
return false;
}
return oldList.get(oldItemPosition).getIdentifier().equals(newList.get(newItemPosition).getIdentifier());
}
@Nullable
@Override
public Object getChangePayload(int oldItemPosition, int newItemPosition) {
return super.getChangePayload(oldItemPosition, newItemPosition);
}
}