Each keyboard app has its own layout and you can't change it. For example android:inputType="phone"
has different layouts on Gboard
and SwiftKey
.
![enter image description here](https://i.stack.imgur.com/WeTvb.png)
解决方案:
您应该实现一个自定义的 InAppKeyboard 并将其显示给用户而不是系统键盘。”为您的 Android 应用程序创建应用程序内键盘 https://medium.com/@ssaurel/creating-an-in-app-keyboard-for-your-android-apps-a0a6c6e1e289” 是一个很好的教程,描述了如何开发这样的自定义 InAppKeyboard,但您可以设计所需的布局并在您的应用程序中轻松使用它。
Update:
对于将 InAppKeyboard 与对话框一起使用,我有一个想法。我开发了一个自定义对话框片段 https://developer.android.com/reference/androidx/fragment/app/DialogFragment它有 2 部分:
1.对话框内容部分
2.自定义键盘部分命名CustomKeyboardDialog
.
您可以扩展此类并创建自定义对话框。两个都setContentView
and findViewById
方法可用,您可以使用它们来管理您的对话框 UI。您必须覆盖onCreate
自定义对话框实现中的方法并调用setContentView
那里。然后覆盖onCreateView
方法,调用findViewById
在那里找到你的 EditText 并通过调用附加它自定义键盘attachToCustomKeyboard
方法。自定义键盘对话框.java
public abstract class CustomKeyboardDialog extends DialogFragment {
private View mRootView;
private int mContentLayoutResID;
private View mContentView;
private CustomKeyboardView mCustomKeyboardView;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onStart() {
super.onStart();
Dialog dialog = getDialog();
if (dialog != null) {
dialog.getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
}
}
@Nullable
@Override
final public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
mRootView = inflater.inflate(R.layout.dialog_custom_keyboard, container, false);
ViewGroup contentViewContainer = mRootView.findViewById(R.id.content_view_container);
mContentView = inflater.inflate(mContentLayoutResID, contentViewContainer, true);
this.mCustomKeyboardView = mRootView.findViewById(R.id.keyboard_view);
this.onCreateView(mContentView);
return mRootView;
}
public View findViewById(int id) {
return mContentView.findViewById(id);
}
public void setContentView(@LayoutRes int layoutResID) {
this.mContentLayoutResID = layoutResID;
}
public void showKeyboard(InputConnection inputConnection) {
mCustomKeyboardView.setInputConnection(inputConnection);
mCustomKeyboardView.setVisibility(View.VISIBLE);
mCustomKeyboardView.animate().translationY(0).setListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
updateContentViewSize(true);
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
}
public void hideKeyboard() {
updateContentViewSize(false);
mCustomKeyboardView.animate().translationY(mCustomKeyboardView.getMeasuredHeight()).setListener(null);
}
private void updateContentViewSize(boolean keyboardVisible) {
ConstraintLayout.LayoutParams layoutParams = (ConstraintLayout.LayoutParams) mContentView.getLayoutParams();
if(keyboardVisible) {
layoutParams.bottomToTop = R.id.keyboard_view;
layoutParams.bottomToBottom = ConstraintLayout.LayoutParams.UNSET;
} else {
layoutParams.bottomToBottom = ConstraintLayout.LayoutParams.PARENT_ID;
layoutParams.bottomToTop = ConstraintLayout.LayoutParams.UNSET;
}
mContentView.setLayoutParams(layoutParams);
}
public void onCreateView(View contentView) {
}
@Override
public void onResume() {
super.onResume();
getDialog().setOnKeyListener(new DialogInterface.OnKeyListener()
{
@Override
public boolean onKey(android.content.DialogInterface dialog, int keyCode,android.view.KeyEvent event) {
if ((keyCode == android.view.KeyEvent.KEYCODE_BACK))
{
if(mCustomKeyboardView.getVisibility() == View.VISIBLE)
hideKeyboard();
return true;
}
else
return false;
}
});
}
@Override
public void onPause() {
super.onPause();
getDialog().setOnKeyListener(null);
}
public void attachToCustomKeyboard(EditText editText) {
editText.setShowSoftInputOnFocus(false);
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
showKeyboard(editText.onCreateInputConnection(new EditorInfo()));
}
}
});
editText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showKeyboard(editText.onCreateInputConnection(new EditorInfo()));
}
});
}
public void detachFromCustomKeyboard(EditText editText) {
editText.setShowSoftInputOnFocus(true);
editText.setOnFocusChangeListener(null);
editText.setOnClickListener(null);
}
}
对话框_自定义_键盘.xml
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/content_view_container"
android:background="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/keyboard_view"
android:orientation="vertical"
android:gravity="center">
</LinearLayout>
<mirm.test.testapp.dialog.CustomKeyboardView
android:id="@+id/keyboard_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
android:background="#eee"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
自定义KeyboardView.java
public class CustomKeyboardView extends LinearLayout implements View.OnClickListener {
private Button button1, button2, button3, button4,
button5, button6, button7, button8,
button9, button0, buttonDelete, buttonEnter, buttonSharp, buttonStar;
private SparseArray<String> keyValues = new SparseArray<>();
private InputConnection inputConnection;
public CustomKeyboardView(Context context) {
this(context, null, 0);
}
public CustomKeyboardView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomKeyboardView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
setOrientation(VERTICAL);
LayoutInflater.from(context).inflate(R.layout.custom_keyboard_layout, this, true);
button1 = (Button) findViewById(R.id.button_1);
button1.setOnClickListener(this);
button2 = (Button) findViewById(R.id.button_2);
button2.setOnClickListener(this);
button3 = (Button) findViewById(R.id.button_3);
button3.setOnClickListener(this);
button4 = (Button) findViewById(R.id.button_4);
button4.setOnClickListener(this);
button5 = (Button) findViewById(R.id.button_5);
button5.setOnClickListener(this);
button6 = (Button) findViewById(R.id.button_6);
button6.setOnClickListener(this);
button7 = (Button) findViewById(R.id.button_7);
button7.setOnClickListener(this);
button8 = (Button) findViewById(R.id.button_8);
button8.setOnClickListener(this);
button9 = (Button) findViewById(R.id.button_9);
button9.setOnClickListener(this);
button0 = (Button) findViewById(R.id.button_0);
button0.setOnClickListener(this);
buttonDelete = (Button) findViewById(R.id.button_delete);
buttonDelete.setOnClickListener(this);
buttonEnter = (Button) findViewById(R.id.button_enter);
buttonEnter.setOnClickListener(this);
buttonSharp = (Button) findViewById(R.id.button_sharp);
buttonSharp.setOnClickListener(this);
buttonStar = (Button) findViewById(R.id.button_star);
buttonStar.setOnClickListener(this);
keyValues.put(R.id.button_1, "1");
keyValues.put(R.id.button_2, "2");
keyValues.put(R.id.button_3, "3");
keyValues.put(R.id.button_4, "4");
keyValues.put(R.id.button_5, "5");
keyValues.put(R.id.button_6, "6");
keyValues.put(R.id.button_7, "7");
keyValues.put(R.id.button_8, "8");
keyValues.put(R.id.button_9, "9");
keyValues.put(R.id.button_0, "0");
keyValues.put(R.id.button_enter, "\n");
keyValues.put(R.id.button_sharp, "#");
keyValues.put(R.id.button_star, "*");
}
@Override
public void onClick(View view) {
if (inputConnection == null)
return;
if (view.getId() == R.id.button_delete) {
CharSequence selectedText = inputConnection.getSelectedText(0);
if (TextUtils.isEmpty(selectedText)) {
inputConnection.deleteSurroundingText(1, 0);
} else {
inputConnection.commitText("", 1);
}
} else {
String value = keyValues.get(view.getId());
inputConnection.commitText(value, 1);
}
}
public void setInputConnection(InputConnection ic) {
inputConnection = ic;
}
}
自定义键盘布局.xml
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/button_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="1"/>
<Button
android:id="@+id/button_2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="2"/>
<Button
android:id="@+id/button_3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="3"/>
<Button
android:id="@+id/button_4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="4"/>
<Button
android:id="@+id/button_5"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="5"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/button_6"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="6"/>
<Button
android:id="@+id/button_7"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="7"/>
<Button
android:id="@+id/button_8"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="8"/>
<Button
android:id="@+id/button_9"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="9"/>
<Button
android:id="@+id/button_0"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="0"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/button_sharp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#"/>
<Button
android:id="@+id/button_star"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="*"/>
<Button
android:id="@+id/button_delete"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.3"
android:text="Delete"/>
<Button
android:id="@+id/button_enter"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.7"
android:text="Enter"/>
</LinearLayout>
</merge>
以下是自定义对话框实现的示例:
示例对话框.java
public class SampleDialog extends CustomKeyboardDialog {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sample_dialog);
}
@Nullable
@Override
public void onCreateView(View contentView) {
EditText editText = (EditText) findViewById(R.id.edittext);
attachToCustomKeyboard(editText);
}
}
样本对话框.xm
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginRight="50dp"
android:layout_marginLeft="50dp"
android:background="#eee">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="32dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Enter Code"></TextView>
<EditText
android:id="@+id/edittext"
android:hint="example: *455*415#"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:text="Send"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
它看起来像这样: