弹出软键盘并弹出输入框,并获取焦点在此输入框里:
国际惯例,先上图:
下面为步骤:
Step 1:自定义带有输入框等等需要的样式的dialog
public class SoftKeyboardInputDialog extends Dialog {
private Activity activity;
public SoftKeyboardInputDialog(@NonNull Context context, int themeResId) {
super(context, themeResId);
this.activity=(Activity) context;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//==构建布局(当然,也可以不动态构建布局,可引用布局文件)
LinearLayout layout=new LinearLayout(activity);
layout.setOrientation(LinearLayout.HORIZONTAL);
layout.setBackgroundColor(Color.WHITE);
LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);
layout.setLayoutParams(params);
final EditText editText=new EditText(activity);
LinearLayout.LayoutParams editTextParams=new LinearLayout.LayoutParams(0,ViewGroup.LayoutParams.WRAP_CONTENT,1);
editText.setLayoutParams(editTextParams);
editText.setHint("请输入");
layout.addView(editText);
Button button=new Button(activity);
button.setText("发送");
layout.addView(button);
//==dialog设置布局,也可以用xml文件的布局
setContentView(layout);
//==监听dialog弹出后立即弹出软键盘并设置焦点
setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
new Thread(new Runnable() {
@Override
public void run() {
//editText.requestFocus();必须在该线程执行;弹出键盘的代码也是,否则有概率不弹出键盘
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
//SystemClock.sleep(300);//在setOnShowListener方法里弹出暂为发现冲突,所以不休眠等dialog弹出后再弹出键盘
//设置控件焦点
editText.setFocusable(true);
editText.setFocusableInTouchMode(true);
editText.requestFocus();
//弹出键盘
InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
}
});
}
}).start();
}
});
//==设置dialog参数
Window window=getWindow();
window.setGravity(Gravity.BOTTOM);
WindowManager.LayoutParams windowParams=window.getAttributes();
windowParams.width=WindowManager.LayoutParams.MATCH_PARENT;
}
}
Step 2:在styles.xml里添加以下样式:
<!--parent="@android:style/Theme.Dialog":点击dialog之外的界面就会关闭dialog-->
<style name="DialogTheme" parent="@android:style/Theme.Dialog">
<!-- 边框 -->
<item name="android:windowFrame">@null</item>
<!-- 是否浮现在activity之上 -->
<item name="android:windowIsFloating">true</item>
<!-- 半透明 -->
<item name="android:windowIsTranslucent">true</item>
<!-- 无标题 -->
<item name="android:windowNoTitle">true</item>
<item name="android:background">@android:color/transparent</item>
<!-- 背景透明 -->
<item name="android:windowBackground">@android:color/transparent</item>
<!-- 模糊 -->
<item name="android:backgroundDimEnabled">true</item>
<!-- 遮罩层透明度 -->
<item name="android:backgroundDimAmount">0.5</item>
</style>
Step 3:activity_main.xml布局为:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/llRoot"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/test"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="测试"/>
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
Step 4:MainActivity为:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取控件
final LinearLayout llRoot=findViewById(R.id.llRoot);//这个为根布局的控件id
Button test=findViewById(R.id.test);
//弹出带有input的软键盘
test.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//使用自定义的dialog
final SoftKeyboardInputDialog dialog=new SoftKeyboardInputDialog(MainActivity.this,R.style.DialogTheme);
dialog.show();
/** ==== ps:如果想按返回键关闭软键盘的同时也关闭dialog,那可以写如下代码:
监听布局宽高变化,进而退出dialog(软键盘弹出布局变小,退出则恢复,以此来判断键盘弹出或退出)
该activity的布局一定要有ScrollView控件 或 滚动的控件(ps:控件可无内容,只为实现布局因软键盘状态而大小变化),
或在AndroidManifest.xml对应<activity>里加入:android:windowSoftInputMode="adjustResize",
或有RecyclerView,否则软键盘弹出或隐藏布局大小没有变化!!
*/
llRoot.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
if (bottom>oldBottom){
dialog.dismiss();
llRoot.removeOnLayoutChangeListener(this);//移除监听,避免不需要时还在监听
}
}
});
}
});
}
}
tip:注意:若动态设置数字键盘,可能有键盘切换的过程而让bottom>oldBottom,所以解决方法:
1.在onCreate方法里写:(ps:必须要在post方法里获取宽高底左右等等参数,否则会获取为0)
llRoot.post(new Runnable() {
@Override
public void run() {
bottom = llRoot.getBottom();//bottom为全局变量
}
});
2.上面的代码更改为
if (MainActivity.this.bottom==bottom){
dialog.dismiss();
llRoot.removeOnLayoutChangeListener(this);//移除监听,避免不需要时还在监听
}