Android的 - HOLD键,重复动作动作、Android、HOLD

2023-09-12 03:01:52 作者:红尘如梦丶梦如烟

早上,所有的,

我承认直客,我是新来的发展,并试图在我的手的Andr​​oid。我一直在试图通过'网找到如何实现一些保持按钮,重复动作的建议 - 我创建从按键的自定义小键盘,想退格键类似的行为。已经走到这一步,我呼吁朋友谁之前处理不当codeD Android的,但是做了很多的C#/ Java的,似乎知道自己在做什么。

在code以下工作得很好,但我觉得它可以更巧妙地完成。我很抱歉,如果我错过了位了,但我希望这说明我的做法。我认为onTouchListener是好的,但在线程的处理方式犯规觉得不对劲。

有没有更好的或者更简单的方式来做到这一点?

谢谢

M

 公共类MyApp的延伸活动{

私人布尔deleteThreadRunning = FALSE;
私人布尔cancelDeleteThread = FALSE;
私人处理程序处理程序=新的处理程序();

公共无效的onCreate(包冰柱){
    super.onCreate(冰柱);

    //可以在这里错过了一些声明...

    Button_Del.setOnTouchListener(新OnTouchListener(){
        公共布尔onTouch(视图V,MotionEvent事件){

           开关(event.getAction())
           {
               案例MotionEvent.ACTION_DOWN:
               {
                   handleDeleteDown();
                   返回true;
               }

               案例MotionEvent.ACTION_UP:
               {
                   handleDeleteUp();
                   返回true;
               }

               默认:
                   返回false;
           }
        }

        私人无效handleDeleteDown(){

            如果(!deleteThreadRunning)
                startDeleteThread();
        }

        私人无效startDeleteThread(){

            螺纹R =新的Thread(){

                @覆盖
                公共无效的run(){
                    尝试 {

                        deleteThreadRunning = TRUE;
                        而(!cancelDeleteThread){

                            handler.post(新的Runnable(){
                                @覆盖
                                公共无效的run(){
                                    deleteOneChar();
                                }
                            });

                            尝试 {
                                视频下载(100);
                            }赶上(InterruptedException异常E){
                                抛出新的RuntimeException(
                                    难道不是char之间等待删除,E);
                            }
                        }
                    }
                    最后
                    {
                        deleteThreadRunning = FALSE;
                        cancelDeleteThread = FALSE;
                    }
                }
            };

            //真正开始删除字符线
            r.start();
        }
    });
}

私人无效handleDeleteUp(){
    cancelDeleteThread = TRUE;
}

私人无效deleteOneChar()
{
    字符串结果= getNumberInput()的getText()的toString()。
    INT长度= result.length();

    如果(长度大于0)
        。getNumberInput()的setText(result.substring(0,长度-1));
        //我不粘贴getNumberInput(),但它得到我想删除字符字符串
}
 

解决方案 PS批处理动作怎么设置

这是比较独立的实现,与任何浏览使用,支持触摸事件

 进口android.os.Handler;
进口android.view.MotionEvent;
进口android.view.View;
进口android.view.View.OnClickListener;
进口android.view.View.OnTouchListener;

/ **
 * A类,可用于为任何视图(如一个按钮)一个TouchListener。
 *它循环运行clickListener,模拟键盘类似的行为。第一
 *点击立即解雇,在initialInterval后下一个,随后
 *在normalInterval后的。
 *
 *< P>间隔定onClick的完成之后,所以它必须跑得快。
 *如果它运行速度慢,它不产生跳过onClicks。可改写到
 *实现这一目标。
 * /
公共类RepeatListener实现OnTouchListener {

    私人处理程序处理程序=新的处理程序();

    私人诠释initialInterval;
    私人最终诠释normalInterval;
    私人最终OnClickListener clickListener;

    私人可运行handlerRunnable =新的Runnable(){
        @覆盖
        公共无效的run(){
            handler.postDelayed(这一点,normalInterval);
            clickListener.onClick(downView);
        }
    };

    私人查看downView;

    / **
     *参数initialInterval首先点击事件发生后的时间间隔
     *参数normalInterval后,第二次及以后点击间隔
     *活动
     *参数clickListener的OnClickListener,将调用
     *定期
     * /
    公共RepeatListener(INT initialInterval,INT normalInterval,
            OnClickListener clickListener){
        如果(clickListener == NULL)
            抛出新抛出:IllegalArgumentException(空可运行);
        如果(initialInterval℃,|| normalInterval℃下)
            抛出新抛出:IllegalArgumentException(负区间);

        this.initialInterval = initialInterval;
        this.normalInterval = normalInterval;
        this.clickListener = clickListener;
    }

    公共布尔onTouch(查看视图,MotionEvent motionEvent){
        开关(motionEvent.getAction()){
        案例MotionEvent.ACTION_DOWN:
            handler.removeCallbacks(handlerRunnable);
            handler.postDelayed(handlerRunnable,initialInterval);
            downView =图。
            downView.set pressed(真正的);
            clickListener.onClick(视图);
            返回true;
        案例MotionEvent.ACTION_UP:
        案例MotionEvent.ACTION_CANCEL:
            handler.removeCallbacks(handlerRunnable);
            downView.set pressed(假);
            downView = NULL;
            返回true;
        }

        返回false;
    }

}
 

用法:

 按钮按钮=新按钮(上下文);
button.setOnTouchListener(新RepeatListener(400,100,新OnClickListener(){
  @覆盖
  公共无效的onClick(视图查看){
    //在code反复执行
  }
}));
 

Morning all,

I'll admit straight off that I'm new to development and trying my hand at Android. I've been trying to search the 'net to find advice on how to implement some "Hold Button to Repeat Action" - I've created a custom numpad from buttons and want a backspace-like behaviour. Having got so far, I called upon a friend who hasnt coded Android before, but done lots of C# / Java and seems to know what he's doing.

The code below works just fine, but I feel it could be done more neatly. I apologise if I've missed bits out, but hopefully this explains my approach. I think the onTouchListener is ok, but the way Threads are handled doesnt feel right.

Is there a better or more simple way to do this?

Thanks,

M

public class MyApp extends Activity {

private boolean deleteThreadRunning = false;
private boolean cancelDeleteThread = false;
private Handler handler = new Handler();

public void onCreate(Bundle icicle) {
    super.onCreate(icicle);

    //May have missed some declarations here...

    Button_Del.setOnTouchListener(new OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {

           switch (event.getAction())
           {
               case MotionEvent.ACTION_DOWN:
               {
                   handleDeleteDown();
                   return true;
               }

               case MotionEvent.ACTION_UP:
               {
                   handleDeleteUp();
                   return true;
               }

               default:
                   return false;
           }
        }

        private void handleDeleteDown() {

            if (!deleteThreadRunning)
                startDeleteThread();
        }

        private void startDeleteThread() {

            Thread r = new Thread() {

                @Override
                public void run() {
                    try {

                        deleteThreadRunning = true;
                        while (!cancelDeleteThread) {

                            handler.post(new Runnable() {   
                                @Override
                                public void run() {
                                    deleteOneChar();
                                }
                            });

                            try {
                                Thread.sleep(100);
                            } catch (InterruptedException e) {
                                throw new RuntimeException(
                                    "Could not wait between char delete.", e);
                            }
                        }
                    }
                    finally
                    {
                        deleteThreadRunning = false;
                        cancelDeleteThread = false;
                    }
                }
            };

            // actually start the delete char thread
            r.start();
        }
    });
}

private void handleDeleteUp() {
    cancelDeleteThread = true;
}

private void deleteOneChar()
{
    String result = getNumberInput().getText().toString();
    int Length = result.length();

    if (Length > 0)
        getNumberInput().setText(result.substring(0, Length-1));
        //I've not pasted getNumberInput(), but it gets the string I wish to delete chars from
}

解决方案

This is more independent implementation, usable with any View, that supports touch event

import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;

/**
 * A class, that can be used as a TouchListener on any view (e.g. a Button).
 * It cyclically runs a clickListener, emulating keyboard-like behaviour. First
 * click is fired immediately, next one after the initialInterval, and subsequent
 * ones after the normalInterval.
 *
 * <p>Interval is scheduled after the onClick completes, so it has to run fast.
 * If it runs slow, it does not generate skipped onClicks. Can be rewritten to
 * achieve this.
 */
public class RepeatListener implements OnTouchListener {

    private Handler handler = new Handler();

    private int initialInterval;
    private final int normalInterval;
    private final OnClickListener clickListener;

    private Runnable handlerRunnable = new Runnable() {
        @Override
        public void run() {
            handler.postDelayed(this, normalInterval);
            clickListener.onClick(downView);
        }
    };

    private View downView;

    /**
     * @param initialInterval The interval after first click event
     * @param normalInterval The interval after second and subsequent click 
     *       events
     * @param clickListener The OnClickListener, that will be called
     *       periodically
     */
    public RepeatListener(int initialInterval, int normalInterval, 
            OnClickListener clickListener) {
        if (clickListener == null)
            throw new IllegalArgumentException("null runnable");
        if (initialInterval < 0 || normalInterval < 0)
            throw new IllegalArgumentException("negative interval");

        this.initialInterval = initialInterval;
        this.normalInterval = normalInterval;
        this.clickListener = clickListener;
    }

    public boolean onTouch(View view, MotionEvent motionEvent) {
        switch (motionEvent.getAction()) {
        case MotionEvent.ACTION_DOWN:
            handler.removeCallbacks(handlerRunnable);
            handler.postDelayed(handlerRunnable, initialInterval);
            downView = view;
            downView.setPressed(true);
            clickListener.onClick(view);
            return true;
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_CANCEL:
            handler.removeCallbacks(handlerRunnable);
            downView.setPressed(false);
            downView = null;
            return true;
        }

        return false;
    }

}

Usage:

Button button = new Button(context);
button.setOnTouchListener(new RepeatListener(400, 100, new OnClickListener() {
  @Override
  public void onClick(View view) {
    // the code to execute repeatedly
  }
}));