public class

GuidedActionAdapterGroup

extends java.lang.Object

 java.lang.Object

↳androidx.leanback.widget.GuidedActionAdapterGroup

Gradle dependencies

compile group: 'androidx.leanback', name: 'leanback', version: '1.2.0-alpha04'

  • groupId: androidx.leanback
  • artifactId: leanback
  • version: 1.2.0-alpha04

Artifact androidx.leanback:leanback:1.2.0-alpha04 it located at Google repository (https://maven.google.com/)

Androidx artifact mapping:

androidx.leanback:leanback com.android.support:leanback-v17

Androidx class mapping:

androidx.leanback.widget.GuidedActionAdapterGroup android.support.v17.leanback.widget.GuidedActionAdapterGroup

Overview

Internal implementation manages a group of GuidedActionAdapters, control the next action after editing finished, maintain the Ime open/close status.

Summary

Constructors
publicGuidedActionAdapterGroup()

Methods
public voidaddAdpter(GuidedActionAdapter adapter1, GuidedActionAdapter adapter2)

public voidcloseIme(View v)

public voidfillAndGoNext(GuidedActionAdapter adapter, TextView v)

public voidfillAndStay(GuidedActionAdapter adapter, TextView v)

public GuidedActionAdaptergetNextAdapter(GuidedActionAdapter adapter)

public voidopenIme(GuidedActionAdapter adapter, GuidedActionsStylist.ViewHolder avh)

public voidsetEditListener(GuidedActionAdapter.EditListener listener)

from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructors

public GuidedActionAdapterGroup()

Methods

public void addAdpter(GuidedActionAdapter adapter1, GuidedActionAdapter adapter2)

public GuidedActionAdapter getNextAdapter(GuidedActionAdapter adapter)

public void setEditListener(GuidedActionAdapter.EditListener listener)

public void openIme(GuidedActionAdapter adapter, GuidedActionsStylist.ViewHolder avh)

public void closeIme(View v)

public void fillAndStay(GuidedActionAdapter adapter, TextView v)

public void fillAndGoNext(GuidedActionAdapter adapter, TextView v)

Source

/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package androidx.leanback.widget;

import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;

import android.content.Context;
import android.util.Log;
import android.util.Pair;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
import androidx.leanback.widget.GuidedActionAdapter.EditListener;

import java.util.ArrayList;

/**
 * Internal implementation manages a group of GuidedActionAdapters, control the next action after
 * editing finished, maintain the Ime open/close status.
 */
@RestrictTo(LIBRARY_GROUP_PREFIX)
public class GuidedActionAdapterGroup {

    private static final String TAG_EDIT = "EditableAction";
    private static final boolean DEBUG_EDIT = false;

    ArrayList<Pair<GuidedActionAdapter, GuidedActionAdapter>> mAdapters =
            new ArrayList<Pair<GuidedActionAdapter, GuidedActionAdapter>>();
    private boolean mImeOpened;
    private EditListener mEditListener;

    public void addAdpter(
            @Nullable GuidedActionAdapter adapter1,
            @Nullable GuidedActionAdapter adapter2
    ) {
        mAdapters.add(new Pair<GuidedActionAdapter, GuidedActionAdapter>(adapter1, adapter2));
        if (adapter1 != null) {
            adapter1.mGroup = this;
        }
        if (adapter2 != null) {
            adapter2.mGroup = this;
        }
    }

    @Nullable
    public GuidedActionAdapter getNextAdapter(@NonNull GuidedActionAdapter adapter) {
        for (int i = 0; i < mAdapters.size(); i++) {
            Pair<GuidedActionAdapter, GuidedActionAdapter> pair = mAdapters.get(i);
            if (pair.first == adapter) {
                return pair.second;
            }
        }
        return null;
    }

    public void setEditListener(@Nullable EditListener listener) {
        mEditListener = listener;
    }

    boolean focusToNextAction(GuidedActionAdapter adapter, GuidedAction action, long nextActionId) {
        // for ACTION_ID_NEXT, we first find out the matching index in Actions list.
        int index = 0;
        if (nextActionId == GuidedAction.ACTION_ID_NEXT) {
            index = adapter.indexOf(action);
            if (index < 0) {
                return false;
            }
            // start from next, if reach end, will go next Adapter below
            index++;
        }

        do {
            int size = adapter.getCount();
            if (nextActionId == GuidedAction.ACTION_ID_NEXT) {
                while (index < size && !adapter.getItem(index).isFocusable()) {
                    index++;
                }
            } else {
                while (index < size && adapter.getItem(index).getId() != nextActionId) {
                    index++;
                }
            }
            if (index < size) {
                GuidedActionsStylist.ViewHolder vh =
                        (GuidedActionsStylist.ViewHolder) adapter.getGuidedActionsStylist()
                                .getActionsGridView().findViewHolderForPosition(index);
                if (vh != null) {
                    if (vh.getAction().hasTextEditable()) {
                        if (DEBUG_EDIT) Log.v(TAG_EDIT, "openIme of next Action");
                        // open Ime on next action.
                        openIme(adapter, vh);
                    } else {
                        if (DEBUG_EDIT) Log.v(TAG_EDIT, "closeIme and focus to next Action");
                        // close IME and focus to next (not editable) action
                        closeIme(vh.itemView);
                        vh.itemView.requestFocus();
                    }
                    return true;
                }
                return false;
            }
            // search from index 0 of next Adapter
            adapter = getNextAdapter(adapter);
            if (adapter == null) {
                break;
            }
            index = 0;
        } while (true);
        return false;
    }

    public void openIme(
            @NonNull GuidedActionAdapter adapter,
            @NonNull GuidedActionsStylist.ViewHolder avh
    ) {
        adapter.getGuidedActionsStylist().setEditingMode(avh, true);
        View v = avh.getEditingView();
        if (v == null || !avh.isInEditingText()) {
            return;
        }
        InputMethodManager mgr = (InputMethodManager)
                v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
        // Make the TextView focusable during editing, avoid the TextView gets accessibility focus
        // before editing started. see also GuidedActionEditText where setFocusable(false).
        v.setFocusable(true);
        v.requestFocus();
        mgr.showSoftInput(v, 0);
        if (!mImeOpened) {
            mImeOpened = true;
            mEditListener.onImeOpen();
        }
    }

    public void closeIme(@NonNull View v) {
        if (mImeOpened) {
            mImeOpened = false;
            InputMethodManager mgr = (InputMethodManager)
                    v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
            mgr.hideSoftInputFromWindow(v.getWindowToken(), 0);
            mEditListener.onImeClose();
        }
    }

    public void fillAndStay(@NonNull GuidedActionAdapter adapter, @NonNull TextView v) {
        GuidedActionsStylist.ViewHolder avh = adapter.findSubChildViewHolder(v);
        updateTextIntoAction(avh, v);
        mEditListener.onGuidedActionEditCanceled(avh.getAction());
        adapter.getGuidedActionsStylist().setEditingMode(avh, false);
        closeIme(v);
        avh.itemView.requestFocus();
    }

    public void fillAndGoNext(@NonNull GuidedActionAdapter adapter, @NonNull TextView v) {
        boolean handled = false;
        GuidedActionsStylist.ViewHolder avh = adapter.findSubChildViewHolder(v);
        updateTextIntoAction(avh, v);
        adapter.performOnActionClick(avh);
        long nextActionId = mEditListener.onGuidedActionEditedAndProceed(avh.getAction());
        adapter.getGuidedActionsStylist().setEditingMode(avh, false);
        if (nextActionId != GuidedAction.ACTION_ID_CURRENT
                && nextActionId != avh.getAction().getId()) {
            handled = focusToNextAction(adapter, avh.getAction(), nextActionId);
        }
        if (!handled) {
            if (DEBUG_EDIT) Log.v(TAG_EDIT, "closeIme no next action");
            handled = true;
            closeIme(v);
            avh.itemView.requestFocus();
        }
    }

    private void updateTextIntoAction(GuidedActionsStylist.ViewHolder avh, TextView v) {
        GuidedAction action = avh.getAction();
        if (v == avh.getDescriptionView()) {
            if (action.getEditDescription() != null) {
                action.setEditDescription(v.getText());
            } else {
                action.setDescription(v.getText());
            }
        } else if (v == avh.getTitleView()) {
            if (action.getEditTitle() != null) {
                action.setEditTitle(v.getText());
            } else {
                action.setTitle(v.getText());
            }
        }
    }

}