Skip to content

Commit

Permalink
Creates a Focusable Layout Managers and Smooth Scrollers
Browse files Browse the repository at this point in the history
This creates two layout managers and new smooth scroller that
will set the Focus after scrolling has completed.  This gets around
the hack of using a handler to set focus after a delay.  No delay is
need here.
  • Loading branch information
kingargyle committed Oct 31, 2018
1 parent 5727c95 commit 6a4ceb3
Show file tree
Hide file tree
Showing 10 changed files with 78 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import us.nineworlds.serenity.ui.browser.tv.episodes.EpisodePosterOnItemSelectedListener;
import us.nineworlds.serenity.ui.browser.tv.seasons.EpisodePosterOnItemClickListener;
import us.nineworlds.serenity.ui.listeners.GalleryVideoOnItemLongClickListener;
import us.nineworlds.serenity.ui.recyclerview.FocusableLinearLayoutManager;

public class EpisodeVideoGalleryFragment extends InjectingFragment {

Expand Down Expand Up @@ -74,8 +75,11 @@ public EpisodeVideoGalleryFragment() {
videoGallery.setAdapter(adapter);
videoGallery.setItemAnimator(new FadeInAnimator());
videoGallery.setHorizontalFadingEdgeEnabled(false);
videoGallery.setLayoutManager(
new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false));

FocusableLinearLayoutManager linearLayoutManager = new FocusableLinearLayoutManager(getActivity());
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
videoGallery.setLayoutManager(linearLayoutManager);

videoGallery.addItemDecoration(new SpaceItemDecoration(
getResources().getDimensionPixelOffset(R.dimen.horizontal_spacing)));
videoGallery.setClipToPadding(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import us.nineworlds.serenity.ui.listeners.AbstractVideoOnItemSelectedListener;
import us.nineworlds.serenity.ui.listeners.GalleryVideoOnItemClickListener;
import us.nineworlds.serenity.ui.listeners.GalleryVideoOnItemLongClickListener;
import us.nineworlds.serenity.ui.recyclerview.FocusableLinearLayoutManager;

import static android.view.View.*;
import static butterknife.ButterKnife.bind;
Expand Down Expand Up @@ -135,7 +136,7 @@ private AbstractVideoOnItemLongClickListener createOnItemLongClickListener(Movie
}

protected LinearLayoutManager createLayoutManager() {
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
LinearLayoutManager linearLayoutManager = new FocusableLinearLayoutManager(getActivity());
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
return linearLayoutManager;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import us.nineworlds.serenity.ui.browser.movie.MoviePosterImageAdapter;
import us.nineworlds.serenity.ui.browser.movie.MoviePosterOnItemSelectedListener;
import us.nineworlds.serenity.ui.listeners.AbstractVideoOnItemSelectedListener;
import us.nineworlds.serenity.ui.recyclerview.FocusableGridLayoutManager;
import us.nineworlds.serenity.widgets.SerenityMenuGridLayoutManager;

import static butterknife.ButterKnife.bind;
Expand Down Expand Up @@ -66,7 +67,7 @@ public VideoGridFragment() {

protected LinearLayoutManager createLayoutManager() {
GridLayoutManager layoutManager =
new GridLayoutManager(getActivity(), 3,
new FocusableGridLayoutManager(getActivity(), 3,
GridLayoutManager.HORIZONTAL, false);
return layoutManager;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,6 @@ public abstract class SerenityActivity extends InjectingMvpActivity {
}
gallery.smoothScrollToPosition(newPosition);
Timber.d("New ItemPosition: " + newPosition);

scrollingHandler.postDelayed(() -> {
LinearLayoutManager linearLayout = (LinearLayoutManager) gallery.getLayoutManager();
View viewByPosition = linearLayout.findViewByPosition(linearLayout.findFirstVisibleItemPosition());
viewByPosition.requestFocusFromTouch();
}, 200);
return true;
}

Expand All @@ -84,12 +78,6 @@ public abstract class SerenityActivity extends InjectingMvpActivity {
}
gallery.smoothScrollToPosition(newPosition);
Timber.d("New ItemPosition: " + newPosition);
scrollingHandler.postDelayed(() -> {
LinearLayoutManager linearLayout = (LinearLayoutManager) gallery.getLayoutManager();
View viewByPosition = linearLayout.findViewByPosition(linearLayout.findLastCompletelyVisibleItemPosition());
viewByPosition.requestFocusFromTouch();
}, 200);

return true;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,8 @@ public boolean onKeyDown(int keyCode, KeyEvent keyEvent) {
if (newPosition < 0) {
newPosition = 0;
}
tvRecyclerView.scrollToPosition(newPosition);
tvRecyclerView.smoothScrollToPosition(newPosition);
Timber.d("New ItemPosition: " + newPosition);

scrollingHandler.postDelayed(() -> {
LinearLayoutManager linearLayout = (LinearLayoutManager) tvRecyclerView.getLayoutManager();
View viewByPosition = linearLayout.findViewByPosition(linearLayout.findFirstCompletelyVisibleItemPosition());
viewByPosition.requestFocusFromTouch();
}, 700);
return true;
}

Expand All @@ -90,13 +84,8 @@ public boolean onKeyDown(int keyCode, KeyEvent keyEvent) {
if (newPosition > itemsCount) {
newPosition = itemsCount - 1;
}
tvRecyclerView.scrollToPosition(newPosition);
tvRecyclerView.smoothScrollToPosition(newPosition);
Timber.d("New ItemPosition: " + newPosition);
scrollingHandler.postDelayed(() -> {
LinearLayoutManager linearLayout = (LinearLayoutManager) tvRecyclerView.getLayoutManager();
linearLayout.findViewByPosition(linearLayout.findLastCompletelyVisibleItemPosition()).requestFocusFromTouch();
}, 700);

return true;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@
import us.nineworlds.serenity.ui.activity.SerenityMultiViewVideoActivity;
import us.nineworlds.serenity.ui.adapters.AbstractPosterImageGalleryAdapter;
import us.nineworlds.serenity.ui.adapters.MenuDrawerAdapter;
import us.nineworlds.serenity.ui.recyclerview.FocusableGridLayoutManager;
import us.nineworlds.serenity.ui.recyclerview.FocusableLinearLayoutManager;
import us.nineworlds.serenity.ui.util.DisplayUtils;

import static android.view.View.*;
Expand Down Expand Up @@ -111,7 +113,7 @@ public class TVShowBrowserActivity extends SerenityMultiViewVideoActivity

private void populateTVShowContent() {
if (gridViewActive) {
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 3, GridLayoutManager.HORIZONTAL, false);
GridLayoutManager gridLayoutManager = new FocusableGridLayoutManager(this, 3, GridLayoutManager.HORIZONTAL, false);
tvShowRecyclerView.setLayoutManager(gridLayoutManager);

tvShowRecyclerView.addItemDecoration(
Expand All @@ -124,8 +126,8 @@ private void populateTVShowContent() {
return;
}

LinearLayoutManager linearLayoutManager =
new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
LinearLayoutManager linearLayoutManager = new FocusableLinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
tvShowRecyclerView.setLayoutManager(linearLayoutManager);
tvShowRecyclerView.addItemDecoration(
new SpaceItemDecoration(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
import us.nineworlds.serenity.ui.activity.SerenityVideoActivity;
import us.nineworlds.serenity.ui.adapters.AbstractPosterImageGalleryAdapter;
import us.nineworlds.serenity.ui.adapters.MenuDrawerAdapter;
import us.nineworlds.serenity.ui.recyclerview.FocusableGridLayoutManager;
import us.nineworlds.serenity.ui.recyclerview.FocusableLinearLayoutManager;
import us.nineworlds.serenity.ui.util.DisplayUtils;
import us.nineworlds.serenity.widgets.DrawerLayout;

Expand Down Expand Up @@ -98,8 +100,9 @@ protected void setupSeasons() {
tvShowSeasonsGallery.setClipToPadding(false);
tvShowSeasonsGallery.setAdapter(adapter);
tvShowSeasonsGallery.setItemAnimator(new FadeInAnimator());
tvShowSeasonsGallery.setLayoutManager(
new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
LinearLayoutManager linearLayoutManager = new FocusableLinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
tvShowSeasonsGallery.setLayoutManager(linearLayoutManager);

tvShowSeasonsGallery.addItemDecoration(createItemDecorator());
tvShowSeasonsGallery.setFocusable(true);
Expand All @@ -112,7 +115,7 @@ protected void setupSeasons() {
gridView.setAdapter(episodeAdapter);
gridView.addItemDecoration(createItemDecorator());
gridView.setItemAnimator(new FadeInAnimator());
GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 2, GridLayoutManager.HORIZONTAL, false) {
GridLayoutManager gridLayoutManager = new FocusableGridLayoutManager(this, 2, GridLayoutManager.HORIZONTAL, false) {
@Override public boolean supportsPredictiveItemAnimations() {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package us.nineworlds.serenity.ui.recyclerview

import android.content.Context
import android.support.v7.widget.GridLayoutManager
import android.support.v7.widget.RecyclerView

open class FocusableGridLayoutManager(val context: Context, spanCount: Int, orientation: Int, reverseLayout: Boolean) : GridLayoutManager(context, spanCount, orientation, reverseLayout) {

override fun smoothScrollToPosition(recyclerView: RecyclerView?, state: RecyclerView.State?, position: Int) {
val smoothScroller = FocusableLinearSmoothScroller(context)

smoothScroller.targetPosition = position
startSmoothScroll(smoothScroller)
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package us.nineworlds.serenity.ui.recyclerview

import android.content.Context
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView

class FocusableLinearLayoutManager(val context: Context) : LinearLayoutManager(context) {

override fun smoothScrollToPosition(recyclerView: RecyclerView?, state: RecyclerView.State?, position: Int) {
val smoothScroller = FocusableLinearSmoothScroller(context)
smoothScroller.targetPosition = position
startSmoothScroll(smoothScroller)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package us.nineworlds.serenity.ui.recyclerview

import android.content.Context
import android.support.v7.widget.LinearSmoothScroller
import android.support.v7.widget.RecyclerView
import android.view.View

class FocusableLinearSmoothScroller(context: Context) : LinearSmoothScroller(context) {

var targetView : View? = null

override fun onTargetFound(targetView: View?, state: RecyclerView.State?, action: Action?) {
super.onTargetFound(targetView, state, action)
this.targetView = targetView
}

override fun onStop() {
super.onStop()

if (targetView != null && !targetView!!.hasFocus()) {
targetView!!.requestFocusFromTouch()
}
}
}

0 comments on commit 6a4ceb3

Please sign in to comment.