Android - 按钮保持重复功能

时间:2016-12-31 06:48:03

标签: java android button

在我的Android项目中,我试图重复此代码(我的MainActivity.class文件中的一个函数):

public void positionChange(View v)
{
    findViewById(R.id.player1).setX(findViewById(R.id.player1).getX() - 30);
    findViewById(R.id.player2).setX(findViewById(R.id.player2).getX() + 30);

}

按住按钮时。

目前,当按下按钮时,每次点击都会调用此代码:

android:onClick="positionChange"

在我的activity_main.xml文件中。由于我是Android编程的新手,我不知道如何做到这一点,而且我发现的现有代码似乎无法正常工作,所以我怎么能让它工作呢?

感谢。

2 个答案:

答案 0 :(得分:1)

首先,你必须知道每次调用findViewById()都会浪费你的应用程序的大部分时间,所以你最好多次使用它们并多次使用它们。

要在按钮按住时重复此代码,您必须使用以下链接并使用此链接提供的自定义侦听器:

Android - Hold Button to Repeat Action

我为了您的方便而复制代码:

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;
}

}

然后在onCreate()中使用它,如下所示:

View player1 =  findViewById(R.id.player1);
View player2 =  findViewById(R.id.player2);
button.setOnTouchListener(new RepeatListener(400, 100, new OnClickListener() {
@Override
public void onClick(View view) {
  // the code to execute repeatedly
  player1.setX(player1.getX() - 30);
  player2.setX(player2.getX() + 30);
}
}));

为了获得更好的代码,您可以将player1和player2定义为public(在onCreate之外),然后在onCreate()中启动它们

答案 1 :(得分:0)

你实际上并不想经常重复这样做 - 这样做会每秒发生数千次。你想要做的是在触摸按钮时设置一个计时器。当计时器触发时,调用该功能,然后设置另一个计时器。释放按钮后,取消定时器。要告诉按下/释放按钮的时间,请在其上设置OnTouchEvent侦听器,并响应TOUCH_DOWN和TOUCH_UP事件。

哦,只是fyi-你不应该这样调用findViewById。在onCreate中调用一次并将结果保存在变量中。不断调用它是低效的。