Libgdx仿写Unity输入框

1.布局xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/dialogRoot"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:paddingLeft="10dp"
    android:background="@color/white">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:gravity="center_vertical"
        android:orientation="horizontal">

        <!-- 左:输入框(占满剩余宽度) -->
        <EditText
            android:id="@+id/etInput"
            android:layout_width="0dp"
            android:layout_height="48dp"
            android:layout_weight="1"
            android:background="@android:color/transparent"
            android:hint=""
            android:imeOptions="actionDone"
            android:inputType="text"
            android:maxLines="1"
            android:textSize="20sp"
            android:paddingStart="22dp"
            android:paddingEnd="22dp"
            android:singleLine="true" />

        <!-- 右:按钮(固定宽度) -->
        <Button
            android:id="@+id/btnOk"
            android:layout_width="88dp"
            android:layout_height="40dp"
            android:background="@color/white"
            android:textSize="13sp"
            android:textStyle="bold"
            android:text="确定" />
    </LinearLayout>
</RelativeLayout>

2.通过弹窗形式实现

package com.joker.dialog;

import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Gravity;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.AbsListView;
import android.widget.Button;
import android.widget.EditText;

import com.badlogic.gdx.backends.android.R;


public class UserInputDialog extends DialogFragment {
    private static final long DISMISS_DELAY_MS = 180L;

    public interface OnSubmitListener {
        void onSubmit(String text);
    }

    public interface OnCancelListener {
        void onCancel();
    }

    private OnSubmitListener listener;
    private OnCancelListener onCancelListener;
    private String hintText = "";
    private boolean submitted;
    private boolean closing;

    public UserInputDialog setOnSubmitListener(OnSubmitListener l) {
        this.listener = l;
        return this;
    }

    public UserInputDialog setOnCancelListener(OnCancelListener l) {
        this.onCancelListener = l;
        return this;
    }

    public UserInputDialog setHint(String hint) {
        this.hintText = hint == null ? "" : hint;
        return this;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Dialog dialog = new Dialog(getContext(), R.style.FullScreenDialogTheme);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(R.layout.dialog_custom);
        dialog.setCanceledOnTouchOutside(true);

        Window w = dialog.getWindow();
        if (w != null) {
            // 底部对齐、宽度全屏
            w.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            w.setGravity(Gravity.BOTTOM);
            // 关键:让窗口为键盘让位,并在弹出时直接弹出键盘(可选)
            w.setSoftInputMode(
                    WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
                            | WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE
            );
            // 背景透明,保留内容圆角
            w.setBackgroundDrawableResource(android.R.color.transparent);
        }


        EditText et = dialog.findViewById(R.id.etInput);
        Button btn = dialog.findViewById(R.id.btnOk);

        if (et != null) {
            et.setHint(hintText);
            et.requestFocus();
            et.post(() -> {
                if (getActivity() == null) return;
                InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
                if (imm != null) {
                    imm.showSoftInput(et, InputMethodManager.SHOW_IMPLICIT);
                }
            });
        }

        // IME 的完成键直接提交
        if (et != null) {
            et.setOnEditorActionListener((v, actionId, event) -> {
                submitAndDismiss(et);
                return true;
            });
            et.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {

                }

                @Override
                public void afterTextChanged(Editable s) {
                    if (listener != null && et != null) {
                        listener.onSubmit(et.getText() != null ? et.getText().toString() : "");
                    }
                }
            });
        }


        if (btn != null) {
            btn.setOnClickListener(v -> submitAndDismiss(et));
        }

        return dialog;
    }

    private void submitAndDismiss(EditText et) {
        if (closing) {
            return;
        }
        closing = true;
        submitted = true;
        if (listener != null && et != null) {
            listener.onSubmit(et.getText() != null ? et.getText().toString() : "");
        }
        hideKeyboard(et);
        if (et != null) {
            et.postDelayed(() -> dismissAllowingStateLoss(), DISMISS_DELAY_MS);
        } else {
            dismissAllowingStateLoss();
        }
    }

    @Override
    public void onCancel(android.content.DialogInterface dialog) {
        super.onCancel(dialog);
        if (!submitted && onCancelListener != null) {
            onCancelListener.onCancel();
        }
    }

    @Override
    public void onDismiss(android.content.DialogInterface dialog) {
        EditText et = getDialog() == null ? null : getDialog().findViewById(R.id.etInput);
        hideKeyboard(et);
        super.onDismiss(dialog);
    }

    private void hideKeyboard(EditText et) {
        if (getActivity() == null) return;
        InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm != null && et != null) {
            imm.hideSoftInputFromWindow(et.getWindowToken(), 0);
        }
    }
}

