在我的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编程的新手,我不知道如何做到这一点,而且我发现的现有代码似乎无法正常工作,所以我怎么能让它工作呢?
感谢。
答案 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中调用一次并将结果保存在变量中。不断调用它是低效的。