Android OnClickListener - bir düğmeyi tanımlayın


134

Aktivitem var:

public class Mtest extends Activity {
  Button b1;
  Button b2;
  public void onCreate(Bundle savedInstanceState) {
    ...
    b1 = (Button) findViewById(R.id.b1);
    b2 = (Button) findViewById(R.id.b2);
    b1.setOnClickListener(myhandler);
    b2.setOnClickListener(myhandler);
    ...
  }
  View.OnClickListener myhandler = new View.OnClickListener() {
    public void onClick(View v) {
      // MY QUESTION STARTS HERE!!!
      // IF b1 do this
      // IF b2 do this
      // MY QUESTION ENDS HERE!!!
    }
  }
}

Hangi düğmenin tıklandığını nasıl kontrol ederim?


1
Birden çok düğme için OnClickListeners eklemenin beş farklı yolunun karşılaştırılması
Suragch

Yanıtlar:


199

Bunu yapmanın yolunu, kolay bir şekilde öğreneceksiniz:

public class Mtest extends Activity {
  Button b1;
  Button b2;
  public void onCreate(Bundle savedInstanceState) {
    ...
    b1 = (Button) findViewById(R.id.b1);
    b2 = (Button) findViewById(R.id.b2);
    b1.setOnClickListener(myhandler1);
    b2.setOnClickListener(myhandler2);
    ...
  }
  View.OnClickListener myhandler1 = new View.OnClickListener() {
    public void onClick(View v) {
      // it was the 1st button
    }
  };
  View.OnClickListener myhandler2 = new View.OnClickListener() {
    public void onClick(View v) {
      // it was the 2nd button
    }
  };
}

Veya yalnızca bir tıklama dinleyicisiyle çalışıyorsanız şunları yapabilirsiniz:

View.OnClickListener myOnlyhandler = new View.OnClickListener() {
  public void onClick(View v) {
      switch(v.getId()) {
        case R.id.b1:
          // it was the first button
          break;
        case R.id.b2:
          // it was the second button
          break;
      }
  }
}

Yine de, bu şekilde yapmanızı önermiyorum çünkü ifkullandığınız her düğme için bir eklemek zorunda kalacaksınız. Bunu korumak zor.


1
Aslında bu doğru değil. Viewdeğil bir Button, ama Buttonbir olduğunu View. Gerçi, bir yayınlayabileceğim Viewa Button. Bunu yapmanın ikinci yolunun tavsiye edilmediğini unutmayın ... belki de v bir istisna oluşturacak bir Düğme olmayabilir.
Cristian

2
Aslında her iki yol da önerilmiyor, cevabımı gör
ognian

Bu, görünümün kimliğini açtığınız tek bir anahtar durum ifadesi ile if, başkalarını değiştirmek oldukça basittir ve vakalar R.java'dan alınmıştır
slayton

Neden v'yi bir Button'a attığınızı merak ediyorum. getId (), Görünümler için de tanımlanır. Bu yüzden gerçekten ikinci yöntemi tavsiye etmem ama Christian'ın çözümünü tercih ederim!
nuala

77

Ya da aynı şeyi ancak dinleyici olmadan deneyebilirsiniz. Düğme XML tanımınızda:

android:onClick="ButtonOnClick"

Ve kodunuzda yöntemi tanımlayın ButtonOnClick:

public void ButtonOnClick(View v) {
    switch (v.getId()) {
      case R.id.button1:
        doSomething1();
        break;
      case R.id.button2:
        doSomething2();
        break;
      }
}

3
Bir sürü olay işleyici, ififade ve dinleyici kullanan diğer cevaplardan çok daha temiz . Düğmeler çalışma zamanında oluşturulursa dinleyiciler harikadır, ancak genellikle durum böyle değildir.
Dennis

6
İlginç bir farklı yaklaşım olsa da, dinleyiciler için XML kancaları Fragments ile köşeler arasında pürüzlüdür , çünkü geri arama etkinlikte (parçada değil) bulunmalıdır.
donfede

Benim prob doSomething2 () bir InvocationTargetException veya bir NullPointerException (veya her ikisi) atmadan ulaşılamaz olduğunu.
Quasaur

1
Sadece bir sidenote: "dinleyicisiz" ifadesi yanlış. Sadece XML'de dinleyiciyi bildiriyorsunuz, hepsi bu.
Hubert Grzeskowiak

42

Tercih ederim:

class MTest extends Activity implements OnClickListener {
    public void onCreate(Bundle savedInstanceState) {
    ...
    Button b1 = (Button) findViewById(R.id.b1);
    Button b2 = (Button) findViewById(R.id.b2);
    b1.setOnClickListener(this);
    b2.setOnClickListener(this);
    ...
}

Ve sonra:

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.b1:
            ....
            break;
        case R.id.b2:
            ....
            break;
    }   
}

Switch- casedaha daha kolay kullanılır if- elseve bu uygulama birçok sınıf değişkenleri yapma gerektirmez.


Bu mükemmel çalıştı. Sen uygulamak gerekir OnClickListener-android.view.View değil OnClickListener-android.content.DialogInterface
gkiko

16

Bir Olay Dinleyicisini Bağlamanın Beş Yolu, tek bir olay dinleyicisi kurmanın çeşitli yollarını gözden geçiren harika bir makaledir. Bunu burada birden fazla dinleyici için genişleteyim.

1. Üye Sınıfı

public class main extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        //attach an instance of HandleClick to the Button
        HandleClick handleClick = new HandleClick();
        findViewById(R.id.button1).setOnClickListener(handleClick);
        findViewById(R.id.button2).setOnClickListener(handleClick);
    }    
    private class HandleClick implements OnClickListener{
        public void onClick(View view) {
            switch(view.getId()) {
            case R.id.button1:
                // do stuff
                break;
            case R.id.button2:
                // do stuff
                break;
            }
        }
    }
}

2. Arayüz Tipi

public class main extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        findViewById(R.id.button1).setOnClickListener(handleClick);
        findViewById(R.id.button2).setOnClickListener(handleClick);
    }
    private OnClickListener handleClick = new OnClickListener() {
        public void onClick(View view) {
            switch (view.getId()) {
            case R.id.button1:
                // do stuff
                break;
            case R.id.button2:
                // do stuff
                break;
            }
        }
    };
}

3. Anonim İç Sınıf

public class main extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        findViewById(R.id.button1).setOnClickListener(new OnClickListener() {
            public void onClick(View view) {
                // do stuff
            }
        });
        findViewById(R.id.button2).setOnClickListener(new OnClickListener() {
            public void onClick(View view) {
                // do stuff
            }
        });
    }
}

4. Faaliyette Uygulama

public class main extends Activity implements OnClickListener {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        findViewById(R.id.button1).setOnClickListener(this);
        findViewById(R.id.button2).setOnClickListener(this);
    }
    public void onClick(View view) {
        switch (view.getId()) {
        case R.id.button1:
            // do stuff
            break;
        case R.id.button2:
            // do stuff
            break;
        }
    }
}

5. OnClick Etkinlikleri için Görünüm Düzenindeki Özellik

public class main extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
    public void HandleClick(View view) {
        switch (view.getId()) {
        case R.id.button1:
            // do stuff
            break;
        case R.id.button2:
            // do stuff
            break;
        }
    }
}

Ve xml'de:

<Button
    android:id="@+id/button1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="HandleClick" />
<Button
    android:id="@+id/button2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="HandleClick" />

12

Sınıf düğmesinde 2 düğmesinin örneklerini kaydetmek istemiyorsanız, bu DAHA İYİ yolu izleyin (bu daha açık ve hızlıdır !!):

public void buttonPress(View v) {
  switch (v.getId()) {
    case R.id.button_one:
        // do something
        break;
    case R.id.button_two:
        // do something else
        break;
    case R.id.button_three:
        // i'm lazy, do nothing
        break;
  }
}

12

Bunu yapmanın başka bir yolu, etkinlikten tek bir dinleyicidir, şöyle:

public class MyActivity extends Activity implements OnClickListener {
    .......  code

    //my listener
    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.mybutton) { 
            DoSomething();
            return;
        }

        if (v.getId() == R.id.mybutton2) { 
            DoSomething2();
            return;
        }
    }
}

Bunu switch-else yerine tek IF ile yapmayı seviyorum, ancak bunu tercih ederseniz, yapmalısınız:

//my listener
@Override
public void onClick(View v) {
    switch(v.getId()) {
        case R.id.mybutton:
        { 
             DoSomething();
             break;
        }

        case R.id.mybutton2:
        {
            DoSomething();
            break;
        }
    }
}

9

En iyi yol switchv.getId () arasında -ing yapmaktır. Her Düğme için ayrı bir anonim OnClickListener'a sahip olmak daha fazla bellek kaplıyor. Düğmeye Görünüm Dökümü gerekli değildir. Anahtar mümkünse if-else kullanmak daha yavaş ve okunması daha zordur. Android kaynağında referansları if-else ile karşılaştırdığınızı fark edebilirsiniz:

if (b1 == v) {
 // ...
} else if (b2 == v) {

Neden bu yolu seçtiklerini tam olarak bilmiyorum, ama o da işe yarıyor.


çünkü artık
id'lerin

@ognian Buraya geldim çünkü ana cevabın onaylanmamış yaklaşımlar kullandığını söylediniz. Günümüzde Android 5.0 Lollipop piyasaya sürüldüğünde, cevabınız hala doğru mu, yoksa yukarıdaki yorumda da belirtildiği gibi, bunun bir hata haline geldi mi? Ne düşüneceğimi veya buradan hangi yöne gideceğimi gerçekten bilmiyorum.
SebasSBM

7

setTag () kullanın;

bunun gibi:

@Override    
public void onClick(View v) {     
    int tag = (Integer) v.getTag();     
    switch (tag) {     
    case 1:     
        System.out.println("button1 click");     
        break;     
    case 2:     
        System.out.println("button2 click");     
       break;   
    }     
}     

Buraya bir işleyiciye ek parametreler geçirmek için bir yöntem aramaya geldim, tam olarak istediğim buydu. Etiket İşaretleme'de bildirilebilir.
19

4

Cristian C'nin cevabına ek olarak (üzgünüm, yorum yapma yeteneğim yok), her iki düğme için bir işleyici yaparsanız, v'yi b1 ve b2 ile doğrudan karşılaştırabilir veya kimliğe göre karşılaştırmak isterseniz, v düğmesini Button (View'da getId () yöntemi de vardır) kullanmanıza gerek yoktur ve bu şekilde cast istisnası endişesi yoktur.


Başka bir seçenek "if (v instanceof Button) {// Düğmeye Yayınla ve burada bir şeyler yap}"
Andy Zhang

4
Button mybutton = new Button(ViewPagerSample.this);
mybutton.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
            // TODO Auto-generated method stub
    }
});

1
Button button1 = (Button)findViewById(R.id.button1);
button1.setOnClickListener(this);

@Override
public void onClick(View v) {
    // TODO Auto-generated method stub
    if(v.getId() == R.id.button1){
        Toast.makeText(context, "Button 1 Click", Toast.LENGTH_LONG).show();
    }
}

Daha fazla ayrıntı için bu makaleye göz atın


Bu az çok mevcut cevapların bir tekrarıdır.
Pang
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.