Android: düğme tıklaması nasıl yapılır


98

Java dışı ve Android dışı alanda sağlam bir deneyime sahip olarak Android öğreniyorum.

Farklı alanlarla ilgili çok fazla kafa karışıklığım var, bunlardan biri düğme tıklamaları ile nasıl başa çıkılacağı. Bunu yapmanın en az 4 yolu vardır (!!!), burada kısaca listelenmiştir

tutarlılık amacıyla bunları listeleyeceğim:

  1. View.OnClickListenerAktivitede sınıfın bir üyesine sahip olun onClickve onCreateaktivite yönteminde mantığı işleyecek bir örneğe atayın .

  2. 'OnCreate' etkinlik yönteminde 'onClickListener' oluşturun ve setOnClickListener kullanarak bunu düğmeye atayın

  3. Aktivitenin kendisinde 'onClickListener'ı uygulayın ve' this'i buton için bir dinleyici olarak atayın. Aktivitede birkaç düğme varsa, uygun düğme için 'onClick' işleyicisini çalıştırmak için düğme kimliği analiz edilmelidir.

  4. Aktivite üzerinde 'onClick' mantığını uygulayan genel metoda sahip olun ve bunu aktivite xml bildirimindeki butona atayın

Soru 1:

Bunların hepsi yöntemler mi, başka seçenek var mı? (Başkasına ihtiyacım yok, sadece merak ediyorum)

Benim için en sezgisel yol en yenisi olabilir: en az miktarda kodun yazılmasını gerektirir ve en çok okunabilir olanıdır (en azından benim için).

Yine de, bu yaklaşımın yaygın olarak kullanıldığını görmüyorum. Kullanmanın eksileri nelerdir?

Soru 2:

Bu yöntemlerin her birinin artıları / eksileri nelerdir? Lütfen deneyiminizi veya iyi bir bağlantıyı paylaşın.

Herhangi bir geri bildirim açığız!

Not: Google'ı denedim ve bu konu için bir şeyler buldum, ancak bulduğum tek şey bunun "nasıl" yapılacağı, neden iyi ya da kötü olduğu değil.

Yanıtlar:


151

Soru 1: Maalesef en sezgisel olduğunu söylediğiniz en az kullanılan Android'dir. Anladığım kadarıyla, kullanıcı arayüzünüzü (XML) ve hesaplama işlevselliğinizi (Java Sınıf Dosyaları) ayırmalısınız. Ayrıca, hata ayıklamayı kolaylaştırır. Aslında bu şekilde okumak ve Android imo hakkında düşünmek çok daha kolay.

Soru 2: Esas olarak kullanılan ikisinin # 2 ve # 3 olduğuna inanıyorum. Örnek olarak bir Button clickButton kullanacağım.

2

anonim bir sınıf biçimindedir.

Button clickButton = (Button) findViewById(R.id.clickButton);
clickButton.setOnClickListener( new OnClickListener() {
            
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                ***Do what you want with the click here***
            }
        });

FindViewById ile düğme değişkeninin ayarlandığı yerin hemen yanında onClick yöntemi olduğu için bu benim favorim. Bu clickButton Düğme Görünümü ile ilgili her şeyin burada yer aldığı çok temiz ve düzenli görünüyor.

İş arkadaşımın yorumladığı bir dezavantaj, onclick dinleyiciye ihtiyaç duyan birçok görünüme sahip olduğunuzu hayal etmenizdir. OnCreate'inizin çok uzun olacağını görebilirsiniz. Bu yüzden kullanmaktan hoşlanıyor:

3

5 clickButton'unuz olduğunu varsayalım:

Etkinlik / Parçanızın OnClickListener'ı uyguladığından emin olun

// in OnCreate

