package com.perflyst.twire.activities.main; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import com.google.android.material.snackbar.Snackbar; import com.perflyst.twire.R; import com.perflyst.twire.misc.LazyFetchingOnScrollListener; import com.perflyst.twire.tasks.GetVisualElementsTask; /** * Main Activity that loads it's content only when it is needed. */ public abstract class LazyMainActivity<T> extends MainActivity implements LazyFetchingActivity<T> { protected LazyFetchingOnScrollListener<T> mOnScrollListener; protected Snackbar snackbar; protected int currentOffset = 0; protected int elementsToFetchLimit = 10; protected int maxElementsToFetch = 500; /** * Refreshes the Activity's visual elements by clearing the adapter and setting the current offset to one. * After the adapter is finished clearing, new elements will be loaded and added. */ @Override public void refreshElements() { int duration = mAdapter.clear(); // Fetch new elements after the adapter animations are done // ToDo: These elements should be loaded while the animations are running. But not be added until the animations are done. new Handler().postDelayed(() -> { setCurrentOffset(0); getRecyclerView().scrollToPosition(0); GetVisualElementsTask<T> getTopGamesTask = new GetVisualElementsTask<>(LazyMainActivity.this); getTopGamesTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); }, duration); } @Override protected void onCreate(Bundle savedInstance) { super.onCreate(savedInstance); // Set up the snackbar for when the user experience a no reply from twitch's servers snackbar = setupSnackbar(); mSwipeRefreshLayout.setProgressViewOffset(true, (int) getResources().getDimension(R.dimen.swipe_refresh_start_offset), (int) getResources().getDimension(R.dimen.swipe_refresh_end_offset)); mSwipeRefreshLayout.setOnRefreshListener(this::refreshElements); // Set up the specialized OnScrollListener mRecyclerView.clearOnScrollListeners(); mOnScrollListener = new LazyFetchingOnScrollListener<>( this, mMainToolbar, mDecorativeToolbar, mToolbarShadow, mCircleIconWrapper, mTitleView, LOG_TAG, this, true ); mScrollListener = mOnScrollListener; mRecyclerView.addOnScrollListener(mScrollListener); GetVisualElementsTask<T> getElementsTask = new GetVisualElementsTask<>(this); getElementsTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } @Override public void onResume() { super.onResume(); if (currentOffset == 0) { startRefreshing(); } } @Override public void onBackPressed() { super.onBackPressed(); hideErrorView(); } private Snackbar setupSnackbar() { String responseMessage = getResources().getString(R.string.no_server_response_message); String actionString = getResources().getString(R.string.no_server_response_action); Snackbar snackbar = Snackbar .make(mRecyclerView, responseMessage, Snackbar.LENGTH_LONG); snackbar.setAction(actionString, v -> scrollToTopAndRefresh()); return snackbar; } protected void shouldShowErrorView() { runOnUiThread(() -> { if (mErrorEmoteView != null && mErrorView != null) { if (getMaxElementsToFetch() == 0) { showErrorView(); } else { hideErrorView(); } } }); } @Override public void notifyUserNoElementsAdded() { if (mAdapter.getItemCount() == 0 && mAdapter.getItemCount() != getMaxElementsToFetch()) { if (!snackbar.isShown()) { snackbar.show(); } } } @Override public void checkIsBackFromMainActivity() { shouldShowErrorView(); super.checkIsBackFromMainActivity(); } @Override public void startProgress() { mProgressView.start(); } @Override public void stopProgress() { mProgressView.stop(); } @Override public void startRefreshing() { mSwipeRefreshLayout.setRefreshing(true); } @Override public void stopRefreshing() { mSwipeRefreshLayout.setRefreshing(false); } @Override public int getMaxElementsToFetch() { return maxElementsToFetch; } @Override public void setMaxElementsToFetch(int maxElementsToFetch) { this.maxElementsToFetch = maxElementsToFetch; } @Override public int getCurrentOffset() { return currentOffset; } @Override public void setCurrentOffset(int currentOffset) { this.currentOffset = currentOffset; } @Override public int getLimit() { return elementsToFetchLimit; } @Override public void setLimit(int aLimit) { elementsToFetchLimit = aLimit; } }