admin管理员组

文章数量:1410706

I have a button in xml layout file

 <Button
        android:id="@+id/button_heat"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text="@string/heat"
        android:textSize="11sp"
        android:background="@drawable/heat_button_background"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHeight_percent="0.124"
        app:layout_constraintHorizontal_bias="0.373"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.885"
        app:layout_constraintWidth_percent="0.12" />

It is attached to a repeat listener in the main java fragment file:

// Define and register RepeatListener on the heat button
binding.buttonHeat.setOnTouchListener(new RepeatListener(30, 30, this.getContext(), view -> {
    rotationAngle -= 11.0F;
    binding.fan.setRotation(-rotationAngle);
    currentlyActiveEventRectangleInTarget = checkPositionsOfActiveElements(true);

    if (currentlyActiveEventRectangleInTarget!= lastIntervalActiveEventRectangleInTarget) {
        if (lastIntervalActiveEventRectangleInTarget !=null && lastIntervalActiveEventRectangleInTarget.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_SOLAR)) {
            lastIntervalActiveEventRectangleInTarget.setBackground(ContextCompat.getDrawable(requireContext(), R.drawable.game_event_rectangle_solar_1));
        }
        if (lastIntervalActiveEventRectangleInTarget !=null && lastIntervalActiveEventRectangleInTarget.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_WIND)) {
            lastIntervalActiveEventRectangleInTarget.setBackground(ContextCompat.getDrawable(requireContext(), R.drawable.game_event_rectangle_wind_1));
        }
        if (lastIntervalActiveEventRectangleInTarget !=null && lastIntervalActiveEventRectangleInTarget.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_GAS)) {
            lastIntervalActiveEventRectangleInTarget.setBackground(ContextCompat.getDrawable(requireContext(), R.drawable.game_event_rectangle_gas_1));
        }
        if (lastIntervalActiveEventRectangleInTarget !=null && lastIntervalActiveEventRectangleInTarget.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_COAL)) {
            lastIntervalActiveEventRectangleInTarget.setBackground(ContextCompat.getDrawable(requireContext(), R.drawable.game_event_rectangle_coal_1));
        }
        lastIntervalActiveEventRectangleInTarget = currentlyActiveEventRectangleInTarget;
    }
    else {
        if (lastIntervalActiveEventRectangleInTarget !=null && lastIntervalActiveEventRectangleInTarget.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_SOLAR)) {
            lastIntervalActiveEventRectangleInTarget.setBackground(ContextCompat.getDrawable(requireContext(), R.drawable.game_event_rectangle_solar_2));
        }
        if (lastIntervalActiveEventRectangleInTarget !=null && lastIntervalActiveEventRectangleInTarget.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_WIND)) {
            lastIntervalActiveEventRectangleInTarget.setBackground(ContextCompat.getDrawable(requireContext(), R.drawable.game_event_rectangle_wind_2));
        }
        if (lastIntervalActiveEventRectangleInTarget !=null && lastIntervalActiveEventRectangleInTarget.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_GAS)) {
            lastIntervalActiveEventRectangleInTarget.setBackground(ContextCompat.getDrawable(requireContext(), R.drawable.game_event_rectangle_gas_2));
        }
        if (lastIntervalActiveEventRectangleInTarget !=null && lastIntervalActiveEventRectangleInTarget.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_COAL)) {
            lastIntervalActiveEventRectangleInTarget.setBackground(ContextCompat.getDrawable(requireContext(), R.drawable.game_event_rectangle_coal_2));
        }
    }

    // the code to execute repeatedly
    if(heatBuilding) {
        thermometer.changeTemperature(0.6);
        RepeatListener.setCurrentlyActiveGameRectangle(currentlyActiveEventRectangleInTarget);

    }

    if (heatDHWTank) {
        hotWaterTank.changeVolumeBar(0.6);
        RepeatListener.setCurrentlyActiveGameRectangle(currentlyActiveEventRectangleInTarget);
    }

    lastIntervalActiveEventRectangleInTarget = currentlyActiveEventRectangleInTarget;
    view.performClick();



}));

The repeat listener looks like this
package com.example.game;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;

import androidx.core.content.ContextCompat;

/**
 * A class, that can be used as a TouchListener on any view (e.g. a Button).
 * It cyclically runs a clickListener, emulating keyboard-like behaviour. First
 * click is fired immediately, next one after the initialInterval, and subsequent
 * ones after the normalInterval.
 *
 * <p>Interval is scheduled after the onClick completes, so it has to run fast.
 * If it runs slow, it does not generate skipped onClicks. Can be rewritten to
 * achieve this.
 */
public class RepeatListener implements View.OnTouchListener {

    private final Handler handler = new Handler();

    private final int initialInterval;
    private final int normalInterval;
    private final View.OnClickListener clickListener;
    private View touchedView;

    private final Context context;



    private static View_Game_Event_Rectangle currentlyActiveGameRectangle;



    private final Runnable handlerRunnable = new Runnable() {
        @Override
        public void run() {
            if(touchedView.isEnabled()) {
                handler.postDelayed(this, normalInterval);
                clickListener.onClick(touchedView);
            } else {
                // if the view was disabled by the clickListener, remove the callback
                handler.removeCallbacks(handlerRunnable);
                touchedView.setPressed(false);
                touchedView = null;
            }
        }
    };

    /**
     * @param initialInterval The interval after first click event
     * @param normalInterval The interval after second and subsequent click
     *       events
     * @param clickListener The OnClickListener, that will be called
     *       periodically
     */
    public RepeatListener(int initialInterval, int normalInterval, Context context,
                          View.OnClickListener clickListener) {
        if (clickListener == null)
            throw new IllegalArgumentException("null runnable");
        if (initialInterval < 0 || normalInterval < 0)
            throw new IllegalArgumentException("negative interval");

        this.initialInterval = initialInterval;
        this.normalInterval = normalInterval;
        this.clickListener = clickListener;
        this.context = context;
    }

    @SuppressLint("ClickableViewAccessibility")
    public boolean onTouch(View view, MotionEvent motionEvent) {
        switch (motionEvent.getAction()) {
            case MotionEvent.ACTION_DOWN:

                handler.removeCallbacks(handlerRunnable);
                handler.postDelayed(handlerRunnable, initialInterval);
                touchedView = view;
                touchedView.setPressed(true);
                touchedView.setBackgroundResource(R.drawable.heat_button_background_pressed);
                clickListener.onClick(view);

                if (currentlyActiveGameRectangle !=null) {
                    if(currentlyActiveGameRectangle.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_SOLAR)) {
                        currentlyActiveGameRectangle.setBackground(ContextCompat.getDrawable(context, R.drawable.game_event_rectangle_solar_2));
                    }
                    if(currentlyActiveGameRectangle.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_WIND)) {
                        currentlyActiveGameRectangle.setBackground(ContextCompat.getDrawable(context, R.drawable.game_event_rectangle_wind_2));
                    }
                    if(currentlyActiveGameRectangle.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_GAS)) {
                        currentlyActiveGameRectangle.setBackground(ContextCompat.getDrawable(context, R.drawable.game_event_rectangle_gas_2));
                    }
                    if(currentlyActiveGameRectangle.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_COAL)) {
                        currentlyActiveGameRectangle.setBackground(ContextCompat.getDrawable(context, R.drawable.game_event_rectangle_coal_2));
                    }
                }
                return true;
            case MotionEvent.ACTION_UP:
                // Restore normal background
                if (touchedView != null) {
                    touchedView.setBackgroundResource(R.drawable.heat_button_background_normal);
                    touchedView.setPressed(false); // Remove the pressed state
                    handler.removeCallbacks(handlerRunnable);
                }

                if (currentlyActiveGameRectangle !=null) {
                    if(currentlyActiveGameRectangle.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_SOLAR)) {
                        currentlyActiveGameRectangle.setBackground(ContextCompat.getDrawable(context, R.drawable.game_event_rectangle_solar_1));
                    }
                    if(currentlyActiveGameRectangle.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_WIND)) {
                        currentlyActiveGameRectangle.setBackground(ContextCompat.getDrawable(context, R.drawable.game_event_rectangle_wind_1));
                    }
                    if(currentlyActiveGameRectangle.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_GAS)) {
                        currentlyActiveGameRectangle.setBackground(ContextCompat.getDrawable(context, R.drawable.game_event_rectangle_gas_1));
                    }
                    if(currentlyActiveGameRectangle.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_COAL)) {
                        currentlyActiveGameRectangle.setBackground(ContextCompat.getDrawable(context, R.drawable.game_event_rectangle_coal_1));
                    }
                }
                return true;
            case MotionEvent.ACTION_CANCEL:
                handler.removeCallbacks(handlerRunnable);
                touchedView.setPressed(false);
                touchedView = null;
                return true;
        }

        return false;
    }

    public static void setCurrentlyActiveGameRectangle(View_Game_Event_Rectangle currentlyActiveGameRectangle) {
        RepeatListener.currentlyActiveGameRectangle = currentlyActiveGameRectangle;
    }

}

