public class

EmojiExtractTextLayout

extends LinearLayout

 java.lang.Object

↳LinearLayout

↳androidx.emoji2.widget.EmojiExtractTextLayout

Gradle dependencies

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

  • groupId: androidx.emoji2
  • artifactId: emoji2-views
  • version: 1.2.0-alpha04

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

Overview

Layout that contains emoji compatibility enhanced ExtractEditText. Should be used by implementations.

Call EmojiExtractTextLayout.onUpdateExtractingViews(InputMethodService, EditorInfo) from .

 public class MyInputMethodService extends InputMethodService {
     // ..
      @Override
     public View onCreateExtractTextView() {
         mExtractView = getLayoutInflater().inflate(R.layout.emoji_input_method_extract_layout,
                 null);
         return mExtractView;
     }

      @Override
     public void onUpdateExtractingViews(EditorInfo ei) {
         mExtractView.onUpdateExtractingViews(this, ei);
     }
 }
 

Summary

Constructors
publicEmojiExtractTextLayout(Context context)

publicEmojiExtractTextLayout(Context context, AttributeSet attrs)

publicEmojiExtractTextLayout(Context context, AttributeSet attrs, int defStyleAttr)

Methods
public intgetEmojiReplaceStrategy()

Returns whether to replace all emoji with EmojiSpans.

public voidonUpdateExtractingViews(InputMethodService inputMethodService, EditorInfo ei)

Initializes the layout.

public voidsetEmojiReplaceStrategy(int replaceStrategy)

Sets whether to replace all emoji with EmojiSpans.

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

Constructors

public EmojiExtractTextLayout(Context context)

public EmojiExtractTextLayout(Context context, AttributeSet attrs)

public EmojiExtractTextLayout(Context context, AttributeSet attrs, int defStyleAttr)

Methods

public void setEmojiReplaceStrategy(int replaceStrategy)

Sets whether to replace all emoji with EmojiSpans. Default value is EmojiCompat.REPLACE_STRATEGY_DEFAULT.

Parameters:

replaceStrategy: should be one of EmojiCompat.REPLACE_STRATEGY_DEFAULT, EmojiCompat.REPLACE_STRATEGY_NON_EXISTENT, EmojiCompat.REPLACE_STRATEGY_ALL

public int getEmojiReplaceStrategy()

Returns whether to replace all emoji with EmojiSpans. Default value is EmojiCompat.REPLACE_STRATEGY_DEFAULT.

Returns:

one of EmojiCompat.REPLACE_STRATEGY_DEFAULT, EmojiCompat.REPLACE_STRATEGY_NON_EXISTENT, EmojiCompat.REPLACE_STRATEGY_ALL

public void onUpdateExtractingViews(InputMethodService inputMethodService, EditorInfo ei)

Initializes the layout. Call this function from .

Source

/*
 * Copyright 2021 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.emoji2.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.inputmethodservice.InputMethodService;
import android.text.InputType;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.widget.LinearLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat;
import androidx.emoji2.text.EmojiCompat;
import androidx.emoji2.text.EmojiSpan;

/**
 * Layout that contains emoji compatibility enhanced ExtractEditText. Should be used by
 * {@link InputMethodService} implementations.
 * <p/>
 * Call {@link #onUpdateExtractingViews(InputMethodService, EditorInfo)} from
 * {@link InputMethodService#onUpdateExtractingViews(EditorInfo)
 * InputMethodService#onUpdateExtractingViews(EditorInfo)}.
 * <pre>
 * public class MyInputMethodService extends InputMethodService {
 *     // ..
 *     {@literal @}Override
 *     public View onCreateExtractTextView() {
 *         mExtractView = getLayoutInflater().inflate(R.layout.emoji_input_method_extract_layout,
 *                 null);
 *         return mExtractView;
 *     }
 *
 *     {@literal @}Override
 *     public void onUpdateExtractingViews(EditorInfo ei) {
 *         mExtractView.onUpdateExtractingViews(this, ei);
 *     }
 * }
 * </pre>
 *
 * {@link androidx.emoji.R.attr#emojiReplaceStrategy}
 */
public class EmojiExtractTextLayout extends LinearLayout {

    private ExtractButtonCompat mExtractAction;
    private EmojiExtractEditText mExtractEditText;
    private ViewGroup mExtractAccessories;
    private View.OnClickListener mButtonOnClickListener;

    /**
     * Prevent calling {@link #init(Context, AttributeSet, int)}} multiple times in case super()
     * constructors call other constructors.
     */
    private boolean mInitialized;

    public EmojiExtractTextLayout(@NonNull Context context) {
        super(context);
        init(context, null /*attrs*/, 0 /*defStyleAttr*/, 0 /*defStyleRes*/);
    }

    public EmojiExtractTextLayout(@NonNull Context context,
            @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0 /*defStyleAttr*/, 0 /*defStyleRes*/);
    }

    public EmojiExtractTextLayout(@NonNull Context context,
            @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs, defStyleAttr, 0 /*defStyleRes*/);
    }

    private void init(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr,
            int defStyleRes) {
        if (!mInitialized) {
            mInitialized = true;
            setOrientation(HORIZONTAL);
            final View view = LayoutInflater.from(context)
                    .inflate(R.layout.input_method_extract_view, this /*root*/,
                            true /*attachToRoot*/);
            mExtractAccessories = view.findViewById(R.id.inputExtractAccessories);
            mExtractAction = view.findViewById(R.id.inputExtractAction);
            mExtractEditText = view.findViewById(android.R.id.inputExtractEditText);

            if (attrs != null) {
                final TypedArray a = context.obtainStyledAttributes(attrs,
                        R.styleable.EmojiExtractTextLayout, defStyleAttr, defStyleRes);
                ViewCompat.saveAttributeDataForStyleable(
                        this, context, R.styleable.EmojiExtractTextLayout, attrs, a, defStyleAttr,
                        defStyleRes);
                final int replaceStrategy = a.getInteger(
                        R.styleable.EmojiExtractTextLayout_emojiReplaceStrategy,
                        EmojiCompat.REPLACE_STRATEGY_DEFAULT);
                mExtractEditText.setEmojiReplaceStrategy(replaceStrategy);
                a.recycle();
            }
        }
    }

    /**
     * Sets whether to replace all emoji with {@link EmojiSpan}s. Default value is
     * {@link EmojiCompat#REPLACE_STRATEGY_DEFAULT}.
     *
     * @param replaceStrategy should be one of {@link EmojiCompat#REPLACE_STRATEGY_DEFAULT},
     *                        {@link EmojiCompat#REPLACE_STRATEGY_NON_EXISTENT},
     *                        {@link EmojiCompat#REPLACE_STRATEGY_ALL}
     *
     * {@link androidx.emoji.R.attr#emojiReplaceStrategy}
     */
    public void setEmojiReplaceStrategy(@EmojiCompat.ReplaceStrategy int replaceStrategy) {
        mExtractEditText.setEmojiReplaceStrategy(replaceStrategy);
    }

    /**
     * Returns whether to replace all emoji with {@link EmojiSpan}s. Default value is
     * {@link EmojiCompat#REPLACE_STRATEGY_DEFAULT}.
     *
     * @return one of {@link EmojiCompat#REPLACE_STRATEGY_DEFAULT},
     *                        {@link EmojiCompat#REPLACE_STRATEGY_NON_EXISTENT},
     *                        {@link EmojiCompat#REPLACE_STRATEGY_ALL}
     *
     * {@link androidx.emoji.R.attr#emojiReplaceStrategy}
     */
    public int getEmojiReplaceStrategy() {
        return mExtractEditText.getEmojiReplaceStrategy();
    }

    /**
     * Initializes the layout. Call this function from
     * {@link InputMethodService#onUpdateExtractingViews(EditorInfo)
     * InputMethodService#onUpdateExtractingViews(EditorInfo)}.
     */
    public void onUpdateExtractingViews(@NonNull InputMethodService inputMethodService,
            @NonNull EditorInfo ei) {
        // the following code is ported as it is from InputMethodService.onUpdateExtractingViews
        if (!inputMethodService.isExtractViewShown()) {
            return;
        }

        if (mExtractAccessories == null) {
            return;
        }

        final boolean hasAction = ei.actionLabel != null
                || ((ei.imeOptions & EditorInfo.IME_MASK_ACTION) != EditorInfo.IME_ACTION_NONE
                && (ei.imeOptions & EditorInfo.IME_FLAG_NO_ACCESSORY_ACTION) == 0
                && ei.inputType != InputType.TYPE_NULL);

        if (hasAction) {
            mExtractAccessories.setVisibility(View.VISIBLE);
            if (mExtractAction != null) {
                if (ei.actionLabel != null) {
                    mExtractAction.setText(ei.actionLabel);
                } else {
                    mExtractAction.setText(inputMethodService.getTextForImeAction(ei.imeOptions));
                }
                mExtractAction.setOnClickListener(getButtonClickListener(inputMethodService));
            }
        } else {
            mExtractAccessories.setVisibility(View.GONE);
            if (mExtractAction != null) {
                mExtractAction.setOnClickListener(null);
            }
        }
    }

    private View.OnClickListener getButtonClickListener(
            final InputMethodService inputMethodService) {
        if (mButtonOnClickListener == null) {
            mButtonOnClickListener = new ButtonOnclickListener(inputMethodService);
        }
        return mButtonOnClickListener;
    }

    private static final class ButtonOnclickListener implements View.OnClickListener {
        private final InputMethodService mInputMethodService;

        ButtonOnclickListener(InputMethodService inputMethodService) {
            mInputMethodService = inputMethodService;
        }

        /**
         * The following code is ported as it is from InputMethodService.mActionClickListener.
         */
        @Override
        public void onClick(View v) {
            final EditorInfo ei = mInputMethodService.getCurrentInputEditorInfo();
            final InputConnection ic = mInputMethodService.getCurrentInputConnection();
            if (ei != null && ic != null) {
                if (ei.actionId != 0) {
                    ic.performEditorAction(ei.actionId);
                } else if ((ei.imeOptions & EditorInfo.IME_MASK_ACTION)
                        != EditorInfo.IME_ACTION_NONE) {
                    ic.performEditorAction(ei.imeOptions & EditorInfo.IME_MASK_ACTION);
                }
            }
        }
    }
}