отключить эффект прокрутки списка действий

У меня есть такой фрагмент GuidedStepSupportFragment.

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");

    }
}

действие1

Проблема: когда я прокручиваю список действий, он выглядит следующим образом;

действие1

Но я хочу что-то вроде этого;

ожидаемый

Как я могу отключить этот эффект в моем списке действий?

Спасибо


person ziLk    schedule 06.04.2020    source источник
comment
На примерах непонятно, в чем разница между тем, что не так, и желаемым эффектом, по крайней мере, я ее не вижу. Это проблема выравнивания?   -  person Ron    schedule 15.04.2020


Ответы (1)


Мне это удалось, и это было нелегко понять.

Не существует поддерживаемого способа сделать это, поскольку API-интерфейсы, которые на самом деле делают это возможным, являются частными пакетами или намеренно скрыты от публичного использования. (Вы можете сделать это самостоятельно, но в конечном итоге вы просто скопируете классы из библиотек для откидывания назад.)

Решение:

@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);
    }
}

Полный пример

Объяснение:

GuidedStepSupportFragment запрашивает GuidedActionsStylist, который отвечает за отображение элементов списка с правой стороны. источник

GuidedActionsStylist Стилист увеличивает макет lb_guidedactions.xml, который содержит VerticalGridView источник

VerticalGridView расширяет BaseGridView и создает GridLayoutManager в качестве менеджера компоновки. Этот GridLayoutManager, к сожалению, является закрытым и окончательным пакетом... (андроид, почему..?). Он имеет метод setFocusScrollStrategy, который используется для определения поведения прокрутки.источник

Посмотрите различные стратегии прокрутки фокуса:

/**
 * 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;

Итак, поскольку API скрыт, мы просто используем отражение, чтобы открыть метод setFocusScrollStrategy и установить для него значение FOCUS_SCROLL_ITEM.

Однако мы не можем сделать это немедленно, так как без настройки прокрутки по умолчанию элементы списка будут всплывать в верхней части макета и не будут оставаться в центре. Поэтому я добавил задержку в 500 мс, что ужасно... Если вам удастся узнать, когда лучше всего это активировать, дайте мне знать.

person JensV    schedule 15.04.2020
comment
В качестве примечания: спасибо за этот интересный вопрос, в процессе исследования я исправил проблему с прокруткой в ​​​​своем собственном телевизионном приложении благодаря этому :) - person JensV; 15.04.2020