Button mClickButton1 = (Button)findViewById(R.id.clickButton1);
mClickButton1.setOnClickListener(this);
Button mClickButton2 = (Button)findViewById(R.id.clickButton2);
mClickButton2.setOnClickListener(this);
Button mClickButton3 = (Button)findViewById(R.id.clickButton3);
mClickButton3.setOnClickListener(this);
Button mClickButton4 = (Button)findViewById(R.id.clickButton4);
mClickButton4.setOnClickListener(this);
Button mClickButton5 = (Button)findViewById(R.id.clickButton5);
mClickButton5.setOnClickListener(this);


// somewhere else in your code

public void onClick(View v) {
    switch (v.getId()) {
        case  R.id.clickButton1: {
            // do something for button 1 click
            break;
        }

        case R.id.clickButton2: {
            // do something for button 2 click
            break;
        }

        //.... etc
    }
}

İş arkadaşımın açıkladığı gibi, tüm onClick hesaplamaları tek bir yerde işlendiğinden ve onCreate yöntemini zorlamadığından, bu şekilde onun gözünde daha temizdir. Ama gördüğüm dezavantajı şudur:

  1. kendilerini görür,
  2. ve onClick yöntemi tarafından kullanılan onCreate içinde bulunabilecek diğer nesnelerin bir alana dönüştürülmesi gerekecektir.

Daha fazla bilgi isterseniz bana bildirin. Sorunuza tam olarak cevap vermedim çünkü oldukça uzun bir soru. Ve eğer bazı siteler bulursam cevabımı genişleteceğim, şu anda sadece biraz deneyim veriyorum.


1
2. seçenek için bunu yapmak isteyeceksiniz: clickButton.setOnClickListener (new View.OnClickListener () {@Override public void onClick (View v) {// TODO you want to do}}); OnClickListener
ColossalChris'i

Seçenek 3, muhtemelen MVP kalıbı ile en temiz ve en kolay olanıdır.
Raffaeu

Seçenek 2 hala onCreate()çok uzun olmayan üretebilir . Tıklama dinleyici atamaları ve anonim sınıflar, içinden çağrılan ayrı bir yardımcı yönteme ayrılabilir onCreate().
Nick Alexeev

@Colossal: Bunu yapmak zorunda değilsin. Aktivite Sınıfına, "View.OnClickListener uygular" gibi uzantı ekleyin.
TomeeNS

11

# 1 Düzen üzerinde oluşturulmayan (ancak açıkça statik olan) düğmeler varken sonuncuyu sıklıkla kullanıyorum.

Uygulamada ve bir iş uygulamasında kullanırsanız, buraya daha fazla dikkat edin, çünkü ProGuard gibi kaynak gizleyici kullandığınızda, bu yöntemleri faaliyetinizde gizlenmeyecek şekilde işaretlemeniz gerekir.

Bu yaklaşımla bir tür derleme zamanı güvenliğini arşivlemek için Android Lint'e bakın ( örnek ).


# 2 Tüm yöntemler için artılar ve eksiler neredeyse aynıdır ve ders şöyle olmalıdır:

Size en uygun olanı veya sizin için en sezgisel olanı kullanın.

Aynısını OnClickListenerbirden çok düğme örneğine atamanız gerekiyorsa, bunu sınıf kapsamında (# 1) kaydedin. Bir Button için basit bir dinleyiciye ihtiyacınız varsa, anonim bir uygulama yapın:

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        // Take action.
    }
});

OnClickListenerEtkinlikte uygulama thisyapmama eğilimindeyim , bu zaman zaman biraz kafa karıştırıcı oluyor (özellikle birden fazla başka olay işleyiciyi uyguladığınızda ve kimse ne yaptığını bilmiyorsa ).


Ben de aynısını takip ediyorum ama hala fonksiyon için çıktı
Rocket

8

4. seçeneği tercih ederim, ancak Grails, Groovy ve JavaFX'te çok fazla çalıştığım için bu bana mantıklı geliyor. Görünüm ve denetleyici arasındaki "sihirli" bağlantılar hepsinde ortaktır. Yöntemi iyi adlandırmak önemlidir:

Görünümde, onClick yöntemini düğmeye veya başka bir widget'a ekleyin:

    android:clickable="true"
    android:onClick="onButtonClickCancel"

Ardından sınıfta yöntemi uygulayın:

public void onButtonClickCancel(View view) {
    Toast.makeText(this, "Cancel pressed", Toast.LENGTH_LONG).show();
}

Yine, yöntemi açık bir şekilde adlandırın, yine de yapmanız gereken bir şey ve bakım ikinci doğa haline gelir.

Büyük bir avantaj, artık yöntem için birim testleri yazabilmenizdir. 1. seçenek bunu yapabilir, ancak 2 ve 3 daha zordur.


1
Biraz waffle yapacağım ve beşinci bir seçenek (hayır, başrolde Bruce Willis değil :)) önereceğim, seçenek 2'nin bir çeşidi: tıklamaları işlemek için Model-View-Presenter çerçevesinde bir Presenter sınıfı kullanın. Otomatik testi ÇOK kolaylaştırır. Daha iyi bilgi için şu bağlantıya göz atın: codelabs.developers.google.com/codelabs/android-testing/…
Steve Gelman

4

En çok kullanılan yol, anonim beyan

    Button send = (Button) findViewById(R.id.buttonSend);
    send.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // handle click
        }
    });

Ayrıca View.OnClickListener nesnesini oluşturabilir ve daha sonra button olarak ayarlayabilirsiniz, ancak yine de örneğin onClick yöntemini geçersiz kılmanız gerekir

View.OnClickListener listener = new View.OnClickListener(){
     @Override
        public void onClick(View v) {
            // handle click
        }
}   
Button send = (Button) findViewById(R.id.buttonSend);
send.setOnClickListener(listener);

Aktiviteniz OnClickListener arayüzünü uyguladığında, aktivite düzeyinde onClick (View v) yöntemini geçersiz kılmalısınız. Ardından, bu etkinliği düğmenin dinleyicisi olarak atayabilirsiniz, çünkü zaten arabirimi uygular ve onClick () yöntemini geçersiz kılar.

public class MyActivity extends Activity implements View.OnClickListener{


    @Override
    public void onClick(View v) {
        // handle click
    }


    @Override
    public void onCreate(Bundle b) {
        Button send = (Button) findViewById(R.id.buttonSend);
        send.setOnClickListener(this);
    }

}

(imho) 4-inci yaklaşım, birden çok düğme aynı işleyiciye sahip olduğunda kullanılır ve etkinlik sınıfında bir yöntem bildirebilir ve bu yöntemi xml düzeninde birden çok düğmeye atayabilirsiniz, ayrıca bir düğme için bir yöntem oluşturabilirsiniz, ancak bu durumda I işleyicileri etkinlik sınıfı içinde bildirmeyi tercih eder.


1

Seçenek 1 ve 2, kodu karmaşaya dönüştürecek iç sınıfı kullanmayı içerir. 2. Seçenek biraz dağınık çünkü her buton için bir dinleyici olacak. Az sayıda düğmeniz varsa, sorun değil. Seçenek 4 için, xml ve java kodunu dördüncü ve geri gitmeniz gerekeceğinden, bu hata ayıklamanın daha zor olacağını düşünüyorum. Birden fazla düğme tıklamasını işlemem gerektiğinde kişisel olarak 3. seçeneği kullanıyorum.


1

Örneğim, Android Studio 2.1'de test edildi

Düğmeyi xml düzeninde tanımla

<Button
    android:id="@+id/btn1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

Java titreşim algılama

Button clickButton = (Button) findViewById(R.id.btn1);
if (clickButton != null) {
    clickButton.setOnClickListener( new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            /***Do what you want with the click here***/
        }
    });
}

1

İşleri kolaylaştırmak için Soru 2'de belirtildiği gibi, değişken hafızadan tasarruf etmek ve görünüm sınıfınızda yukarı ve aşağı gezinmekten kaçınmak için bu gibi lambda yöntemini kullanabilirsiniz.

//method 1
findViewById(R.id.buttonSend).setOnClickListener(v -> {
          // handle click
});

ancak tıklama etkinliğini bir yöntemde düğmenize bir kerede uygulamak isterseniz.

@D tarafından Soru 3'ü kullanabilirsiniz. Tran cevap. Ancak kendi görüş sınıfınızı ile uygulamayı unutmayın View.OnClickListener.

Diğerinde 3. Soruyu doğru kullanmak


1
Bu, IMO yöntem referansları ile birleştirilen modern cevap olarak düşünülmelidir. Diğer cevapların çoğu, Android'de Java8 öncesi kod oldukları gerçeğini açıklamıyor.
Ryan The Leach

0

Soru 1 - Bunlar, görüntüleme tıklamalarını işlemenin tek yoludur.

Soru # 2 -
Seçenek # 1 / Seçenek # 4 - Seçenek # 1 ile seçenek # 4 arasında çok fazla fark yok. Gördüğüm tek fark, bir durumda etkinliğin OnClickListener'ı uygulamak, diğer durumda ise anonim bir uygulama olacaktır.

Seçenek # 2 - Bu yöntemde anonim bir sınıf oluşturulacaktır. Bu yöntem biraz tuhaftır, çünkü birden fazla düğmeniz varsa bunu birden çok kez yapmanız gerekir. Anonim sınıflar için, bellek sızıntılarını ele alırken dikkatli olmalısınız.

Seçenek # 3 - Yine de bu kolay bir yoldur. Genellikle, Programcılar yazana kadar herhangi bir yöntemi kullanmamaya çalışırlar ve bu nedenle bu yöntem yaygın olarak kullanılmaz. Çoğunlukla insanların 4. Seçeneği kullandığını görürsünüz. Çünkü kodlama açısından daha temiz.


Merhaba Gaurav, cevabınız için teşekkür ederim. Ancak burada ne demek istediğinizi açıklığa kavuşturabilir misiniz? Anonim sınıflar için, bellek sızıntılarıyla ilgilenirken dikkatli olmalısınız. Hafıza sızıntıları buraya nasıl gelir?
Budda

Sadece şunu bilmelisiniz: eğer uygulamanızın ömrü boyunca birden çok kez çağrılabilecek bir yöntem içinde anonim bir sınıf oluşturursanız, bir sınıfın birkaç örneği değil, bunların örnekleri dahil birkaç sınıf oluşturulacaktır. Normal iç sınıfları kullanarak ve dinleyicileri örnek alanları olarak başlatarak bundan kaçınabilirsiniz. Yapıcı argümanları aracılığıyla dinleyicinin durumunu bilinçli hale getirerek farklı dinleyici sınıflarını azaltmaya çalışın. Normal bir iç sınıf, size özel oluşturuculardan ve diğer yöntemlerden yarar sağlar.
Risadinha

0

Ayrıca, bu işlemi diğer MVVM çerçevelerini kullanan kişilere çok aşina hale getirebilecek çeşitli kitaplıklar biçiminde seçenekler de vardır.

https://developer.android.com/topic/libraries/data-binding/

Düğmeleri şu şekilde bağlamanıza izin veren resmi bir kitaplık örneğini gösterir:

<Button
    android:text="Start second activity"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:onClick="@{() -> presenter.showList()}"
/>

0

Adım 1: Bir XML Dosyası Oluşturun:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/btnClickEvent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Click Me" />
</LinearLayout>

Adım 2: MainActivity'yi oluşturun:

package com.scancode.acutesoft.telephonymanagerapp;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity implements View.OnClickListener {

    Button btnClickEvent;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnClickEvent = (Button) findViewById(R.id.btnClickEvent);
        btnClickEvent.setOnClickListener(MainActivity.this);

    }

    @Override
    public void onClick(View v) {
        //Your Logic
    }
}

HappyCoding!

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.