【问题标题】:Button subclass onClick not responding按钮子类 onClick 没有响应
【发布时间】:2015-02-02 08:52:16
【问题描述】:

我正在尝试创建 Button 的子类。代码如下

package com.comnet.bookshelf;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.Button;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;

public class myButton extends Button implements OnClickListener{
    Paint mainPaint;
    int colorArray[];
    int colorArrayAlt[];
    boolean touch=false;
    Rect bound;
    public myButton(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
        mainPaint=new Paint();
        bound=new Rect();
        defaultColorIndexArray();
    }

    public myButton(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        mainPaint=new Paint();
        bound=new Rect();
        defaultColorIndexArray();
    }

    public myButton(Context context)
    {
        super(context);
        mainPaint=new Paint();
        bound=new Rect();
        defaultColorIndexArray();
    }
    private void defaultColorIndexArray(){
        colorArray=new int[]{
        0xFFd28181, //1
        0xFFd48787,     //2
        0xFFd68d8d, //3
        0xFFd89292, //4
        0xFFda9898, //5
        0xFFdc9e9e, //6
        0XFFdea2a2, //7
        0XFFe0a8a8,     //8
        0xFFe2adad, //9
        0XFFe3b1b1, //10
        0XFFe4b4b4, //11
        0XFFe6b9b9, //12
        0XFFe7bdbd, //13
        0XFFe9c0c0, //14
        0XFFeac3c3, //15
        0XFFebc6c6, //16
        0XFFebc7c7, //17
        0XFFecc9c9, //18
        0XFFeccaca, //19
        0XFFeccaca,     //20
        0XFFeccbcb, //21
        0XFFeccbcb      //22
        };
        colorArrayAlt=new int[]{
        0XFFeccbcb, //22
        0XFFeccbcb, //21
        0XFFeccaca, //20
        0XFFeccaca, //19
        0XFFecc9c9, //18
        0XFFebc7c7, //17
        0XFFebc6c6, //16
        0XFFeac3c3, //15
        0XFFe9c0c0, //14
        0XFFe7bdbd, //13
        0XFFe6b9b9, //12
        0XFFe4b4b4, //11
        0XFFe3b1b1, //10
        0xFFe2adad, //9
        0XFFe0a8a8, //8
        0XFFdea2a2, //7
        0xFFdc9e9e, //6
        0xFFda9898, //5
        0xFFd89292, //4
        0xFFd68d8d, //3
        0xFFd48787, //2
        0xFFd28181  //1
        };
    }
    public void setButtonColorIndexArray(int carray[], int carray_alt[]){
    }
    @Override 
    protected void onDraw(Canvas canvasObject) {
        super.onDraw(canvasObject);
        int draw_color[];
        if(touch==false)
        draw_color=colorArray;
        else
        draw_color=colorArrayAlt;
        int width=canvasObject.getWidth();
        int height=canvasObject.getHeight();
        double colorcount=44;
        double divheight=height;
        double f=colorcount/divheight;

        double step=0;
        for(int i=0;i<height;i++,step+=f){
        int next=(int) Math.round(step);
        if(next>43) next=43;
        else if(next<0)next=0;
        if(next<22){
        mainPaint.setColor(draw_color[next]);
        canvasObject.drawLine(0, i, width, i, mainPaint);
        }
        else{
        mainPaint.setColor(draw_color[43-next]);
        canvasObject.drawLine(0, i, width, i, mainPaint);
        }
        //int color=;
        mainPaint.setColor(getCurrentTextColor());

        String str=this.getText().toString();
        //mainPaint.setColor(Color.WHITE); 
        mainPaint.setStyle(Style.FILL); 
        //canvasObject.drawPaint(mainPaint); 

        mainPaint.setColor(Color.BLACK); 
        mainPaint.setTextSize(20); 
        mainPaint.getTextBounds(str, 0, str.length(), bound);
        int x=(width-(bound.right-bound.left))/2;
        int y=(height+(bound.bottom-bound.top))/2;

        canvasObject.drawText(str, x, y, mainPaint);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev){
        if(ev.getAction()==MotionEvent.ACTION_DOWN){
        //Log.i("Click", "ACTION_DOWN");
        touch=true;
        this.invalidate();
        }
        else if(ev.getAction()==MotionEvent.ACTION_UP){
        touch=false;
        this.invalidate();
        }

        return true;
    }

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        Log.i("Clicked", "Clicked");
    }
}