and I have 3 xml drawable files: heat_button_background:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android=";>
    <item android:state_pressed="true">
        <layer-list>
            <item>
                <shape android:shape="rectangle">
                    <solid android:color="#FFFFFF" /> <!-- White when pressed -->
                    <corners android:radius="8dp" /> <!-- Rounded corners -->
                </shape>
            </item>
        </layer-list>
    </item>
    <item>
        <layer-list>
            <item>
                <shape android:shape="rectangle">
                    <solid android:color="#CCCCCC" /> <!-- Light gray when not pressed -->
                    <corners android:radius="8dp" /> <!-- Rounded corners -->
                </shape>
            </item>
        </layer-list>
    </item>
</selector>

heat_button_background_normal:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android=";>
    <item>
        <layer-list>
            <item>
                <shape android:shape="rectangle">
                    <solid android:color="#CCCCCC" /> <!-- Light gray when not pressed -->
                    <corners android:radius="8dp" /> <!-- Rounded corners -->
                </shape>
            </item>
        </layer-list>
    </item>
</selector>

heat_button_background_pressed:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android=";>
    <item>
        <layer-list>
            <item>
                <shape android:shape="rectangle">
                    <solid android:color="#FFFFFF" /> <!-- White when pressed -->
                    <corners android:radius="8dp" /> <!-- Rounded corners -->
                </shape>
            </item>
        </layer-list>
    </item>
</selector>

Unforuantely, when pressing the button, is does not change its color or anything regarding its layout (altough the logic of the button in the game app with the repeat listener works properly). Can you think of a reason as to why this is happening? I think it might have something to do with the repeat listener as it might be refreshing the layout or something like that. But I tried a lot and could not solve the problem.

Reminder: Does anyone have any idea as to why this is happening?

I have a button in xml layout file

 <Button
        android:id="@+id/button_heat"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text="@string/heat"
        android:textSize="11sp"
        android:background="@drawable/heat_button_background"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHeight_percent="0.124"
        app:layout_constraintHorizontal_bias="0.373"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.885"
        app:layout_constraintWidth_percent="0.12" />

It is attached to a repeat listener in the main java fragment file:

// Define and register RepeatListener on the heat button
binding.buttonHeat.setOnTouchListener(new RepeatListener(30, 30, this.getContext(), view -> {
    rotationAngle -= 11.0F;
    binding.fan.setRotation(-rotationAngle);
    currentlyActiveEventRectangleInTarget = checkPositionsOfActiveElements(true);

    if (currentlyActiveEventRectangleInTarget!= lastIntervalActiveEventRectangleInTarget) {
        if (lastIntervalActiveEventRectangleInTarget !=null && lastIntervalActiveEventRectangleInTarget.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_SOLAR)) {
            lastIntervalActiveEventRectangleInTarget.setBackground(ContextCompat.getDrawable(requireContext(), R.drawable.game_event_rectangle_solar_1));
        }
        if (lastIntervalActiveEventRectangleInTarget !=null && lastIntervalActiveEventRectangleInTarget.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_WIND)) {
            lastIntervalActiveEventRectangleInTarget.setBackground(ContextCompat.getDrawable(requireContext(), R.drawable.game_event_rectangle_wind_1));
        }
        if (lastIntervalActiveEventRectangleInTarget !=null && lastIntervalActiveEventRectangleInTarget.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_GAS)) {
            lastIntervalActiveEventRectangleInTarget.setBackground(ContextCompat.getDrawable(requireContext(), R.drawable.game_event_rectangle_gas_1));
        }
        if (lastIntervalActiveEventRectangleInTarget !=null && lastIntervalActiveEventRectangleInTarget.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_COAL)) {
            lastIntervalActiveEventRectangleInTarget.setBackground(ContextCompat.getDrawable(requireContext(), R.drawable.game_event_rectangle_coal_1));
        }
        lastIntervalActiveEventRectangleInTarget = currentlyActiveEventRectangleInTarget;
    }
    else {
        if (lastIntervalActiveEventRectangleInTarget !=null && lastIntervalActiveEventRectangleInTarget.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_SOLAR)) {
            lastIntervalActiveEventRectangleInTarget.setBackground(ContextCompat.getDrawable(requireContext(), R.drawable.game_event_rectangle_solar_2));
        }
        if (lastIntervalActiveEventRectangleInTarget !=null && lastIntervalActiveEventRectangleInTarget.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_WIND)) {
            lastIntervalActiveEventRectangleInTarget.setBackground(ContextCompat.getDrawable(requireContext(), R.drawable.game_event_rectangle_wind_2));
        }
        if (lastIntervalActiveEventRectangleInTarget !=null && lastIntervalActiveEventRectangleInTarget.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_GAS)) {
            lastIntervalActiveEventRectangleInTarget.setBackground(ContextCompat.getDrawable(requireContext(), R.drawable.game_event_rectangle_gas_2));
        }
        if (lastIntervalActiveEventRectangleInTarget !=null && lastIntervalActiveEventRectangleInTarget.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_COAL)) {
            lastIntervalActiveEventRectangleInTarget.setBackground(ContextCompat.getDrawable(requireContext(), R.drawable.game_event_rectangle_coal_2));
        }
    }

    // the code to execute repeatedly
    if(heatBuilding) {
        thermometer.changeTemperature(0.6);
        RepeatListener.setCurrentlyActiveGameRectangle(currentlyActiveEventRectangleInTarget);

    }

    if (heatDHWTank) {
        hotWaterTank.changeVolumeBar(0.6);
        RepeatListener.setCurrentlyActiveGameRectangle(currentlyActiveEventRectangleInTarget);
    }

    lastIntervalActiveEventRectangleInTarget = currentlyActiveEventRectangleInTarget;
    view.performClick();



}));

The repeat listener looks like this
package com.example.game;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;

import androidx.core.content.ContextCompat;

/**
 * A class, that can be used as a TouchListener on any view (e.g. a Button).
 * It cyclically runs a clickListener, emulating keyboard-like behaviour. First
 * click is fired immediately, next one after the initialInterval, and subsequent
 * ones after the normalInterval.
 *
 * <p>Interval is scheduled after the onClick completes, so it has to run fast.
 * If it runs slow, it does not generate skipped onClicks. Can be rewritten to
 * achieve this.
 */
public class RepeatListener implements View.OnTouchListener {

    private final Handler handler = new Handler();

    private final int initialInterval;
    private final int normalInterval;
    private final View.OnClickListener clickListener;
    private View touchedView;