3.设置样式,以及键盘出现和退出动画

    <style name="FullScreenDialogTheme" parent="android:Theme.Dialog">
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowMinWidthMajor">0dp</item>
        <item name="android:windowMinWidthMinor">0dp</item>
        <item name="android:padding">0dp</item>


        <item name="android:colorBackgroundCacheHint">@null</item>
        <item name="android:windowAnimationStyle">@style/BottomDialogWindowAnimation</item>

        <item name="android:windowContentOverlay">@null</item>
        <item name="android:windowFullscreen">true</item>
    </style>
    <style name="BottomDialogWindowAnimation">
        <item name="android:windowEnterAnimation">@anim/dialog_slide_in_bottom</item>
        <item name="android:windowExitAnimation">@anim/dialog_slide_out_bottom</item>
    </style>

4.Libdx使用

 initialize(new GameTest(new UserInputListener() {
            @Override
            public void showHandleInput(String hint, Input.TextInputListener callback) {
                runOnUiThread(() -> {
                    try {
                        new UserInputDialog()
                                .setHint(hint)
                                .setOnSubmitListener(text -> {
                                    if (callback != null) {
                                        Gdx.app.postRunnable(() -> callback.input(text));
                                    }
                                })
                                .setOnCancelListener(() -> {
                                    if (callback != null) {
                                        Gdx.app.postRunnable(callback::canceled);
                                    }
                                })
                                .show(getFragmentManager(), "unity_input_bar");
                    } catch (Exception e) {
                        if (callback != null) {
                            Gdx.app.postRunnable(callback::canceled);
                        }
                    }
                });
            }
        }), configuration);

5.点击弹出


public class LoadScreen extends BaseScreen {
    public LoadScreen(BaseGame game) {
        super(game);
    }

    @Override
    public void initView() {
        super.initView();
//        TextField textField = new TextField("",new TextField.TextFieldStyle(){{
//            font = Asset.getAsset().loadBitFont("font/Manrope-Bold_56_1.fnt");
//            cursor = new TextureRegionDrawable(Asset.getAsset().getSprite("textfield/textc.png"));
//            fontColor = Color.WHITE;
//        }});
//        textField.setSize(Constant.GAMEWIDTH,200);
//        addActor(textField);
//        textField.setDebug(true);
//        textField.setPosition(Constant.GAMEWIDTH/2f,Constant.GAMEHIGHT*3/5, Align.center);
        Label label = new Label("Loading...",new Label.LabelStyle(){{
            font = Asset.getAsset().loadBitFont("font/Manrope-Bold_56_1.fnt");
            fontColor = Color.WHITE;
        }});
        addActor(label);
        label.setWidth(Constant.GAMEWIDTH);
        label.setPosition(Constant.GAMEWIDTH/2f,Constant.GAMEHIGHT*3/5, Align.center);
        label.setText("new player ");
        label.setDebug(true);
        label.setAlignment(Align.left);
        label.addListener(new OrdinaryButtonListener(){
            @Override
            public void clicked(InputEvent event, float x, float y) {
                super.clicked(event, x, y);
                GameTest.getUserInputListener().showHandleInput("请输入玩家名称", new Input.TextInputListener() {
                    @Override
                    public void input(String text) {
                        label.setText(text);
                    }

                    @Override
                    public void canceled() {

                    }
                });
            }
        });
    }
}

image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容