119.Androidのシンプルなソフトキーボードとメニューのシームレスな切り替え効果、チャットインターフェイスのソフトキーボードのシームレスな切り替え

//この効果は主に、windowSoftInputMode の 3 つの状態 (SOFT_INPUT_ADJUST_NOTHING、SOFT_INPUT_ADJUST_PAN、SOFT_INPUT_ADJUST_RESIZE) の切り替えを動的に設定することによって実現されます。

 

1. 最初のステップは、必要な依存ライブラリをインポートすることです。

//recyclerView
実装「com.android.support:recyclerview-v7:28.0.0」

//リサイクラーアダプター
実装「com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.28」

2. 2 番目のステップは、新しい SeamlessSwitchActivity ページを作成することです。マニフェストで windowSoftInputMode が stateHidden|adjustResize に設定されていることに注意してください。

//マニフェスト: 

<アクティビティ
    android:name=".phone.activity.SeamlessSwitchActivity"
    android:launchMode="シングルトップ"
    android:screenOrientation="ポートレート"
    android:windowSoftInputMode="stateHidden|adjustResize"
    tools:ignore="LockedOrientationActivity" />

//アクティビティ:

/**
 * @著者CJF
 */
public class SeamlessSwitchActivity extends AppCompatActivityimplemented View.OnClickListener, View.OnTouchListener {
    private Final LinearLayoutManager マネージャー = new LinearLayoutManager(this);
    プライベート最終 SdkAdapter アダプター = new SdkAdapter(R.layout.sdk_item);
    プライベート SystemKeyboardUtils systemKeyboardUtils;
    プライベートビュー mSeamlessSwitchBottomLayout;
    プライベートRecyclerView mSeamlessSwitchRecy;
    プライベート ImageView mSeamlessSwitchMore;

    @オーバーライド
    protected void onCreate(@Nullable Bundle SavedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_simless_switch);

        mSeamlessSwitchMore = findViewById(R.id.mSeamlessSwitchMore);
        mSeamlessSwitchBottomLayout = findViewById(R.id.mSeamlessSwitchBottomLayout);
        mSeamlessSwitchRecy = findViewById(R.id.mSeamlessSwitchRecy);
        mSeamlessSwitchMore.setOnClickListener(this);
        mSeamlessSwitchRecy.setOnTouchListener(this);

        //ソフトキーボードレイアウト監視
        systemKeyboardUtils = new SystemKeyboardUtils(this, mSeamlessSwitchBottomLayout);
        systemKeyboardUtils.setOnKeyBoardListener(new SystemKeyboardUtils.OnKeyBoardListener() {
            @オーバーライド
            public void onShow(int height) {
                Log.e("TAG1231", "onShow height:" + height);
                // 下部のレイアウトを表示
                systemKeyboardUtils.showBottomLayout(height);
                //反転後、リストは一番下にスライドします。0 が一番下です
                マネージャー.scrollToPosition(0);
                //画像を設定する
                mSeamlessSwitchMore.setImageResource(R.drawable.svg_sms_more);
            }

            @オーバーライド
            public void onHide(int height) {
                Log.e("TAG1231", "onHide height:" + height);
                //画像を設定する
                mSeamlessSwitchMore.setImageResource(R.drawable.svg_keyboard);
            }
        });

        //リストの反転
        manager.setReverseLayout(true);
        mSeamlessSwitchRecy.setLayoutManager(マネージャー);
        mSeamlessSwitchRecy.setAdapter(アダプター);
        //反転後、リストは一番下にスライドします。0 が一番下です
        マネージャー.scrollToPosition(0);

