2

我有一个切换按钮,当我按下它时应该运行代码,当我松开它时应该运行更多代码。然而,我第一次按下并放手时没有任何反应。每次都很好,这是为什么呢?我可以看到该方法仅在我松开按钮时第一次运行(尽管它不会触发该方法的任何 onTouch 部分),我怎样才能解决这个问题,并让它在第一次按下时工作?

public void pushtotalk3(final View view) {
    ((ToggleButton) view).setChecked(true);
    ((ToggleButton) view).setChecked(false);
    view.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            //if more than one call, change this code
            int callId = 0;
            for (SipCallSession callInfo : callsInfo) {
                callId = callInfo.getCallId();
                Log.e(TAG, "" + callInfo.getCallId());
            }
            final int id = callId;
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN: {  //press
                    ((ToggleButton) view).setBackgroundResource(R.drawable.btn_blue_glossy);
                    ((ToggleButton) view).setChecked(true);
                    OnDtmf(id, 17, 10);
                    OnDtmf(id, 16, 9);
                    return true;
                }
                case MotionEvent.ACTION_UP: { //release
                    ((ToggleButton) view).setBackgroundResource(R.drawable.btn_lightblue_glossy);
                    ((ToggleButton) view).setChecked(false);
                    OnDtmf(id, 18, 11);
                    OnDtmf(id, 18, 11);
                    return true;
                }
                default: return false;
            }
        }
    });
}

编辑:按钮的xml:

<ToggleButton
        android:id="@+id/PTT_button5"
        android:layout_width="0dp"
        android:layout_height="fill_parent"
        android:text="@string/ptt5" 
        android:onClick="pushtotalk5"
        android:layout_weight="50"
        android:textOn="Push To Talk On"
        android:textOff="Push To Talk Off"
        android:background="@drawable/btn_lightblue_glossy"
        android:textColor="@android:color/white"
        android:textSize="15sp"
        />      

编辑:硬件问题,无法测试解决方案 atm。

4

6 回答 6

2

另一种方法是使用手势检测器,而不是onTouch

private class CustomGestureListener extends GestureDetector.SimpleOnGestureListener {
    private boolean down = false;

    @Override   
    public void onShowPress(MotionEvent e) {
        down = true;
        doDownActions();
    }

    public boolean onSingleTapUp(MotionEvent e) {
        if (down) {
            down = false;
            doUpActions();
        }

        // The gesture has been used so return true. If you wish to pretend it hasn't
        // return false
        return true;
    }

    // Strictly you may also need to catch some of the other events to
    // guarantee correct termination of the sequence
}

然后,需要创建此侦听器并将其添加到视图中:

// Create it.
final GestureDetector myGestureListener = new GestureDetector(getApplicationContext(), new CustomGestureListener());

// Set it up for use:
view.setOnTouchListener(new OnTouchListener() {
    public boolean onTouch(View v, MotionEvent event) {
        myGestureListener.onTouchEvent(event);
        // Pass it on to the system. Be cleverer about this if needed!
        return super.onTouchEvent(event);
    }
});

// And put an onClick method it to force it to work (this shouldn't be necessary but
// it seems like sometimes it is)
view.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
    }
});
于 2013-11-03T20:32:31.763 回答
2

您的in_call_card.xml包含ToggleButton. 根据源代码的链接,in_call_card.xmlInCallCard.java. InCallCard是应用程序定义的自定义视图。

为了附加侦听器,您需要InCallCard查看InCallActivity. 您可以在getView方法中找到它(接近文件末尾)。

根据以上观察,您的问题可以通过以下方式解决:

1)在InCallCard视图中找到按钮

2)以编程方式附加,OnTouchListener如下所示:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if(convertView == null) {
        convertView = new InCallCard(InCallActivity.this, null);
    }

    if(convertView instanceof InCallCard) {
        InCallCard vc = (InCallCard) convertView;
        vc.setOnTriggerListener(InCallActivity.this);

        // set the touch listener here.. 
        // (1) get the button within the InCallCard view (vc)
        // (2) set the onTouchListener
        final View view = vc.findViewById(R.id.PTT_button5);
        view.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                //if more than one call, change this code
                int callId = 0;
                for (SipCallSession callInfo : callsInfo) {
                    callId = callInfo.getCallId();
                    Log.e(TAG, "" + callInfo.getCallId());
                }
                final int id = callId;
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN: {  //press
                        ((ToggleButton) view).setBackgroundResource(R.drawable.btn_blue_glossy);
                        ((ToggleButton) view).setChecked(true);
                        OnDtmf(id, 17, 10);
                        OnDtmf(id, 16, 9);
                        return true;
                    }
                    case MotionEvent.ACTION_UP: { //release
                        ((ToggleButton) view).setBackgroundResource(R.drawable.btn_lightblue_glossy);
                        ((ToggleButton) view).setChecked(false);
                        OnDtmf(id, 18, 11);
                        OnDtmf(id, 18, 11);
                        return true;
                    }
                    default: return false;
                }
            }
        });

        SipCallSession session = (SipCallSession) getItem(position);
        vc.setCallState(session);
    }

    return convertView;
}

注意:这不是最有效的做事方式(就像我们做的那样findViewById),但肯定会解决您的问题。如果您想改进,请阅读ViewHolderandroid 中的模式并在此处使用它。

此外,您应该src早先发布代码链接。这里的每个人都给出了正确的答案,但没有人确定你的具体情况是什么。

于 2013-11-05T02:30:55.527 回答
1

如果您使用布局,获取切换按钮会更好。至少对我来说更容易

LayoutInflater inflater = getLayoutInflater();
View otherLayout = inflator.inflate(R.layout.toggle_layout, null);
ToggleButton toggle = (ToggleButton) otherLayout.findViewById(R.id.toggleID);
toggle.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
           switch(event.getAction()) {
             case MotionEvent.ACTION_DOWN:
                 //your code
                 break;
             case MotionEvent.ACTION_UP:
                 // your code
                 break;
           }
           return false;
    }
});

试试看,让我知道。我对按钮也有同样的想法,但我使用 onClick 而不是 onTouch。

于 2013-10-25T14:17:46.347 回答
1

发生这种情况是因为您在单击按钮时看到了listner,因此您必须在onCreate 中设置listner,只需将下面的代码替换为您的。

public void OnCreate(Bundle savedInstanceState)
{
          //setContetView
          //other intlization goes here

          view.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                //if more than one call, change this code
                int callId = 0;
                for (SipCallSession callInfo : callsInfo) {
                    callId = callInfo.getCallId();
                    Log.e(TAG, "" + callInfo.getCallId());
                }
                final int id = callId;
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN: {  //press
                        ((ToggleButton) view).setBackgroundResource(R.drawable.btn_blue_glossy);
                        ((ToggleButton) view).setChecked(true);
                        OnDtmf(id, 17, 10);
                        OnDtmf(id, 16, 9);
                        return true;
                    }
                    case MotionEvent.ACTION_UP: { //release
                        ((ToggleButton) view).setBackgroundResource(R.drawable.btn_lightblue_glossy);
                        ((ToggleButton) view).setChecked(false);
                        OnDtmf(id, 18, 11);
                        OnDtmf(id, 18, 11);
                        return true;
                    }
                    default: return false;
                }
            }
        });

}




public void pushtotalk3(final View view) {
        ((ToggleButton) view).setChecked(true);
        ((ToggleButton) view).setChecked(false);


}
于 2013-11-03T08:18:53.283 回答
1

我喜欢beworker的回答,但如果你不能。

您的活动类可以实现 OnTouchListener 并进入方法 onTouch() ,如果视图正确则处理事件,否则不处理事件。

pushtotalk3() 方法可以为空。

例子

class MyActivity implements OnTouchListener{
    // code ..
 @Override
    public boolean onTouch(View v, MotionEvent event) {
        if(v.getId() != R.id.PTT_button5)
                return false;

        //if more than one call, change this code
        int callId = 0;
        for (SipCallSession callInfo : callsInfo) {
            callId = callInfo.getCallId();
            Log.e(TAG, "" + callInfo.getCallId());
        }
        final int id = callId;
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN: {  //press
                ((ToggleButton) view).setBackgroundResource(R.drawable.btn_blue_glossy);
                ((ToggleButton) view).setChecked(true);
                OnDtmf(id, 17, 10);
                OnDtmf(id, 16, 9);
                return true;
            }
            case MotionEvent.ACTION_UP: { //release
                ((ToggleButton) view).setBackgroundResource(R.drawable.btn_lightblue_glossy);
                ((ToggleButton) view).setChecked(false);
                OnDtmf(id, 18, 11);
                OnDtmf(id, 18, 11);
                return true;
            }
            default: return false;
        }
    }

    public void pushtotalk3(final View view) {}

}

现在设置监听器。有两种情况。

案例布局膨胀:

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.mylayout);
}

@Override
public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
    if(parent!=null)
        parent.setOnTouchListener(this);        
    return super.onCreateView(parent, name, context, attrs);
}

以编程方式创建的案例视图

    protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    View myView = new MyView();

    setContentView(myView);
            myView.setOnTouchListener(this);

}
于 2013-11-04T21:50:19.353 回答
1

我只是大大改变了你的逻辑,它对我很有效。你可以把你的电话相关的东西放回去测试。而且您不需要 onClick 侦听器,因为 onTouch 侦听器完全取代了它。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test_touch);

    final View view = findViewById(R.id.PTT_button5);
    view.setOnTouchListener(new OnTouchListener() {
        @Override public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN: {  //press
                    System.out.println("talk");
                    ((ToggleButton) view).setChecked(true);
                    return true;
                }
                case MotionEvent.ACTION_UP: { //release
                    System.out.println("don't talk");
                    ((ToggleButton) view).setChecked(false);
                    return true;
                }
                default: return false;
            }
        }
    });
}
于 2013-11-02T08:59:08.663 回答