所以我有一个用户输入数据的对话框,这里是用户的年龄。所以我希望当/如果用户让edittext留空时,edittext会像在api演示中那样做震动动画。到目前为止,当输入无效信息时,我无法获得不解散的对话框。谢谢。
mInflater = (LayoutInflater) Information.this.getSystemService(LAYOUT_INFLATER_SERVICE);
mLayout = mInflater.inflate(R.layout.agedialog, null);
mAgeEditText = (EditText) mLayout.findViewById(R.id.AgeEditText);
mAgeResultTextView = (TextView) findViewById(R.id.AgeResultTextView);
final Animation shake = AnimationUtils.loadAnimation(Information.this, R.anim.shake);
mInputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
mInputManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
new AlertDialog.Builder(Information.this).setView(mLayout).setTitle(R.string.EnterYourAge)
.setPositiveButton(R.string.OK, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mInputManager.hideSoftInputFromWindow(mAgeEditText.getWindowToken(), 0);
if (TextUtils.isEmpty(mAgeEditText.getText())) {
mAgeEditText.startAnimation(shake);
// here the dialog dismisses even if I call startAnimation
}
else {
HelperClass.getInstance().setAge(Integer.parseInt(mAgeEditText.getText().toString()));
mAgeResultTextView.setText(HelperClass.getInstance().getAge());
}
}
}).setNegativeButton(R.string.Cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mInputManager.hideSoftInputFromWindow(mAgeEditText.getWindowToken(), 0);
dialog.cancel();
}
}).show();
一个额外的夏日小爱情故事:
如果你想摇动整个AlertDialog
,而不仅仅是EditText
,你可以在你的对话片段中这样做:
(注意!为了清晰起见,我省略了任何完整性检查,例如示例代码中上下文和窗口的空验证)
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Create the alert dialog as usual.
AlertDialog shakyAlertDialog = new AlertDialog.Builder(getContext())
.setTitle(R.string.title)
.setMessage(R.string.message) // Optional
.setView(R.layout.input) // This one holds your EditText
.setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.ok, null)
.show();
// Get hold of the edit text we want to validate on.
EditText input = shakyAlertDialog.findViewById(R.id.age_input);
// Replace the "OK" button's click listener. As discussed in previous
// answers this will replace the auto-dismiss behavior.
shakyAlertDialog
.getButton(DialogInterface.BUTTON_POSITIVE)
.setOnClickListener(view -> {
if (input.getText().isEmpty()) {
// This is the gold. This is how we shake the entire
// AlertDialog, not only the EditText.
shakyAlertDialog
.getWindow()
.getDecorView()
.animate()
.translationX(16f)
.setInterpolator(new CycleInterpolator(7f))
} else {
// Do something with the input, but don't
// forget to manually dismiss the dialog.
shakyAlertDialog.dismiss()
}
});
return shakyAlertDialog;
}
好的,所以我想出了答案很长一段时间后,这是问,但万一有人想要这个,我认为这是明智的继续并发布答案。
基本上这不能用警告对话框完成,它与按钮和消极按钮被点击时的行为有关。然而,这可以用一个常规的对话框来完成。你需要一些动画xml文件,这些文件可以在api demo的animm文件夹res下找到(api demo中的原始java文件是Animation1.java,所以你可以查看一下)。我还做了这样的设计,这样键盘就可以让用户随时输入。你可以通过删除所有的inputmanager来摆脱它。无论如何,下面是对话框的代码。
public void showAgeDialog() {
final Dialog dialog = new Dialog(Information.this);
dialog.setContentView(R.layout.age_dialog);
dialog.setTitle(R.string.InputAge);
final EditText ageEditText = (EditText) dialog.findViewById(R.id.AgeEditText);
inputManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
dialog.show();
Button positive = (Button) dialog.findViewById(R.id.OkButton);
Button negative = (Button) dialog.findViewById(R.id.CancelButton);
positive.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
if (ageEditText.getText().toString().isEmpty()) {
Animation shake = AnimationUtils.loadAnimation(Information.this, R.anim.shake);
ageEditText.startAnimation(shake);
Toast.makeText(Information.this, "Please enter an age", Toast.LENGTH_SHORT).show();
}
else {
database.updateAge(Integer.parseInt(ageEditText.getText().toString()));
inputManager.hideSoftInputFromWindow(ageEditText.getWindowToken(), 0);
dialog.dismiss();
}
}
});
negative.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
inputManager.hideSoftInputFromWindow(ageEditText.getWindowToken(), 0);
dialog.dismiss();
}
});
}
这是我的布局代码。我让这个对话框看起来完全像一个警告对话框,有确定和取消按钮,背景是灰色的。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<EditText
android:id="@+id/AgeEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginBottom="18dp"
android:layout_marginLeft="100dp"
android:layout_marginRight="100dp"
android:hint="@string/Years"
android:inputType="number"
android:maxLength="2"
android:textSize="18sp" >
</EditText>
<LinearLayout
style="@android:style/ButtonBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/OkButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/Ok" />
<Button
android:id="@+id/CancelButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/Cancel" />
</LinearLayout>
</LinearLayout>
使用AlertDialog实现OPs请求是完全可能的。不过,稍微调整一下是必要的。
AlertDialog
将在您使用构建器创建的按钮上注册自己的OnClickListener
。这些处理程序将在拒绝对话框之前委托给您注册的侦听器。
show()
之后立即注册自己的处理程序,从而覆盖对话框自己的侦听器:
mLayout = mInflater.inflate(R.layout.agedialog, null);
mAgeEditText = (EditText) mLayout.findViewById(R.id.AgeEditText);
mAgeResultTextView = (TextView) findViewById(R.id.AgeResultTextView);
Animation shake = AnimationUtils.loadAnimation(Information.this, R.anim.shake);
// create dialog with buttons but without registering click listeners
AlertDialog dialog = new AlertDialog.Builder(Information.this)
.setView(mLayout)
.setTitle(R.string.EnterYourAge)
.setPositiveButton(R.string.OK, null) // only declare button, add listener later
.setNegativeButton(R.string.Cancel, null) // dito
.create();
// define click listeners for ok and cancel
OnClickListener okListener = new OnClickListener() {
public void onClick(View button) {
mInputManager.hideSoftInputFromWindow(mAgeEditText.getWindowToken(), 0);
if (TextUtils.isEmpty(mAgeEditText.getText())) {
// input not valid -> shake
mAgeEditText.startAnimation(shake);
}
else {
HelperClass.getInstance().setAge(Integer.parseInt(mAgeEditText.getText().toString()));
mAgeResultTextView.setText(HelperClass.getInstance().getAge());
dialog.dismiss(); // close dialog, since input is valid
}
}
};
OnClickListener cancelListener = ...
// show dialog and immediately register our own listeners afterwards
dialog.show();
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(okListener);
dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(cancelListener);