簡體   English   中英

如何在Android中擴展Button類?

[英]How to extend the Button class in Android?

我正在嘗試擴展 Android 中的Button類。 我有一個flicker.java和一個MainActivity.java 我想擴展 Button 類並向它添加一個像public void flicker_with_current_color(){}這樣的方法,以便我可以使用flicker.flicker_with_current_color(); MainActivity.java 不幸的是,Android Studio 給了我錯誤(作為提示):

此自定義視圖應改為擴展 androidx.appcompat.widget.AppCompatButton

我想要做的是添加一個自定義方法,以便我可以在任何地方使用它。 我知道這可以通過在MainActivity.java創建一個方法來完成,但我正在嘗試創建一個與 Android 的Button類相同但具有更多方法的自定義 Button 類。 我不知道我錯在哪里。

flicker.java

package com.its.me;

import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.provider.CalendarContract;
import android.util.AttributeSet;
import android.widget.Button;
import android.widget.TextView;

import org.w3c.dom.Text;

import java.util.Timer;

public class flicker extends Button{

    public flicker(Context context) {
        super(context);
    }

    public void flicker_with_current_color(Button btn, String color_to_flicker, String color_to_switch_back_to, int time_interval, int times_to_flicker){

        for(int i=0; i<times_to_flicker; i++){

            btn.setTextColor(Color.parseColor(color_to_flicker));

            Timer t = new java.util.Timer();
            t.schedule(
                    new java.util.TimerTask() {
                        @Override
                        public void run() {

                            btn.setTextColor(Color.parseColor(color_to_switch_back_to));

                            t.cancel();
                        }
                    },
                    time_interval
            );

        }
    }

    public void flicker_with_current_color(String color_to_flicker, String color_to_switch_back_to, int time_interval, int times_to_flicker){

        for(int i=0; i<times_to_flicker; i++){

            this.setTextColor(Color.parseColor(color_to_flicker));

            Timer t = new java.util.Timer();
            t.schedule(
                    new java.util.TimerTask() {
                        @Override
                        public void run() {

                            //this.setTextColor(Color.parseColor(color_to_switch_back_to));

                            t.cancel();
                        }
                    },
                    time_interval
            );

        }
    }

    public void flicker_with_current_color(Button btn, int total_time, int times_to_flicker, String color_to_flicker, String color_to_switch_back_to){

        int time_interval = total_time/times_to_flicker;

        for(int i=0; i<times_to_flicker; i++){

            btn.setTextColor(Color.parseColor(color_to_flicker));

            Timer t = new java.util.Timer();
            t.schedule(
                    new java.util.TimerTask() {
                        @Override
                        public void run() {

                            btn.setTextColor(Color.parseColor(color_to_switch_back_to));

                            t.cancel();
                        }
                    },
                    time_interval
            );

        }

    }

}

提前致謝!

首先,您必須記住,您將需要額外的、重載的構造函數。 最重要的一個是您提供 XML 屬性attrs那個 - 沒有它,按鈕甚至無法創建。 您可以在您的代碼中使用這組構造函數,就可以了:

public FlickerButton(Context context) {
    super(context, null, android.R.attr.buttonStyle);
}

public FlickerButton(Context context, AttributeSet attrs) {
    super(context, attrs, android.R.attr.buttonStyle);
}

public FlickerButton(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

您的代碼中可能出現的第二個問題是CalledFromWrongThreadException 當你在不同的線程中設置一個帶有任務的計時器時,Android 會抱怨視圖,在這種情況下是我們的FlickerButton ,正在與創建它的線程不同的線程上操作:

只有創建視圖層次結構的原始線程才能觸及其視圖。

為此,我會改變閃爍動畫的方法。 我將使用ValueAnimator來為顏色閃爍設置動畫,而不是使用計時器。 仔細分析代碼:

private int buttonTextColor = Color.BLACK; // Initially we will set the color to black
private ValueAnimator flickerAnimation; // Animator that will animate between the colors

public void flicker_with_current_color(String colorToFlicker, String colorToSwitchBackTo, int timeInterval, int timesToFlicker) {

    // Animator will animate from the colorToSwitchBackTo 
    // through colorToFlicker and back to the colorToSwitchBackTo
    flickerAnimation = ValueAnimator.ofArgb(
            Color.parseColor(colorToSwitchBackTo),
            Color.parseColor(colorToFlicker),
            Color.parseColor(colorToSwitchBackTo)
    );

    // The duration of one animation interval and how many times teh animation will repeat
    flickerAnimation.setDuration(timeInterval).setRepeatCount(timesToFlicker);

    // Specify what will happen when the animated value will change
    flickerAnimation.addUpdateListener(valueAnimator -> {
        buttonTextColor = (int) valueAnimator.getAnimatedValue();

        // invalidate() will invalidate the view and in turn call the onDraw() method
        invalidate();
    });

    flickerAnimation.start(); // start the animation
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    setTextColor(buttonTextColor);
}

將所有這些代碼放在AppCompatButton的子類中以實現向后兼容性您就可以使用按鈕了:

public class FlickerButton extends AppCompatButton {

    // Insert all the code from above here

}

在 XML 文件中:

<com.example.flickerbutton.FlickerButton
        android:id="@+id/flicker_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Flicker Button" />

FlickerButton的父FlickerButton

((FlickerButton) findViewById(R.id.flicker_button)).setOnClickListener(view -> {
        ((FlickerButton) view).flicker_with_current_color(
                "white", "black", 500, 10);
    });

使用所有這些代碼,按鈕的文本顏色將通過黑白顏色閃爍 10 次半秒。

現在,我不會離開你的只有這個代碼-我推薦你讀在Android中的自定義視圖指導,取得更好的對什么在上面的代碼中發生的事情理解和改善你的現有項目。 祝你好運 :)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM