【问题标题】:OnLongClickListener in Button inside ListViewListView 内 Button 中的 OnLongClickListener
【发布时间】:2013-07-15 14:03:12
【问题描述】:

我遇到了问题,并且按钮的行为异常。实际上是数量字段的两个按钮加号(+)和减号(-)。

这些按钮在 ListView 中,我可以毫无问题地处理 OnClickListener,但是当我放置 OnLongClickListener 时...我在两个不同的 ListView 中遇到了两个问题:

1)所有信息和行为都正常,但是当我长按按钮时,我的自动增加/减少值的处理程序启动,但是,我认为,因为焦点他失去了控制,即使我释放按钮,处理程序不要停止。我在对话框中出于相同目的使用了相同的处理程序,并且工作正常。

2) 在另一个 ListView 中,当我放置 OnLongClickListener 时,一些字段(TextView、Spinner)停止工作。

这是我的 Handler,它是一个类 Repeater,在 OnTouchListener 和 OnLongClickListener 中实现:

public class Repeater implements OnTouchListener, OnLongClickListener{

    private View view; 

    private Repeater other_repeater;

    private int     REP_DELAY = 50; 
    private Handler repeatHandler = new Handler();

    private boolean mAutoRepeater = false;

    public Repeater(){}

    public Repeater(View view){
        this.setView(view);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if(( event.getAction() == MotionEvent.ACTION_UP         || 
             event.getAction() == MotionEvent.ACTION_CANCEL     ||
             event.getAction() == MotionEvent.ACTION_HOVER_EXIT ||
             event.getAction() == MotionEvent.ACTION_OUTSIDE)
           && mAutoRepeater ){
            mAutoRepeater = false;
        }
        return false;
    }

    @Override
    public boolean onLongClick(View v) {
        if(getOther_repeater() != null){
            getOther_repeater().stop();
        }
        mAutoRepeater = true;
        repeatHandler.post( new RptUpdater() );
        return false;
    }

    private class RptUpdater implements Runnable {
        public void run() {
            if( mAutoRepeater ){
                getView().performClick();
                repeatHandler.postDelayed( new RptUpdater(), REP_DELAY );
            }
        }
    }

    public void stop(){
        mAutoRepeater = false;
    }

    public void setView(View view) {
        this.view = view;
    }

    public View getView() {
        return view;
    }

    public void setOther_repeater(Repeater other_repeater) {
        this.other_repeater = other_repeater;
    }

    public Repeater getOther_repeater() {
        return other_repeater;
    }
}

每个 ListView 都有我的 CustomAdapter,有将近一千行...下面的代码是我设置中继器的地方:

            Repeater qt_produto_menos_repeater = new Repeater(viewHolder.qt_produto_menos);

            viewHolder.qt_produto_menos.setOnTouchListener    (qt_produto_menos_repeater);
            viewHolder.qt_produto_menos.setOnLongClickListener(qt_produto_menos_repeater);

            Repeater qt_produto_mais_repeater = new Repeater(viewHolder.qt_produto_mais);

            viewHolder.qt_produto_mais.setOnTouchListener    (qt_produto_mais_repeater);
            viewHolder.qt_produto_mais.setOnLongClickListener(qt_produto_mais_repeater);

            qt_produto_menos_repeater.setOther_repeater(qt_produto_mais_repeater);
            qt_produto_mais_repeater.setOther_repeater(qt_produto_menos_repeater);

这是我在 xml 中的 ListView:

    <ListView
            android:id="@+id/lv_resultado_produtos"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:divider="@color/Black"
            android:dividerHeight="1dip"
            android:fastScrollEnabled="true"
            android:scrollX="0dip"
            android:scrollY="0dip"
            android:scrollbarSize="22dip"
            android:scrollbarStyle="outsideOverlay" 
     />

我不知道为什么按钮的 OnClickListener 工作正常,而 OnLongClick 却不行。

请帮忙,我被困了好几天了。

[编辑]

LongClick 工作正常,但是当我释放按钮时,Repeater 无法获得“UP”/“CANCEL”动作。 OnTouchListener 需要知道停止 Handler,即使所有逻辑都在 CustomAdapter 中。而且这个是针对一个ListView,另外一个是让其他领域疯狂,但是如果我能解决“释放按钮”的问题,我会很高兴的!

[编辑2]

最后我隔离了这个问题。第二个ListView我解决了这个问题,我的Repeater在所有逻辑之后被调用,我不知道为什么,但这让列表变得疯狂!

第一个问题,我发现 notifyDataSetChanged() 搞砸了一切,当调用 notify...() 时按钮失去焦点,Repeater 从来没有得到停止增加/减少的“命令”,我部分解决了改变这个:

        if( mAutoRepeater ){
            getView().performClick();
            repeatHandler.postDelayed( new RptUpdater(), REP_DELAY );
        }

对此,在中继器中:

        if( view.isPressed() ){
            getView().performClick();
            repeatHandler.postDelayed( new RptUpdater(), REP_DELAY );
        }

所以,现在,当 notify...() 被调用时,他停止增加/减少,但这不是我们想要的行为。有人知道“延迟”通知吗?或者如果用户仍在按下按钮,请将焦点再次设置到按钮上(并保持按下状态)?

【问题讨论】:

    标签: android android-listview onlongclicklistener


    【解决方案1】:

    我在适配器的 getView() 中尝试了这个,它工作正常,没有任何列表视图和按钮功能的错误:

    testButton.setOnLongClickListener(new OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            Toast.makeText(context, "long click achieved", Toast.LENGTH_SHORT).show();
            testButton.setVisibility(View.INVISIBLE);
            return false;
        }
    });
    

    您可以尝试在 getView 中编写 onlongclick 功能,看看它是否可以这样工作?顺便说一句,我的测试按钮和列表 xml 文件上没有焦点说明:

    <Button
        android:id="@+id/test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />
    

    还有名单:

    <ListView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>
    

    【讨论】:

    • 感谢您的回答,但 LongClick 工作正常,但当我释放按钮时,Repeater 无法获得“UP”/“CANCEL”动作。 OnTouchListener 需要知道停止处理程序,即使所有逻辑都在 CustomAdapter 内:(
    • 然后我建议实现一个 GestureDetector 以便您可以正确获取触摸事件,例如; @Override public void onLongPress(MotionEvent e) { // 做某事 } public boolean onDown(MotionEvent e) { // 做某事 }
    猜你喜欢
    • 1970-01-01
    • 2013-01-20
    • 1970-01-01
    • 2019-08-12
    • 2011-06-05
    • 2011-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多