除了一个之外的所有东西都按我的预期工作。

onClick 根本没有响应。代码如下:

((myButton)inflatedLayout.findViewById(R.id.DeleteButton)).setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        DeleteTheEntireBook();
    }
}); 

默认类的按钮工作正常

如果您还有任何问题,请告诉我。

【问题讨论】:

  • 哪个 Onclick 没有被调用?一种是在子类中实现的还是一种用于删除书的?
  • @KarnShah 他们都不是,我添加的第二个是为了测试行为。
  • 问题是你已经覆盖了onTouchEvent。评论它。您将能够被 onClick 解雇
  • Touch事件的目的是什么?
  • 如果你想同时处理这两个,从触摸返回 FALSE 然后只有 Click 事件会被触发。 如果你为touchevent返回true,ClickListener永远不会得到它

标签: java android


【解决方案1】:

问题是你已经覆盖了 onTouchEvent。

标记这些词:

您应该在 OnTouchListener 中返回 false,然后您的 OnClickListener 也会被处理。

所以你可能会想,我会在那里做我的事情并返回 false,这样我也可以获得点击。如果你这样做,它会起作用,但你不会订阅其他即将到来的触摸事件(ACTION_MOVE,ACTION_UP)因此唯一的选择是在那里返回true,但是你不会收到我们之前所说的任何点击事件。

所以你需要使用 performClick() 在 ACTION_UP 中手动执行点击

经过测试和工作的代码:

@Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            // Log.i("Click", "ACTION_DOWN");
            touch = true;
            this.invalidate();

        } else if (ev.getAction() == MotionEvent.ACTION_UP) {
            touch = false;
            this.invalidate();
            // KEY LINE
            performClick();
        }
        return true;


    }

希望对你有所帮助ツ

【讨论】:

  • 您好ツ。谢谢您的回复。你的建议奏效了。你问了一个关于处理 onTouchEvent 的原因的问题。好吧,我已经处理了它,因为我想改变触摸按钮的外观。这是迄今为止我找到的最好的方法。如果你知道更好的方法,你能建议我吗!谢谢。
  • Yaa.. 你可以使用 selector fr that 。这是一个简单的方法 :) 你只需要将你的 java 代码转换为 XML,虽然这可能很困难 :) 然后你不需要 onDraw 和 onTouch
  • @SweetWisherツ 好吧,这只是我想要完成的一些工作的开始:)。这是我学习的一部分。
【解决方案2】:

在构造函数中,添加onClickListener, 也不需要((myButton)inflatedLayout.findViewB...

public myButton(Context context, AttributeSet attrs, int defStyle)
{
    super(context, attrs, defStyle);
    mainPaint=new Paint();
    bound=new Rect();
    defaultColorIndexArray();
    setOnClickListener(this);
}

那么一旦单击按钮,就应该调用myButton 类中被覆盖的onClick

【讨论】:

  • 您好,我已经尝试了您的建议。但是,它没有帮助。感谢您抽出宝贵时间。
【解决方案3】:

View.OnClickListener :单击视图时要调用的回调的接口定义。 你能用这个代码吗:

((myButton)inflatedLayout.findViewById(R.id.DeleteButton)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
    DeleteTheEntireBook();
}

});

【讨论】:

  • 你好,Rajapandiyan JJ,这正是我所做的。我已经导入了 View.OnCickListener,这就是我没有编写 View.OnclickListener 的原因。但感谢您抽出宝贵时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-24
  • 2017-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-17
相关资源
最近更新 更多