    private final Context context;



    private static View_Game_Event_Rectangle currentlyActiveGameRectangle;



    private final Runnable handlerRunnable = new Runnable() {
        @Override
        public void run() {
            if(touchedView.isEnabled()) {
                handler.postDelayed(this, normalInterval);
                clickListener.onClick(touchedView);
            } else {
                // if the view was disabled by the clickListener, remove the callback
                handler.removeCallbacks(handlerRunnable);
                touchedView.setPressed(false);
                touchedView = null;
            }
        }
    };

    /**
     * @param initialInterval The interval after first click event
     * @param normalInterval The interval after second and subsequent click
     *       events
     * @param clickListener The OnClickListener, that will be called
     *       periodically
     */
    public RepeatListener(int initialInterval, int normalInterval, Context context,
                          View.OnClickListener clickListener) {
        if (clickListener == null)
            throw new IllegalArgumentException("null runnable");
        if (initialInterval < 0 || normalInterval < 0)
            throw new IllegalArgumentException("negative interval");

        this.initialInterval = initialInterval;
        this.normalInterval = normalInterval;
        this.clickListener = clickListener;
        this.context = context;
    }

    @SuppressLint("ClickableViewAccessibility")
    public boolean onTouch(View view, MotionEvent motionEvent) {
        switch (motionEvent.getAction()) {
            case MotionEvent.ACTION_DOWN:

                handler.removeCallbacks(handlerRunnable);
                handler.postDelayed(handlerRunnable, initialInterval);
                touchedView = view;
                touchedView.setPressed(true);
                touchedView.setBackgroundResource(R.drawable.heat_button_background_pressed);
                clickListener.onClick(view);

                if (currentlyActiveGameRectangle !=null) {
                    if(currentlyActiveGameRectangle.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_SOLAR)) {
                        currentlyActiveGameRectangle.setBackground(ContextCompat.getDrawable(context, R.drawable.game_event_rectangle_solar_2));
                    }
                    if(currentlyActiveGameRectangle.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_WIND)) {
                        currentlyActiveGameRectangle.setBackground(ContextCompat.getDrawable(context, R.drawable.game_event_rectangle_wind_2));
                    }
                    if(currentlyActiveGameRectangle.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_GAS)) {
                        currentlyActiveGameRectangle.setBackground(ContextCompat.getDrawable(context, R.drawable.game_event_rectangle_gas_2));
                    }
                    if(currentlyActiveGameRectangle.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_COAL)) {
                        currentlyActiveGameRectangle.setBackground(ContextCompat.getDrawable(context, R.drawable.game_event_rectangle_coal_2));
                    }
                }
                return true;
            case MotionEvent.ACTION_UP:
                // Restore normal background
                if (touchedView != null) {
                    touchedView.setBackgroundResource(R.drawable.heat_button_background_normal);
                    touchedView.setPressed(false); // Remove the pressed state
                    handler.removeCallbacks(handlerRunnable);
                }

                if (currentlyActiveGameRectangle !=null) {
                    if(currentlyActiveGameRectangle.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_SOLAR)) {
                        currentlyActiveGameRectangle.setBackground(ContextCompat.getDrawable(context, R.drawable.game_event_rectangle_solar_1));
                    }
                    if(currentlyActiveGameRectangle.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_WIND)) {
                        currentlyActiveGameRectangle.setBackground(ContextCompat.getDrawable(context, R.drawable.game_event_rectangle_wind_1));
                    }
                    if(currentlyActiveGameRectangle.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_GAS)) {
                        currentlyActiveGameRectangle.setBackground(ContextCompat.getDrawable(context, R.drawable.game_event_rectangle_gas_1));
                    }
                    if(currentlyActiveGameRectangle.getEventType().equals(FR_Game.VIEW_EVENT_RECTANGLE_COAL)) {
                        currentlyActiveGameRectangle.setBackground(ContextCompat.getDrawable(context, R.drawable.game_event_rectangle_coal_1));
                    }
                }
                return true;
            case MotionEvent.ACTION_CANCEL:
                handler.removeCallbacks(handlerRunnable);
                touchedView.setPressed(false);
                touchedView = null;
                return true;
        }

        return false;
    }

    public static void setCurrentlyActiveGameRectangle(View_Game_Event_Rectangle currentlyActiveGameRectangle) {
        RepeatListener.currentlyActiveGameRectangle = currentlyActiveGameRectangle;
    }

}

