Package structure: moved UI utilities.

Part of #963.
This commit is contained in:
Dennis Guse
2022-01-15 20:35:17 +01:00
parent 2ca69df447
commit 10f00c4c99
4 changed files with 5 additions and 5 deletions
@@ -34,7 +34,6 @@ import androidx.loader.content.Loader;
import de.dennisguse.opentracks.AbstractActivity;
import de.dennisguse.opentracks.ContextualActionModeCallback;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.adapters.ScrollVisibleViews;
import de.dennisguse.opentracks.content.data.Marker;
import de.dennisguse.opentracks.content.data.MarkerColumns;
import de.dennisguse.opentracks.content.data.Track;
@@ -43,6 +42,7 @@ import de.dennisguse.opentracks.databinding.MarkerListBinding;
import de.dennisguse.opentracks.services.TrackRecordingService;
import de.dennisguse.opentracks.services.TrackRecordingServiceConnection;
import de.dennisguse.opentracks.ui.markers.DeleteMarkerDialogFragment.DeleteMarkerCaller;
import de.dennisguse.opentracks.ui.util.ScrollVisibleViews;
import de.dennisguse.opentracks.util.ActivityUtils;
import de.dennisguse.opentracks.util.IntentUtils;
@@ -23,11 +23,11 @@ import java.time.Instant;
import java.time.OffsetDateTime;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.adapters.ExecutorListViewService;
import de.dennisguse.opentracks.adapters.ScrollVisibleViews;
import de.dennisguse.opentracks.content.data.MarkerColumns;
import de.dennisguse.opentracks.content.data.Track;
import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
import de.dennisguse.opentracks.ui.util.ExecutorListViewService;
import de.dennisguse.opentracks.ui.util.ScrollVisibleViews;
import de.dennisguse.opentracks.util.ListItemUtils;
public class MarkerResourceCursorAdapter extends ResourceCursorAdapter implements ScrollVisibleViews.VisibleViewsListener {
@@ -0,0 +1,78 @@
package de.dennisguse.opentracks.ui.util;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
* ExecutorService wrap that avoid the execution of the same object in a ListView.
*
* @param <T> the type of the object that will be used to identified the Runnable.
*/
public class ExecutorListViewService<T> {
private final List<T> enqueueObjects = new ArrayList<>();
private final ExecutorService executorService;
public ExecutorListViewService(int numThreads) {
executorService = Executors.newFixedThreadPool(numThreads);
}
public void shutdown() {
enqueueObjects.clear();
executorService.shutdown();
}
/**
* Execute the runnable for the object.
*
* @param object the Object.
* @param runnable the Runnable.
*/
public void execute(T object, Runnable runnable) {
if (!preExecute(object)) {
return;
}
new Thread(() -> {
Future<?> future = executorService.submit(runnable);
try {
future.get();
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
postExecute(object);
}).start();
}
/**
* Before execution it must checks if the object is already enqueued.
*
* @param object the object to check.
* @return true if it can be executed or false otherwise.
*/
private boolean preExecute(T object) {
synchronized (enqueueObjects) {
if (!enqueueObjects.contains(object)) {
enqueueObjects.add(object);
return true;
} else {
return false;
}
}
}
/**
* After execution remove the object from the queue.
*
* @param object the object to be removed from the queue.
*/
private void postExecute(T object) {
synchronized (enqueueObjects) {
enqueueObjects.remove(object);
}
}
}
@@ -0,0 +1,42 @@
package de.dennisguse.opentracks.ui.util;
import android.view.View;
import android.widget.AbsListView;
import androidx.annotation.NonNull;
/**
* AbsListView.OnScrollListener class that can be used to know what views in a ListView are currently visible while scrolling.
*/
public class ScrollVisibleViews implements AbsListView.OnScrollListener {
private int from = -1;
private int to = -1;
private final VisibleViewsListener visibleViewsListener;
public ScrollVisibleViews(@NonNull VisibleViewsListener visibleViewsListener) {
this.visibleViewsListener = visibleViewsListener;
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE || scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING || scrollState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
if (from >= 0 && to >= 0) {
for (int i = from; i < to; i++) {
View viewChild = view.getChildAt(i - from);
visibleViewsListener.onViewVisible(viewChild, i);
}
}
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
from = firstVisibleItem;
to = firstVisibleItem + visibleItemCount;
}
public interface VisibleViewsListener {
void onViewVisible(View view, int position);
}
}