如何在 Android 中扩展 Button 类?
Posted
技术标签:
【中文标题】如何在 Android 中扩展 Button 类?【英文标题】:How to extend the Button class in Android? 【发布时间】:2021-12-24 01:52:08 【问题描述】:我正在尝试在 android 中扩展 Button
类。我有一个flicker.java
和一个MainActivity.java
。我想扩展 Button 类并向其添加类似public void flicker_with_current_color()
的方法,以便我可以在MainActivity.java
中使用flicker.flicker_with_current_color();
。不幸的是,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
);
【问题讨论】:
This custom view should extend androidx.appcompat.widget.AppCompatButton instead
- 这只是一个警告,但最好使用AppCompat
版本的Button
以实现向后兼容性。请参阅here。当涉及到flicker
按钮时 - 完全预期的行为是什么,您提供的代码是否有效?如果不是,那么发生了什么?请改进您的问题。
@sweak,非常感谢!这么晚才回复很抱歉。代码不起作用。当我单击按钮时应用程序崩溃。我只是想为按钮添加一些功能,但我无法在 MainActivity.java 中使用它们。我希望 ExtendedButton 闪烁其参数中的时间和颜色,例如ExtendedButton.flicker_with_current_color(...);
。在 XML 中,我想像 Android 的 Button 类一样添加它,例如 <ExtendedButton.../>
。在问题中,闪烁类是ExtendedButton。我怎样才能做到这一点?
【参考方案1】:
首先您必须记住,您将需要额外的重载构造函数。最重要的一项是您提供 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_
android:layout_
android:text="Flicker Button" />
在FlickerButton
的父级中:
((FlickerButton) findViewById(R.id.flicker_button)).setOnClickListener(view ->
((FlickerButton) view).flicker_with_current_color(
"white", "black", 500, 10);
);
使用所有这些代码,按钮的文本颜色将在半秒内通过黑白闪烁 10 次。
现在我不会只留下这段代码 - 我建议您阅读 Android 中自定义视图的 this 指南,以便更好地了解上述代码中发生的事情并改进您现有的项目。祝你好运:)
【讨论】:
非常感谢您的回答!它不再崩溃,但它不会闪烁。我想我以错误的方式使用它。 This 是 FlickerButton.java,其中包含您答案中的代码。我尝试仅使用您建议的功能,但我看不到按钮/其文本的颜色有任何变化。然后我复制粘贴了问题中的函数,但也没有用。然后我做了另一个函数,但没有按预期工作。 它(我制作的另一个功能:changecol(...)
)只在我点击它时改变颜色(即使是我一直按下按钮的时候也不改变;只有当我释放它时,它才会改变颜色一会儿,然后变回黑色)。我在 MainActivity.java 中使用它,例如:flickerbuttonname.setOnClickListener(new View.OnClickListener() @Override public void onClick(View view) Toast.makeText(MainActivity.this, "Changing color now.", Toast.LENGTH_SHORT).show(); flickerbuttonname.changecol("#00ff00"); );
。我是否正确实施了它?再次感谢:D
您必须向我展示您是如何在onClickListener
中使用flicker_with_current_color
函数的。
您已将时间间隔设置为 5000 毫秒,即 5 秒。颜色过渡需要很长时间,因此没有闪烁效果。使其达到 500。
等等,非常抱歉。当我第一次构建它时,我没有注释掉我的 onDragListener 和 onTouchListener。我很抱歉我忘记了这一点。我想这就是问题所在,并且以某种方式干扰了 UI 和按钮的事件。非常感谢 :D以上是关于如何在 Android 中扩展 Button 类?的主要内容,如果未能解决你的问题,请参考以下文章
Paypal Native Checkout Button 不断加载,然后在 Android 上消失
如何使用 android 中的 SQLite 扩展类在数据库中插入值?