Встряхните анимацию с помощью Alert Dialog (если недопустимая информация потрясет текст редактирования и не пропустите)

1

Итак, у меня есть диалог, в котором пользователь вводит данные, вот возраст пользователя. Поэтому мне бы хотелось, чтобы когда/если пользователь покидает текст 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();
Теги:
android-layout

4 ответа

4
Лучший ответ

Хорошо, поэтому я выяснил ответ долгое время после того, как это было спрошено, но на всякий случай кто-то этого захочет, я подумал, что было бы разумно идти дальше и публиковать ответ.

В принципе, это невозможно сделать с помощью диалогового окна Alert Dialog, это связано с поведением при нажатии кнопки и отрицательных кнопок. Однако это можно сделать с помощью обычного диалога. Вам нужно несколько анимационных xmls, и их можно найти в папке api demo anim под res (исходный java файл - Animation1.java в api demos, чтобы вы могли проверить это). Я также сделал так, чтобы клавиатура была готова для ввода пользователем. Вы можете избавиться от этого, удалив все элементы 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();
        }
    });
}

Вот код моего макета. Я сделал это диалоговое окно таким же, как диалоговое окно Alert Dialog с кнопками Ok и Cancel вместе с серым фоном.

    <?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>
  • 0
    у каждого всегда есть заголовок поста в блоге "animate alertDialog" .. который очень расстраивает / вводит в заблуждение .. вы на 100% правы, вы не можете анимировать AlertDialog, но вы можете анимировать диалог.
0

Немного истории о любви летом:

Если вы хотите встряхнуть весь 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 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;
}
  • 0
    Это прекрасно работает, спасибо
0

Окончательно можно реализовать запрос OPs с помощью AlertDialog. Тем не менее, нужно немного подкорректировать.

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);
0

Отвечайте на мой ответ Android: диалог отклоняется, не вызывая отклонения, чтобы не отклонять диалог.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню