最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

java - Button with RepeatListener in Android does not change color when being pressed - Stack Overflow

programmeradmin2浏览0评论

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>
发布评论

评论列表(0)

  1. 暂无评论