'disable the scroll effect of the action list
I've got a GuidedStepSupportFragment fragment like this.
public class SampleStepFragment extends GuidedStepSupportFragment {
@NonNull
@Override
public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) {
String title = "Title";
String breadcrumb = "Breadcrumb";
String description = "Description";
Drawable icon = getActivity().getDrawable(R.drawable.ic_videocam_black_24dp);
return new GuidanceStylist.Guidance(title, description, breadcrumb, icon);
}
@Override
public void onCreateActions(@NonNull List<GuidedAction> actions, Bundle savedInstanceState) {
addAction(actions, ACTION_CONTINUE, "Action1");
addAction(actions, ACTION_BACK, "Action2");
}
}
Problem: When I scroll the action list, it shows like this;
But I want to something like this;
How can I disable this effect on my action list?
Thanks
Solution 1:[1]
I managed it and it wasn't easy to figure out.
There's no supported way of doing it, since the APIs that actually make this possible are package private or hidden from public use on purpose. (You can do it yourself, but you just end up copying classes from the leanback libraries.)
The solution:
@Override
public void onCreateActions(@NonNull List<GuidedAction> actions, Bundle savedInstanceState) {
addAction(actions, GuidedAction.ACTION_ID_CONTINUE, "Action1");
addAction(actions, GuidedAction.ACTION_ID_CANCEL, "Action2");
// Run code delayed on mainThread (any other/better method can/should be used)
// It's delayed because if focus scroll is disabled, the list will stick to the top of the layout
new Handler(Looper.getMainLooper()).postDelayed(this::disableFocusScroll, 500);
}
private void disableFocusScroll() {
RecyclerView.LayoutManager layoutManager = SampleStepFragment.this.getGuidedActionsStylist().getActionsGridView().getLayoutManager();
try {
Method method = layoutManager.getClass().getMethod("setFocusScrollStrategy", int.class);
method.invoke(layoutManager, 1 /* FOCUS_SCROLL_ITEM */);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
Log.e(TAG, "disableFocusScroll: ", e);
}
}
The explanation:
A GuidedStepSupportFragment requests a GuidedActionsStylist which is responsible for rendering the list items on the right side. source
The GuidedActionsStylist stylist inflates the layout lb_guidedactions.xml which contains a VerticalGridView source
The VerticalGridView extends BaseGridView and creates a GridLayoutManager as its layout manager. This GridLayoutManager is sadly package private and final... (android why..?). It has the method setFocusScrollStrategy which is used to determine how scrolling behaves.source
See the different focus scroll strategies:
/**
* Always keep focused item at a aligned position. Developer can use
* WINDOW_ALIGN_XXX and ITEM_ALIGN_XXX to define how focused item is aligned.
* In this mode, the last focused position will be remembered and restored when focus
* is back to the view.
* @hide
*/
@RestrictTo(LIBRARY_GROUP)
public final static int FOCUS_SCROLL_ALIGNED = 0;
/**
* Scroll to make the focused item inside client area.
* @hide
*/
@RestrictTo(LIBRARY_GROUP)
public final static int FOCUS_SCROLL_ITEM = 1;
/**
* Scroll a page of items when focusing to item outside the client area.
* The page size matches the client area size of RecyclerView.
* @hide
*/
@RestrictTo(LIBRARY_GROUP)
public final static int FOCUS_SCROLL_PAGE = 2;
So since the API is hidden, we just use reflection to expose the setFocusScrollStrategy method and set it to FOCUS_SCROLL_ITEM.
We can't do this immediately though, since without the default scroll setting, the list items will pop to the top of the layout and won't stay centered. So I added a delay of 500ms which is horrible... If you manage to find out when it's best to trigger this, let me know.
Solution 2:[2]
It turns out there is a much more elegant and simpler solution. It is enough to add to the body of onViewCreated in the class that inherits guideStepSupportFragment windowAlignment option (there are other alignment options):
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// ...
val gridView = guidedActionsStylist.actionsGridView
gridView.windowAlignment = VerticalGridView.WINDOW_ALIGN_BOTH_EDGE
// ...
super.onViewCreated(view, savedInstanceState)
}
Solution 3:[3]
Here is a simple way to disable VerticalGridView scrolling
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
VerticalGridView gridView = getGuidedActionsStylist().getActionsGridView();
gridView.setScrollEnabled(false);
super.onViewCreated(view, savedInstanceState);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 | XJIOP |



