我是Android新手,很抱歉,这个问题很容易回答。我有两个按钮,一个减少按钮和一个增加按钮,在它们中间是一个显示值的TextView。
当我点击减少按钮时,TextView中的值减小并且当我按下增加按钮时增加,没有问题,我得到了它的工作,但问题是只需单击一下,值就会增加/减少1 。我想要实现的是,当我连续按下按钮(例如增加按钮)时,该值也会不断增加,并且只有在我释放增加按钮时才会停止。
这可能吗?如果是这样,您能否展示一些示例代码或如何实现它的参考?谢谢!
这是我的main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="44dp"
android:gravity="center_horizontal" >
<Button android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="<" />
<TextView android:id="@+id/textView1"
android:layout_width="50dp"
android:layout_height="fill_parent"
android:layout_alignBottom="@+id/button1"
android:layout_toRightOf="@+id/button1"
android:gravity="center"
android:text="45" />
<Button android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toRightOf="@+id/textView1"
android:text=">" />
</RelativeLayout>
</RelativeLayout>
这是我的Main.java
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class Main extends Activity {
private Button _decrease;
private Button _increase;
private TextView _value;
private static int _counter = 45;
private String _stringVal;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
_decrease = (Button) findViewById(R.id.button1);
_increase = (Button) findViewById(R.id.button2);
_value = (TextView) findViewById(R.id.textView1);
_decrease.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Log.d("src", "Decreasing value...");
_counter--;
_stringVal = Integer.toString(_counter);
_value.setText(_stringVal);
}
});
_increase.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Log.d("src", "Increasing value...");
_counter++;
_stringVal = Integer.toString(_counter);
_value.setText(_stringVal);
}
});
}
}
答案 0 :(得分:76)
要使其正常工作,您需要一个线程,当您长按按钮时,该线程将更新整数值。
在您的活动中创建一个处理程序:
private Handler repeatUpdateHandler = new Handler();
和2个将说明的变量:是增量还是减量?一次只能设置一个。
private boolean mAutoIncrement = false;
private boolean mAutoDecrement = false;
目前的数值
public int mValue;
一个将在另一个线程中运行的类:
class RptUpdater implements Runnable {
public void run() {
if( mAutoIncrement ){
increment();
repeatUpdateHandler.postDelayed( new RptUpdater(), REP_DELAY );
} else if( mAutoDecrement ){
decrement();
repeatUpdateHandler.postDelayed( new RptUpdater(), REP_DELAY );
}
}
}
为按钮添加长按监听器:
mBTIncrement.setOnLongClickListener(
new View.OnLongClickListener(){
public boolean onLongClick(View arg0) {
mAutoIncrement = true;
repeatUpdateHandler.post( new RptUpdater() );
return false;
}
}
);
mBTIncrement.setOnTouchListener( new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if( (event.getAction()==MotionEvent.ACTION_UP || event.getAction()==MotionEvent.ACTION_CANCEL)
&& mAutoIncrement ){
mAutoIncrement = false;
}
return false;
}
});
在上面的例子中,按钮是增量按钮。创建另一个按钮,将mAutoDecrement设置为true。
而decrement()将是一个函数,它会将你的实例设置为int变量:
public void decrement(){
mValue--;
_value.setText( ""+mValue );
}
你想出了增量。哦,REP_DELAY是一个设置为50的静态int变量。
我看到这是Jeffrey Cole在http://www.technologichron.net/提供的开源NumberPicker的摘录。必须添加正确作者的归属。
答案 1 :(得分:4)
我在长按时增加值的方法是使用Timer来定期检查按钮是否仍按下而不是增加值,否则取消定时器。要更新UI,请使用Handler。
vh.bttAdd.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
if(vh.bttAdd.isPressed()) {
final int track = ((ChannelAudioTrack) channels.get(vh.getAdapterPosition())).goToNextTrack();
updateUI(vh,track);
}
else
timer.cancel();
}
},100,200);
return true;
}
});
处理程序:
private void updateUI(final TrackViewHolder vh, final int track)
{
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
vh.tvTrackNumber.setText(Integer.toString(track));
}
}) ;
}
答案 2 :(得分:3)
我迟到了回答这个问题,但它可以帮助任何寻求更好答案的人。
我创建了一个CounterHandler
类,它非常容易使用,以实现上述连续计数器功能。
您可以使用&#34;如何使用&#34;在以下要点中找到该课程。例。 https://gist.github.com/nomanr/d142f4ccaf55ceba22e7f7122b55b9b6
示例代码
new CounterHandler.Builder()
.incrementalView(buttonPlus)
.decrementalView(buttonMinus)
.minRange(-50) // cant go any less than -50
.maxRange(50) // cant go any further than 50
.isCycle(true) // 49,50,-50,-49 and so on
.counterDelay(200) // speed of counter
.counterStep(2) // steps e.g. 0,2,4,6...
.listener(this) // to listen counter results and show them in app
.build();
多数民众赞成。 :)
答案 3 :(得分:1)
似乎没有一个完美的解决方案,总会涉及一些复杂性。
这是我的尝试,它结合了Wiktor的答案,但提供了一个完整的MainActivity,您可以剪切/粘贴。
在我的示例中,复杂的部分是onLongClickListener,它的深度以及匿名类的数量。
但是,另一方面,简单的是,所有内容都包含在一个相对较短的类(MainActivity)中,并且只有一个主要代码块-onLongClickListener-仅定义了一次,非常清楚“操作”代码为:
package com.example.boober.aalongclickoptimizationunit;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity {
TextView valueDisplay;
Button minusButton;
Button plusButton;
Button[] arrayOfControlButtons;
Integer currentDisplayValue = 500;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
valueDisplay = findViewById(R.id.value);
minusButton = findViewById(R.id.minusButton);
plusButton = findViewById(R.id.plusButton);
arrayOfControlButtons = new Button[]{plusButton, minusButton}; // this could be a large set of buttons
updateDisplay(); // initial setting of display
for (Button b : arrayOfControlButtons) {
b.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(final View v) {
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
if (v.isPressed()) { // important: checking if button still pressed
runOnUiThread(new Runnable() {
@Override
public void run() {
// --------------------------------------------------
// this is code that runs each time the
// long-click timer "goes off."
switch (v.getId()) {
// which button was pressed?
case R.id.plusButton: {
currentDisplayValue = currentDisplayValue + 10;
break;
}
case R.id.minusButton: {
currentDisplayValue = currentDisplayValue - 10;
break;
}
}
updateDisplay();
// --------------------------------------------------
}
});
} else
timer.cancel();
}
}, 100, 200);
// if set to false, then long clicks will propagate into single-clicks
// also, and we don't want that.
return true;
}
});
}
}
// ON-CLICKS (referred to from XML)
public void minusButtonPressed(View ignored) {
currentDisplayValue--;
updateDisplay();
}
public void plusButtonPressed(View ignored) {
currentDisplayValue++;
updateDisplay();
}
// INTERNAL
private void updateDisplay() {
valueDisplay.setText(currentDisplayValue.toString());
}
}
答案 4 :(得分:1)
虽然接受的答案是完全正确的,但可以简化一点。
基本上,我们可以优化两件事:
这是我的版本:
// global variables
Handler handler = new Handler();
Runnable runnable;
increaseView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
runnable = new Runnable() {
@Override
public void run() {
if (!increaseView.isPressed()) return;
increaseValue();
handler.postDelayed(runnable, DELAY);
}
};
handler.postDelayed(runnable, DELAY);
return true;
}
});
此处可重用可运行对象。当不再按下视图时,它将停止自动调用。
减少视图或按钮可以用类似的方式定义。
答案 5 :(得分:0)
只想分享自己的解决方案,对我来说真的很好。
首先,在您的活动中创建一个处理程序
private Handler mHandler = new Handler();
然后,创建将递增/递减并显示您的数字的可运行对象。在这里,我们将检查您的按钮是否仍处于按下状态,然后递增,然后重新运行可运行的。
private Runnable incrementRunnable = new Runnable() {
@Override
public void run() {
mHandler.removeCallbacks(incrementRunnable); // remove our old runnable, though I'm not really sure if this is necessary
if(IncrementButton.isPressed()) { // check if the button is still in its pressed state
// increment the counter
// display the updated value here, if necessary
mHandler.postDelayed(incrementRunnable, 100); // call for a delayed re-check of the button's state through our handler. The delay of 100ms can be changed as needed.
}
}
}
最后,在按钮的onLongClickListener中使用它
IncrementButton.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
mHandler.postDelayed(incrementRunnable, 0); // initial call for our handler.
return true;
}
});
就是这样!
另一种方法是在OnLongClickListener本身中声明处理程序和可运行程序,尽管我自己不确定这是否是一种好习惯。
IncrementButton.setOnLongClickListener(new View.OnLongClickListener() {
private Handler mHandler = Handler();
private Runnable incrementRunnable = new Runnable() {
@Override
public void run() {
mHandler.removeCallbacks(incrementRunnable);
if(IncrementButton.isPressed()) {
// increment the counter
// display the updated value here, if necessary
mHandler.postDelayed(incrementRunnable, 100);
}
}
};
@Override
public boolean onLongClick(View view) {
mHandler.postDelayed(incrementRunnable, 0);
return true;
}
});
当执行此连续增量时,我建议在一定时间/增量后增加增量值。 例如如果取得的number_of_increment小于10,则增加1。否则,增加3。
答案 6 :(得分:0)
导入java.awt。; 导入java.awt.event。; 公共类LabelNumber扩展Frame实现ActionListener {
Button badd,bsub;
TextField t1;
void display()
{
setTitle("Label number change");
setSize(400,500);
setLayout(new FlowLayout());
setVisible(true);
badd=new Button("+");
t1=new TextField("0",6);
bsub= new Button("-");
add(bsub);add(t1);add(badd);
badd.addActionListener(this);
bsub.addActionListener(this);
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
}
);
}
public void actionPerformed(ActionEvent e)
{
int count=0,add=0,sub,n1,n2;
count=Integer.parseInt(t1.getText());
if(e.getSource()==badd)
{
if(count<10)
{
count=count+1;
t1.setText(""+count);
}
else
{
t1.setText("limit:10");
}
}
if(e.getSource()==bsub)
{
if(count<10)
{
count=count-1;
t1.setText(""+count);
}
else
{
t1.setText("limit:10");
}
}
}
public static void main(String args[])
{
LabelNumber obj =new LabelNumber();
obj.display();
}
}
答案 7 :(得分:0)
针对Kotlin用户
myButton.setOnLongClickListener {
val handler = Handler(Looper.myLooper()!!)
val runnable : Runnable = object : Runnable {
val number = 0
override fun run() {
handler.removeCallbacks(this)
if (myButton.isPressed) {
val newNumber= number + 1
textView.text = "$newNumber Items"
handler.postDelayed(this, 100)
}
}
}
handler.postDelayed(runnable,0)
true
}
答案 8 :(得分:0)
初始化和调用方法
int speed = 0;
button = findViewById(R.id.button);
button.setOnTouchListener((v, event) -> {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
v.setPressed(true);
increment();
} else if (event.getAction() == MotionEvent.ACTION_UP) {
v.setPressed(false);
speed = 0;
}
return true;
});
这是增加方法
public void increment() {
new Handler().postDelayed(() -> {
Toast.makeText(FrequencyActivity.this, String.valueOf(speed), Toast.LENGTH_SHORT).show();
if (button.isPressed()) {
speed += 1;
increment();
}
}, 200); //200 ms for fast incrementing
}
答案 9 :(得分:-1)
我创建的最好,最简单的解决方案,请查看它是否对我有用
public void increment() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
check_amount = check_amount + 100;// increment by 100
tv_balance.setText("" + check_amount); // show continues incrementing value
if (check_amount != 5000) {
increment();
}
}
}, 1); //1 ms for fast incrementing
}