Android的onFocusChanged函数从未被调用。

7
我创建了一个自定义按钮,扩展了View类,按照这个教程的说明:

http://kahdev.wordpress.com/2008/09/13/making-a-custom-android-button-using-a-custom-view/

但是我有一个问题, onFocusChanged()函数从未被调用。
这是我的代码:
public class CustomButton extends View
{
    ...
    public CustomButton(Context context, Car car) 
    {
        super(context);
        setFocusable(true);
        setBackgroundColor(Color.BLACK);
        setOnClickListener(listenerAdapter);
        setClickable(true);
    }

    @Override
    protected void onFocusChanged(boolean gainFocus, int direction,
                                  Rect previouslyFocusedRect)
    {
        if (gainFocus == true)
        {
            this.setBackgroundColor(Color.rgb(255, 165, 0));
        }
        else
        {
            this.setBackgroundColor(Color.BLACK);
        }
    }
    ...
}

事实上,当我点击我的自定义按钮时,什么也没发生...使用调试器,我可以看到该函数从未被调用。我不知道为什么。
那么,我是否忘记了一步?还有其他我错过的事情吗?

焦点事件与单击事件无关。如果你想要在按钮被点击时执行一些操作,那么请添加一个 onclick 监听器。 - aromero
3个回答

8

事实上,问题是我没有将自定义按钮的属性“触摸模式下可聚焦”设置为true。我已在构造函数中添加setFocusableInTouchMode(true);,现在它表现更好了。感谢Phil和Vicki D的帮助。

public class CustomButton extends View
{
    ...
    public CustomButton(Context context, Car car) 
    {
        super(context);
        setFocusable(true);
        setFocusableInTouchMode(true); // Needed to call onFocusChanged()
        setBackgroundColor(Color.BLACK);
        setOnClickListener(listenerAdapter);
        setClickable(true);
    }

    @Override
    protected void onFocusChanged(boolean gainFocus, int direction,
                                  Rect previouslyFocusedRect)
    {
        if (gainFocus == true)
        {
            this.setBackgroundColor(Color.rgb(255, 165, 0));
        }
        else
        {
            this.setBackgroundColor(Color.BLACK);
        }
        super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);  
    }
    ...
}

0
文档中说:“当覆盖时,请确保调用超类,以便发生标准的焦点处理。” 您在上面的代码中省略了该调用,类似下面的代码应该有所帮助。
@Override
protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect)
{

    if (gainFocus == true)
    {
        this.setBackgroundColor(Color.rgb(255, 165, 0));
    }
    else
    {
        this.setBackgroundColor(Color.BLACK);
    }
    super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);  
}

你的自定义按钮在哪种容器中? - Phil
那里是否还有其他控件可能会捕获onFocusChanged事件呢? - Phil
在第一个LinearLayout中,我有一个包含自定义按钮的LinearLayout和一个包含按钮的FrameLayout。我将尝试删除该按钮。 - Cedekasme
所以我尝试删除FrameLayout中的按钮,但仍然无法正常工作... onFocusChanged()函数没有被调用。 - Cedekasme
1
事实上,问题在于我没有将自定义按钮的属性“可触摸模式下可聚焦”设置为true。我在构造函数中添加了setFocusableInTouchMode(true);,现在它运行得更好了。 感谢您的帮助。 - Cedekasme
显示剩余3条评论

0

你必须在构造函数中设置setOnFocusChangeListener,类似于这样:

 public CustomButton(Context context, Car car) 
{
    ...
    setOnFocusChangeListener(this);
    ...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接