【问题标题】:I dont know why the performClick() method not called我不知道为什么没有调用 performClick() 方法
【发布时间】:2015-03-08 21:46:54
【问题描述】:

我正在编写一个实现 Checkable 接口的按钮。我重写了方法:performClick,但它没有被调用。根据文档中提到的:

从类中复制的描述:android.view.View 如果已定义,则调用此视图的 OnClickListener。执行与点击相关的所有正常操作:报告可访问性事件、播放声音等。

我认为当我点击屏幕上的按钮时系统应该会自动调用它。但什么也没发生。还是我必须自己调用?

我有以下代码:

public class MyButton extends Button implements Checkable {

private static final String TAG = "MyButton";
private boolean mChecked;
private boolean mBroadcasting;

private OnCheckedChangeListener mOnCheckedChangeListener;
private OnCheckedChangeListener mOnCheckedChangeWidgetListener;

private static final int[] CHECKED_STATE_SET = {
        android.R.attr.state_checked
};

public MyButton(Context context) {
    this(context, null);
}

public MyButton(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

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

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

    Log.i(TAG, "begin to paint lines");
    Paint paint = getPaint();

    paint.setColor(android.graphics.Color.BLACK);

    canvas.drawLine(0, 0, this.getWidth(), 0, paint);
    canvas.drawLine(0, 0, 0, this.getHeight(), paint);
    canvas.drawLine(this.getWidth(), 0, this.getWidth(), this.getHeight(), paint);
    canvas.drawLine(0, this.getHeight(), this.getWidth(), this.getHeight(), paint);
}

@Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
    super.onInitializeAccessibilityEvent(event);
    event.setClassName(MyButton.class.getName());
}

@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
    super.onInitializeAccessibilityNodeInfo(info);
    info.setClassName(MyButton.class.getName());
}



@Override
public boolean performClick() {
    toggle();
    Log.i(TAG, "the view was clicked");
    return super.performClick();
}

@Override
public void setChecked(boolean checked) {
    if (mChecked != checked) {
        mChecked = checked;
        refreshDrawableState();

        // Avoid infinite recursions if setChecked() is called from a listener
        if (mBroadcasting) {
            return;
        }

        mBroadcasting = true;
        if (mOnCheckedChangeListener != null) {
            mOnCheckedChangeListener.onCheckedChanged(this, mChecked);
        }
        if (mOnCheckedChangeWidgetListener != null) {
            mOnCheckedChangeWidgetListener.onCheckedChanged(this, mChecked);
        }

        mBroadcasting = false;
    }
}

@Override
public boolean isChecked() {
    return mChecked;
}

@Override
public void toggle() {
    setChecked(!mChecked);
    Log.i(TAG, "the view was toggled");
}

@Override
protected int[] onCreateDrawableState(int extraSpace) {
    int[] drawableState = super.onCreateDrawableState(extraSpace);

    if (isChecked()) {
        mergeDrawableStates(drawableState, CHECKED_STATE_SET);
    }
    return drawableState;
}

public OnCheckedChangeListener getOnCheckedChangeListener() {
    return mOnCheckedChangeListener;
}

public void setOnCheckedChangeListener(OnCheckedChangeListener mOnCheckedChangeListener) {
    this.mOnCheckedChangeListener = mOnCheckedChangeListener;
}

public OnCheckedChangeListener getOnCheckedChangeWidgetListener() {
    return mOnCheckedChangeWidgetListener;
}

public void setOnCheckedChangeWidgetListener(OnCheckedChangeListener mOnCheckedChangeWidgetListener) {
    this.mOnCheckedChangeWidgetListener = mOnCheckedChangeWidgetListener;
}

/**
 * Interface definition for a callback to be invoked when the checked state
 * of a compound button changed.
 */
public static interface OnCheckedChangeListener {
    /**
     * Called when the checked state of a compound button has changed.
     *
     * @param buttonView The compound button view whose state has changed.
     * @param isChecked  The new checked state of buttonView.
     */
    void onCheckedChanged(MyButton buttonView, boolean isChecked);
}

}

布局中的MyButton:

<com.example.demo.view.MyButton
    android:id="@+id/mybtn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/checkable_button"
    android:textColor="@drawable/button_text"
    android:text="checkable" />

先谢谢你了。

第一个答案是正确的。

解释:

public MyButton(Context context, AttributeSet attrs) 这个是 叫。然后它调用 MyButton(context, attrs, 0)。这是哪里 defStyleAttr 被设置为 0,而默认情况下它将是 com.android.internal.R.attr.buttonStyle.

【问题讨论】:

    标签: android view


    【解决方案1】:

    你需要使用正确的构造函数:

    public MyButton(Context context) {
        super(context);
    }
    
    public MyButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    
    public MyButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public MyButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }
    

    编辑:

    这些是来自Button 类的构造函数:

    public Button(Context context) {
        this(context, null);
    }
    
    public Button(Context context, AttributeSet attrs) {
        this(context, attrs, com.android.internal.R.attr.buttonStyle);
    }
    
    public Button(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }
    
    public Button(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }
    

    看看你能不能找到这些和你的构造函数之间的区别。

    【讨论】:

    • 嘿,它确实有效。但为什么?我的构造函数没有发现任何问题。我认为使用 this() 最终会使用 super()。
    • @evolever 确实如此,但它使用不正确的参数调用超级构造函数。
    • 为此调用了哪个构造函数?
    • @evolever 我已经添加了Button类构造函数的代码,看看你是否可以通过不调用超级构造函数找到你所犯的错误。
    • 嗨,我在问题中添加了布局。你能解释一下调用的是哪个构造函数吗?
    猜你喜欢
    • 1970-01-01
    • 2022-08-21
    • 1970-01-01
    • 2015-08-01
    • 1970-01-01
    • 2021-09-24
    • 2010-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多