and I have 3 xml drawable files: heat_button_background:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android/apk/res/android">
    <item android:state_pressed="true">
        <layer-list>
            <item>
                <shape android:shape="rectangle">
                    <solid android:color="#FFFFFF" /> <!-- White when pressed -->
                    <corners android:radius="8dp" /> <!-- Rounded corners -->
                </shape>
            </item>
        </layer-list>
    </item>
    <item>
        <layer-list>
            <item>
                <shape android:shape="rectangle">
                    <solid android:color="#CCCCCC" /> <!-- Light gray when not pressed -->
                    <corners android:radius="8dp" /> <!-- Rounded corners -->
                </shape>
            </item>
        </layer-list>
    </item>
</selector>

heat_button_background_normal:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android/apk/res/android">
    <item>
        <layer-list>
            <item>
                <shape android:shape="rectangle">
                    <solid android:color="#CCCCCC" /> <!-- Light gray when not pressed -->
                    <corners android:radius="8dp" /> <!-- Rounded corners -->
                </shape>
            </item>
        </layer-list>
    </item>
</selector>

heat_button_background_pressed:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android/apk/res/android">
    <item>
        <layer-list>
            <item>
                <shape android:shape="rectangle">
                    <solid android:color="#FFFFFF" /> <!-- White when pressed -->
                    <corners android:radius="8dp" /> <!-- Rounded corners -->
                </shape>
            </item>
        </layer-list>
    </item>
</selector>

Unforuantely, when pressing the button, is does not change its color or anything regarding its layout (altough the logic of the button in the game app with the repeat listener works properly). Can you think of a reason as to why this is happening? I think it might have something to do with the repeat listener as it might be refreshing the layout or something like that. But I tried a lot and could not solve the problem.

Reminder: Does anyone have any idea as to why this is happening?

Share edited Mar 14 at 14:23 VanessaF asked Mar 7 at 11:05 VanessaFVanessaF 7552 gold badges17 silver badges48 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 2

Updated RepeatListener.java

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
import androidx.core.content.ContextCompat;

public class RepeatListener implements View.OnTouchListener {

    private final int initialInterval;
    private final int normalInterval;
    private final View.OnClickListener clickListener;
    private final Context context;
    private final Handler handler = new Handler();
    private View touchedView;
    private GameRectangle currentlyActiveGameRectangle; // Assuming this is defined somewhere
    private final Runnable handlerRunnable = new Runnable() {
        @Override
        public void run() {
            if (touchedView != null && touchedView.isPressed()) {
                clickListener.onClick(touchedView);
                handler.postDelayed(this, normalInterval);
            }
        }
    };

    public RepeatListener(int initialInterval, int normalInterval, Context context,
                          View.OnClickListener clickListener) {
        if (clickListener == null)
            throw new IllegalArgumentException("null runnable");
        if (initialInterval < 0 || normalInterval < 0)
            throw new IllegalArgumentException("negative interval");

        this.initialInterval = initialInterval;
        this.normalInterval = normalInterval;
        this.clickListener = clickListener;
        this.context = context;
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        switch (motionEvent.getAction()) {
            case MotionEvent.ACTION_DOWN:
                handler.removeCallbacks(handlerRunnable);
                handler.postDelayed(handlerRunnable, initialInterval);
                touchedView = view;
                touchedView.setPressed(true);

                // Change background when pressed
                touchedView.setBackground(ContextCompat.getDrawable(context, R.drawable.heat_button_background_pressed));

                clickListener.onClick(view);

                // Change the currently active game rectangle background
                if (currentlyActiveGameRectangle != null) {
                    switch (currentlyActiveGameRectangle.getEventType()) {
                        case FR_Game.VIEW_EVENT_RECTANGLE_SOLAR:
                            currentlyActiveGameRectangle.setBackground(ContextCompat.getDrawable(context, R.drawable.game_event_rectangle_solar_2));
                            break;
                        case FR_Game.VIEW_EVENT_RECTANGLE_WIND:
                            currentlyActiveGameRectangle.setBackground(ContextCompat.getDrawable(context, R.drawable.game_event_rectangle_wind_2));
                            break;
                        case FR_Game.VIEW_EVENT_RECTANGLE_GAS:
                            currentlyActiveGameRectangle.setBackground(ContextCompat.getDrawable(context, R.drawable.game_event_rectangle_gas_2));
                            break;
                        case FR_Game.VIEW_EVENT_RECTANGLE_COAL:
                            currentlyActiveGameRectangle.setBackground(ContextCompat.getDrawable(context, R.drawable.game_event_rectangle_coal_2));
                            break;
                    }
                }
                return true;

            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                if (touchedView != null) {
                    touchedView.setPressed(false);
                    handler.removeCallbacks(handlerRunnable);

                    // Restore normal background
                    touchedView.setBackground(ContextCompat.getDrawable(context, R.drawable.heat_button_background_normal));
                }

                // Restore the currently active game rectangle background
                if (currentlyActiveGameRectangle != null) {
                    switch (currentlyActiveGameRectangle.getEventType()) {
                        case FR_Game.VIEW_EVENT_RECTANGLE_SOLAR:
                            currentlyActiveGameRectangle.setBackground(ContextCompat.getDrawable(context, R.drawable.game_event_rectangle_solar_1));
                            break;
                        case FR_Game.VIEW_EVENT_RECTANGLE_WIND:
                            currentlyActiveGameRectangle.setBackground(ContextCompat.getDrawable(context, R.drawable.game_event_rectangle_wind_1));
                            break;
                        case FR_Game.VIEW_EVENT_RECTANGLE_GAS:
                            currentlyActiveGameRectangle.setBackground(ContextCompat.getDrawable(context, R.drawable.game_event_rectangle_gas_1));
                            break;
                        case FR_Game.VIEW_EVENT_RECTANGLE_COAL:
                            currentlyActiveGameRectangle.setBackground(ContextCompat.getDrawable(context, R.drawable.game_event_rectangle_coal_1));
                            break;
                    }
                }
                touchedView = null;
                return true;
        }

        return false;
    }
    public static void setCurrentlyActiveGameRectangle(View_Game_Event_Rectangle currentlyActiveGameRectangle) {
        RepeatListener.currentlyActiveGameRectangle = currentlyActiveGameRectangle;
    }
}

Button in activity_main.xml

<Button
    android:id="@+id/button_heat"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:text="@string/heat"
    android:textSize="11sp"
    android:background="@drawable/heat_button_background_normal"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHeight_percent="0.124"
    app:layout_constraintHorizontal_bias="0.373"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintVertical_bias="0.885"
    app:layout_constraintWidth_percent="0.12"/>

Updated Background Drawables

res/drawable/heat_button_background_normal.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android/apk/res/android" android:shape="rectangle">
    <solid android:color="#CCCCCC"/> <!-- Light gray when not pressed -->
    <corners android:radius="8dp"/>
</shape>

res/drawable/heat_button_background_pressed.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android/apk/res/android" android:shape="rectangle">
    <solid android:color="#FFFFFF"/> <!-- White when pressed -->
    <corners android:radius="8dp"/>
</shape>

本文标签: javaButton with RepeatListener in Android does not change color when being pressedStack Overflow