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