Search code examples
androidandroid-layoutandroid-alertdialogtouch-event

Why isn't TouchListener working on custom alert dialog?


I implmented a class that extends Dialog and implements OnTouchListener, the layout has two TextViews and a third to serve as a button, and I used the TouchListener to change the button color on ActionDown and performClick() on ActionUp but the dialog is not detecting any touch events. It used to work but then I tried to add a second button, and some methods to set the visibility and the onClick() of each button, but since that didn't work because I got an error saying that I was calling OnClickListener on a null reference I tried to revert back. But now it doesn't detect touch events.

public class AlertDialog extends Dialog implements View.OnTouchListener {

    private TextView titleView;
    private TextView messageView;
    private TextView buttonViewLeft;


    private String title;
    private String message;
    private String textButtonLeft;
    private String textButtonRight;


    public void setTextButtonRight(String textButtonRight) {
        this.textButtonRight = textButtonRight;
    }


    public void setTextButtonLeft(String textButtonLeft) {
        this.textButtonLeft = textButtonLeft;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.alertdialog);

        buttonViewLeft = findViewById(R.id.alertButton);

        buttonViewLeft.setVisibility(View.VISIBLE);


        titleView = findViewById(R.id.alertTitle);
        messageView = findViewById(R.id.alertMessage);

        titleView.setText(title);
        messageView.setText(message);

        buttonViewLeft.setText(textButtonLeft);


    }

    public AlertDialog(@NonNull Context context) {
        super(context);
    }


    @Override
    public boolean onTouch(View v, MotionEvent event) {

        Log.e("Touch","Touch");
        switch (event.getAction()) {

            case MotionEvent.ACTION_DOWN:
                buttonViewLeft.setBackgroundColor(ContextCompat.getColor(v.getContext(), R.color.press_grey));
                buttonViewLeft.setAlpha(0.5f);

                return true;

            case MotionEvent.ACTION_UP:
                v.performClick();
                return true;

        }

        return false;
    }
}

 private void wrongCredentialsAlert(String e){

        AlertDialog alertDialog = new AlertDialog(LoginActivity.this);
        alertDialog.setTitle(getString(R.string.alert_incorrect_password_title) + e);
        alertDialog.setMessage(getString(R.string.alert_message_incorrect_password));
        alertDialog.setTextButtonLeft("OK");
        alertDialog.getWindow().setBackgroundDrawableResource(R.color.transparent);
        alertDialog.show();

    }

<?xml version="1.0" encoding="utf-8"?>

<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="250dp"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    app:cardCornerRadius="10dp"
    app:cardPreventCornerOverlap="false">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/alertBackground">

        <TextView
            android:id="@+id/alertTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:gravity="center"
            android:text="TextView"
            android:textColor="?attr/colorOnPrimary"
            android:textSize="18sp"
            android:textStyle="bold"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/alertMessage"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:ems="12"
            android:gravity="center"
            android:text="@string/alert_message_incorrect_password"
            android:textColor="?attr/colorOnPrimary"
            android:textSize="14sp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/alertTitle" />

        <TextView
            android:id="@+id/alertButton"
            android:layout_width="0dp"
            android:layout_height="50dp"
            android:gravity="center"
            android:textColor="@color/white"
            app:layout_constraintTop_toBottomOf="@id/separator"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent" />


        <View
            android:id="@+id/separator"
            android:layout_width="0dp"
            android:layout_height="0.5dp"
            android:layout_marginTop="16dp"
            android:background="@color/separator_grey"
            app:layout_constraintBottom_toTopOf="@+id/alertButton"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@id/alertMessage" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</com.google.android.material.card.MaterialCardView>

Solution

  • you are never setting the OnTouchListener to anything. The implements only means that it has a function that has been defined in the OnTouchListener interface. If onTouch should be called you need to set it to any view with setOnTouchListener(this). It seems that you want to do that with your button.

    Just a side note: if you want to react to click events visually there is a bunch of possibilities with background-Drawables depending on the state in XML. The typical event you are looking for is the OnClickListener. Managing the visual appearance yourself in onTouch tends to create problems and I would recommend this only for specific demands.