        List<String> list = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            list.add("データ" + i);
        }
        アダプタ.addData(リスト);
    }


    @オーバーライド
    public void onClick(View v) {
        switch (v.getId()) {
            ケース R.id.mSeamlessSwitch詳細:
                //ソフトキーボードが有効かどうかを判断する
                ブール値表示 = systemKeyboardUtils.isShow();
                Log.e("TAG1231", "show:" + show);
                if (表示) {
                    //ソフトキーボードを非表示にする
                    systemKeyboardUtils.hideSoftInput();
                    // 画像を切り替える
                    mSeamlessSwitchMore.setImageResource(R.drawable.svg_keyboard);
                } それ以外 {
                    //ソフトキーボードを開く
                    systemKeyboardUtils.showSoftInput();
                    // 画像を切り替える
                    mSeamlessSwitchMore.setImageResource(R.drawable.svg_sms_more);
                }
                壊す;
            デフォルト:
                壊す;
        }
    }

    /**
     ※リストレイアウトをタッチすると、一番下のレイアウトが非表示になります
     *
     * @paramv
     * @paramイベント
     * @戻る
     */
    @オーバーライド
    public boolean onTouch(View v, MotionEvent イベント) {
        // 下部のレイアウトを非表示にする
        boolean HideBottomLayout = systemKeyboardUtils.hideBottomLayout();
        if (hideBottomLayout) {
            // 画像を切り替える
            mSeamlessSwitchMore.setImageResource(R.drawable.svg_keyboard);
        }
        false を返します。
    }

    @オーバーライド
    protected void onDestroy() {
        super.onDestroy();
        //レイアウトリスナーを削除
        systemKeyboardUtils.onDestroy();
    }

}

3. 3 番目のステップは、新しい SystemKeyboardUtils ツール クラスを作成することです。

/**
 * ソフトキーボードレイアウトモニタリング
 *
 * @著者CJF
 */
パブリック クラス SystemKeyboardUtils {

    /**
     * アクティビティのルートビュー
     */
    プライベートビュー rootView;

    /**
     * ルートビューの表示高さを記録します
     */
    private int rootViewVisibleHeight;

    /**
     * ソフトキーボードが有効かどうかを確認します
     */
    プライベートブール値 isShow = false;

    /**
     * コンテクスト
     */
    プライベートアクティビティアクティビティ。

    /**
     * 下部レイアウトの表示/非表示が必要です
     */
    プライベートビューのbottomLayout;

    /**
     *アニメーションの長さ
     */
    プライベートfinal int animatorDuration = 300;

    プライベート OnKeyBoardListener onKeyBoardListener;

    プライベート最終InputMethodManager imm;

    /**
     * @param アクティビティコンテキスト
     * @parambottomLayout は下部レイアウトの表示と非表示を切り替える必要があります
     */
    public SystemKeyboardUtils(アクティビティ activity, ViewbottomLayout) {
        this.activity = アクティビティ;
        this.bottomLayout =bottomLayout;

        // アクティビティのルートビューを取得します
        rootView = activity.getWindow().getDecorView();

        //ビュー ツリー内のグローバル レイアウトの変更、またはビュー ツリー内のビューの表示状態の変更を監視します。
        rootView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);

        //ソフトキーボード管理
        imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
    }

    /**
     * レイアウトモニタリング
     */
    private ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener = () -> {
        // 画面に表示されている現在のルート ビューのサイズを取得します
        Rect r = 新しい Rect();
        rootView.getWindowVisibleDisplayFrame(r);
        intvisibleHeight = r.height();
        if (rootViewVisibleHeight == 0) {
            rootViewVisibleHeight = 可視高さ;
            戻る;
        }

        //ルートビューの表示高さは変化していないので、ソフトキーボードの表示・非表示状態は変化していないとみなせる
        if (rootViewVisibleHeight ==visibleHeight) {
            戻る;
        }

        //ルートビューの表示高さが200より小さくなり、ソフトキーボードの表示とみなせる
        if (rootViewVisibleHeight -visibleHeight > 200) {
            if (onKeyBoardListener != null) {
                onKeyBoardListener.onShow(rootViewVisibleHeight -visibleHeight);
            }
            rootViewVisibleHeight = 可視高さ;
            isShow = true;
            戻る;
        }

        //ルートビューの表示高さが200より大きくなり、ソフトキーボードが隠れたとみなせる
        if (visibleHeight - rootViewVisibleHeight > 200) {
            if (onKeyBoardListener != null) {
                onKeyBoardListener.onHide(visibleHeight - rootViewVisibleHeight);
            }
            rootViewVisibleHeight = 可視高さ;
            isShow = false;
            戻る;
        }

    };

    /**
     * ソフトキーボードが有効かどうかを確認します
     *
     * @戻る
     */
    public boolean isShow() {
        戻り値は表示です。
    }

    /**
     * 下部のレイアウトを表示
     *
     * @パラメータの高さ
     */
    public void showBottomLayout(int height) {
        //ソフトキーボード設定は最初に動的にSOFT_INPUT_ADJUST_NOTHINGに設定されます。この時点ではレイアウトの変更を監視できません
        activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);
        // 表示レイアウト
        BottomLayout.setVisibility(View.VISIBLE);
        // 高さを変更する
        ViewGroup.LayoutParams params =bottomLayout.getLayoutParams();
        params.height = 高さ;
        BottomLayout.setLayoutParams(params);
        //ソフトキーボードの設定は最終的にSOFT_INPUT_ADJUST_PANに設定されます。このとき、レイアウトの変更を再度監視できます
        activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
    }

    /**
     * 下部のレイアウトを非表示にする
     */
    public boolean hideBottomLayout() {
        //下部レイアウトが非表示でソフトキーボードが表示されていない場合は実行しない
        if (bottomLayout.getVisibility() == View.GONE && !isShow()) {
            false を返します。
        }
        //ソフトキーボードを非表示にする
        HideSoftInput();
        // 表示を非表示に設定しますが、レイアウト領域を占有します
        BottomLayout.setVisibility(View.INVISIBLE);
        // 下部レイアウトの高さを取得します
        int meteredHeight =bottomLayout.getMeasuredHeight();
        //アニメーション
        最終的な ValueAnimatorfoldAnimator = ValueAnimator.ofInt(measuredHeight, 0);
        foldAnimator.setDuration(animatorDuration);
        foldAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @オーバーライド
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                // 高さを変更する
                最終的な ViewGroup.LayoutParams lp =bottomLayout.getLayoutParams();
                lp.height = (int) valueAnimator.getAnimatedValue();
                BottomLayout.setLayoutParams(lp);
            }
        });

        foldAnimator.addListener(new AnimatorListenerAdapter() {
            @オーバーライド
            public void onAnimationEnd(アニメーターアニメーション) {
                super.onAnimationEnd(アニメーション);
                // 下部のレイアウトを非表示にします
                BottomLayout.setVisibility(View.GONE);
                //ソフトキーボードの設定は最終的にSOFT_INPUT_ADJUST_RESIZEに設定されます。このとき、レイアウトの変更を再度監視できます
                activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
            }
        });
        foldAnimator.start();
        true を返します。
    }

    /**
     * レイアウト リスナーを削除します
     */
    public void onDestroy() {
        rootView.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayoutListener);
    }

    /**
     * ソフトキーボードを非表示にする
     */
    public void hideSoftInput() {
        if (imm == null) {
            戻る;
        }
        imm.hideSoftInputFromWindow(activity.getWindow().getDecorView().getWindowToken(), 0);
    }

    /**
     * ソフトキーボードを開きます
     */
    public void showSoftInput() {
        if (imm == null) {
            戻る;
        }
        imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
    }

    public void setOnKeyBoardListener(OnKeyBoardListener onKeyBoardListener) {
        this.onKeyBoardListener = onKeyBoardListener;
    }

    パブリック インターフェイス OnKeyBoardListener {
        void onShow(int height);

        void onHide(int height);
    }

}

4. 4 番目のステップでは、いくつかの単純なデータを適応させるための新しい SdkAdapter アダプター クラスを作成します。

public class SdkAdapter extends BaseQuickAdapter<String, BaseViewHolder> {

    public SdkAdapter(intlayoutResId) {
        super(layoutResId);
    }

    @オーバーライド
    protected void Convert(BaseViewHolder helper, String item) {
        helper.setText(R.id.mOppoSdkTextPosition, String.valueOf(helper.getAdapterPosition()));
        helper.setText(R.id.mOppoSdkText, item);
    }
}

5. 5 番目のステップは、各 XML レイアウト ファイルと SVG 画像リソース ファイルです。

//アクティビティ_シームレス_スイッチ:

<?xml バージョン="1.0" エンコーディング="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="垂直">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/mSeamlessSwitchRecy"
        android:layout_width="match_parent"
        android:layout_weight="1"
        android:layout_height="0dp"/>

    <LinearLayout
        android:background="@drawable/background_white"
        android:layout_width="match_parent"
        android:layout_height="ラップコンテンツ"
        アンドロイド:重力 = "中心"
        android:orientation="垂直">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="ラップコンテンツ"
            アンドロイド:重力 = "中心"
            android:orientation="水平">

            <イメージビュー
                android:id="@+id/mSeamlessSwitchMore"
                android:layout_width="0dp"
                android:layout_height="@dimen/dp_50"
                android:layout_gravity="センター"
                android:layout_weight="1"
                android:background="@drawable/background_white"
                android:padding="@dimen/dp_8"
                android:src="@drawable/svg_keyboard" />

            <編集テキスト
                android:layout_width="0dp"
                android:layout_height="ラップコンテンツ"
                android:layout_marginBottom="@dimen/dp_20"
                android:layout_marginTop="@dimen/dp_20"
                android:layout_marginRight="@dimen/dp_20"
                アンドロイド:layout_weight="5"
                android:background="@drawable/sms_details_bg"
                android:gravity="中央|左"
                アンドロイド:ヒント="入力"
                android:maxHeight="@dimen/dp_200"
                android:minHeight="@dimen/dp_40"
                android:paddingBottom="@dimen/dp_10"
                android:paddingLeft="@dimen/dp_10"
                android:paddingTop="@dimen/dp_10"
                android:textColor="@color/black"
                android:textColorHint="@color/color_657091"
                android:textSize="@dimen/sp_15" />

        </LinearLayout>

        <TextView
            android:visibility="消えた"
            アンドロイド:重力 = "中心"
            android:text="コンテンツのレイアウト"
            android:id="@+id/mSeamlessSwitchBottomLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

    </LinearLayout>

</LinearLayout>

//sdk_item:

<?xml バージョン="1.0" エンコーディング="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="ラップコンテンツ"
    android:layout_marginBottom="@dimen/dp_5"
    android:layout_marginLeft="@dimen/dp_20"
    android:layout_marginRight="@dimen/dp_20"
    android:layout_marginTop="@dimen/dp_5"
    android:background="@drawable/selector_common_item"
    アンドロイド:重力 = "中心"
    android:orientation="水平">

    <TextView
        android:id="@+id/mOppoSdkTextPosition"
        android:layout_width="0dp"
        android:layout_height="ラップコンテンツ"
        アンドロイド:layout_weight="2"
        android:background="@drawable/selector_common_item"
        アンドロイド:重力 = "中心"
        android:minHeight="@dimen/dp_50"
        android:padding="@dimen/dp_10"
        アンドロイド:テキスト="0"
        android:textColor="@color/black"
        android:textSize="@dimen/sp_15" />

    <TextView
        android:id="@+id/mOppoSdkText"
        android:layout_width="0dp"
        android:layout_height="ラップコンテンツ"
        アンドロイド:layout_weight="8"
        android:background="@drawable/selector_common_item"
        android:gravity="左|中央垂直"
        android:minHeight="@dimen/dp_50"
        android:padding="@dimen/dp_10"
        android:text="テキスト"
        android:textColor="@color/black"
        android:textSize="@dimen/sp_15" />

</LinearLayout>

//svg 画像ファイル svg_keyboard:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    アンドロイド:幅="24dp"
    アンドロイド:高さ="24dp"
    android:tint="#E7E9EF"
    アンドロイド:ビューポート高さ="24.0"
    android:viewportWidth="24.0">
    <パス
        android:fillColor="#ffffffff"
        android:pathData="M20,5L4,5c-1.1,0 -1.99,0.9 -1.99,2L2,17c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,7c0,-1.1 - 0.9、-2 -2、-2zM11、8h2v2h-2L11、8zM11、11h2v2h-2v-2zM8、8h2v2L8、10L8、8zM8、11h2v2L8、13v-2zM7、13L5、13v-2h2v2zM7、10L5、10L5、8h2v2zM 16,17L8,17v- 2h8v2zM16,13h-2v-2h2v2zM16,10h-2L14,8h2v2zM19,13h-2v-2h2v2zM19,10h-2L17,8h2v2z" />
</vector>

// SVG 画像ファイル svg_sms_more:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    アンドロイド:幅="24dp"
    アンドロイド:高さ="24dp"
    アンドロイド:アルファ="0.85"
    android:autoMirrored="true"
    android:tint="#E7E9EF"
    アンドロイド:ビューポート高さ = "24"
    android:viewportWidth="24">
    <パス
        android:fillColor="#ffffffff"
        android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM17,13h-4v4h-2v-4L7,13v -2h4L11,7h2v4h4v2z" />
</vector>

//------------------------------------------------ - - - - - -終わり - - - - - - - - - - - - - - - - - - - -------------------------

おすすめ

転載: blog.csdn.net/weixin_42061754/article/details/129316225