एंड्रॉइड: बटन को कैसे हैंडल करें क्लिक करें


95

गैर-जावा और गैर-एंड्रॉइड क्षेत्र में एक ठोस अनुभव होने के बाद, मैं एंड्रॉइड सीख रहा हूं।

मुझे विभिन्न क्षेत्रों के साथ बहुत भ्रम है, उनमें से एक बटन क्लिक को कैसे संभालना है। ऐसा करने के कम से कम 4 तरीके हैं (!!!), उन्हें संक्षेप में यहां सूचीबद्ध किया गया है

स्थिरता के उद्देश्य से मैं उनकी सूची दूंगा:

  1. View.OnClickListenerगतिविधि में कक्षा का एक सदस्य रखें और इसे एक ऐसे उदाहरण के लिए असाइन करें जो गतिविधि विधि onClickमें तर्क को संभाल लेगा onCreate

  2. 'OnCreate' गतिविधि पद्धति में 'onClickListener' बनाएँ और setOnClickListener का उपयोग करके इसे बटन पर असाइन करें

  3. गतिविधि में 'onClickListener' को लागू करें और बटन के लिए श्रोता के रूप में 'this' असाइन करें। मामले के लिए अगर गतिविधि में कुछ बटन हैं, उचित आईडी के लिए 'ऑनक्लिक' हैंडलर को निष्पादित करने के लिए बटन आईडी का विश्लेषण किया जाना चाहिए

  4. गतिविधि पर सार्वजनिक विधि रखें जो 'onClick' तर्क को लागू करती है और इसे गतिविधि xml घोषणा में बटन पर असाइन करें

प्रश्न 1:

क्या वे सभी विधियां हैं, क्या कोई अन्य विकल्प है? (मैं किसी भी अन्य की जरूरत नहीं है, बस जिज्ञासु)

मेरे लिए, सबसे सहज तरीका सबसे नया होगा: इसके लिए कम से कम कोड टाइप करने की आवश्यकता होती है और यह सबसे अधिक पढ़ने योग्य होता है (कम से कम मेरे लिए)।

हालाँकि, मैं इस दृष्टिकोण का व्यापक रूप से उपयोग नहीं करता। इसका उपयोग करने के लिए विपक्ष क्या हैं?

प्रश्न 2:

इन विधियों में से प्रत्येक के लिए पेशेवरों / विपक्ष क्या हैं? कृपया अपना अनुभव या अच्छी लिंक साझा करें।

किसी भी प्रतिक्रिया का स्वागत है!

PS मैंने Google के लिए प्रयास किया है और इस विषय के लिए कुछ ढूंढ रहा हूं, लेकिन केवल एक चीज जो मुझे मिली है वह है विवरण "कैसे" ऐसा करने के लिए, न कि यह अच्छा या बुरा क्यों है।

जवाबों:


147

प्रश्न 1: दुर्भाग्य से आप जिसको कहते हैं, वह सबसे सहज है। जैसा कि मैं समझता हूं, आपको अपने यूआई (एक्सएमएल) और कम्प्यूटेशनल कार्यक्षमता (जावा क्लास फाइल्स) को अलग करना चाहिए। यह आसान डिबगिंग के लिए भी बनाता है। इस तरह से पढ़ना और Android imo के बारे में सोचना वास्तव में बहुत आसान है।

प्रश्न 2: मेरा मानना ​​है कि दो मुख्य रूप से # 2 और # 3 उपयोग किए जाते हैं। मैं एक उदाहरण के रूप में एक बटन क्लिकबटन का उपयोग करूंगा।

2

एक अनाम वर्ग के रूप में है।

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

यह मेरा पसंदीदा है क्योंकि इसमें बटन दृश्य चर के साथ सेट किया गया है, जिसके ठीक बगल में ऑनक्लिक विधि है। यह बहुत साफ और सुव्यवस्थित लगता है कि इस क्लिकबटन बटन व्यू के साथ जो कुछ भी व्यवहार होता है वह यहां स्थित है।

एक सहकर्मी जो मेरी सहकर्मी टिप्पणी करता है, वह यह है कि कल्पना करें कि आपके पास कई विचार हैं जो कि श्रोता की आवश्यकता है। आप देख सकते हैं कि आपका onCreate लंबाई में बहुत लंबा हो जाएगा। ताकि वह उपयोग करना पसंद करे:

3

आप कहें, 5 क्लिक करें:

सुनिश्चित करें कि आपकी गतिविधि / फ्रैगमेंट OnClickListener लागू करें

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

इस तरह से मेरे सहकर्मी बताते हैं कि उनकी आँखों में नटखट है, क्योंकि सभी ऑनकिक गणना को एक जगह पर संभाला जाता है और ऑनक्रिएट विधि को भीड़ नहीं देता है। लेकिन मैं देख रहा हूँ, यह है कि:

  1. खुद को देखता है,
  2. और कोई भी अन्य वस्तु जो onClick विधि द्वारा उपयोग किए जाने वाले onCreate में स्थित हो सकती है, को एक फ़ील्ड में बनाना होगा।

यदि आप अधिक जानकारी चाहते हैं तो मुझे बताएं। मैंने आपके प्रश्न का पूरी तरह से उत्तर नहीं दिया क्योंकि यह बहुत लंबा प्रश्न है। और अगर मुझे कुछ साइटें मिलें तो मैं अपने उत्तर का विस्तार करूंगा, अभी मैं कुछ अनुभव दे रहा हूं।


1
विकल्प 2 के लिए आप इसे बनाना चाहते हैं: clickButton.setOnClickListener (नया View.OnClickListener () {@Override public void onClick (देखें v) {// TODO जो आप करना चाहते हैं}}); मदद करने के लिए इसे सुलझाने के लिए OnClickListener
ColossalChris

विकल्प 3 शायद एमवीपी पैटर्न के साथ विस्तार करने के लिए सबसे साफ और सबसे आसान है।
रफाउउ

विकल्प 2 अभी भी उत्पादन कर सकता है onCreate()जो भयानक रूप से लंबा नहीं है। क्लिक श्रोता असाइनमेंट और अनाम कक्षाओं को अलग हेल्पर विधि में फैक्टर किया जा सकता है जिसे कहा जाता है onCreate()
निक अलेक्सिएव

@ कोलोसल: आपको ऐसा करने की जरूरत नहीं है। "लागू करें View.OnClickListener" जैसी गतिविधि वर्ग के लिए एक्सटेंशन जोड़ें।
टोमेएनएस

10

# 1 मैं लेआउट पर बटन होने पर पिछले एक का अक्सर उपयोग करता हूं जो उत्पन्न नहीं होते हैं (लेकिन स्पष्ट रूप से स्थिर)।

यदि आप इसे व्यवहार में और एक व्यावसायिक अनुप्रयोग में उपयोग करते हैं, तो यहां अतिरिक्त ध्यान दें, क्योंकि जब आप स्रोत obfuscater का उपयोग करते हैं ProGuard जैसे , तो आपको अपनी गतिविधि में इन तरीकों को चिह्नित करने की आवश्यकता होगी वे अस्पष्ट नहीं हैं।

इस दृष्टिकोण के साथ किसी तरह के संकलन-समय-सुरक्षा को संग्रहीत करने के लिए, एंड्रॉइड लिंट ( उदाहरण ) पर एक नज़र डालें ।


# 2 सभी तरीकों के लिए पेशेवरों और विपक्ष लगभग समान हैं और सबक होना चाहिए:

वह प्रयोग करें जो कभी सबसे उपयुक्त हो या आपको सबसे अधिक सहज लगता हो।

यदि आपको एक OnClickListenerसे अधिक बटन इंस्टेंसेस को असाइन करना है , तो इसे क्लास-स्कोप (# 1) में सेव करें। यदि आपको एक बटन के लिए एक सरल श्रोता की आवश्यकता है, तो एक अनाम कार्यान्वयन करें:

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

मैं OnClickListenerगतिविधि में लागू नहीं करता हूं , यह समय-समय पर थोड़ा भ्रमित हो जाता है (विशेषकर जब आप कई अन्य इवेंट-हैंडलर लागू करते हैं और किसी को नहीं पता है कि thisसभी क्या कर रहे हैं)।


मैं उसी का अनुसरण कर रहा हूं, लेकिन अभी भी फ़ंक्शन के लिए कोई आउटपुट नहीं मिल रहा है, मेरा कोड और क्वेरी यहां है: stackoverflow.com/questions/25107427/…
रॉकेट

8

मैं विकल्प 4 को पसंद करता हूं, लेकिन यह मेरे लिए सहज ज्ञान युक्त है क्योंकि मैं ग्रेल्स, ग्रूवी और जावाएफएक्स में बहुत अधिक काम करता हूं। दृश्य और नियंत्रक के बीच "मैजिक" कनेक्शन सभी में सामान्य हैं। विधि को अच्छी तरह से नाम देना महत्वपूर्ण है:

दृश्य में, बटन या अन्य विजेट के लिए ऑनक्लिक विधि जोड़ें:

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

फिर कक्षा में, विधि को संभालें:

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

फिर से, विधि को स्पष्ट रूप से नाम दें, कुछ भी आपको वैसे भी करना चाहिए, और रखरखाव दूसरी प्रकृति बन जाता है।

एक बड़ा फायदा यह है कि आप विधि के लिए अब यूनिट टेस्ट लिख सकते हैं। विकल्प 1 ऐसा कर सकता है, लेकिन 2 और 3 अधिक कठिन हैं।


1
मैं थोड़ा वफ़ल करने जा रहा हूं और एक पांचवां विकल्प सुझाता हूं (नहीं, ब्रूस विलिस :) अभिनीत नहीं), विकल्प 2 का एक प्रकार: क्लिक को संभालने के लिए मॉडल-व्यू-प्रस्तुतकर्ता ढांचे में प्रस्तुतकर्ता वर्ग का उपयोग करें। यह स्वचालित परीक्षण को आसान बनाता है। बेहतर जानकारी के लिए इस लिंक को देखें: codelabs.developers.google.com/codelabs/android-testing/…
स्टीव जेलमैन

4

सबसे ज्यादा इस्तेमाल किया जाने वाला तरीका है, अनाम घोषणा

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

इसके अलावा, आप View.OnClickListener ऑब्जेक्ट बना सकते हैं और इसे बाद में बटन पर सेट कर सकते हैं, लेकिन आपको अभी भी उदाहरण के लिए onClore विधि को ओवरराइड करने की आवश्यकता है

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

जब आपकी गतिविधि OnClickListener इंटरफ़ेस को लागू करती है, तो आपको गतिविधि स्तर पर onClick (देखें v) विधि को ओवरराइड करना होगा। फिर आप इस गतिविधि को श्रोता के रूप में बटन करने के लिए आश्वासन दे सकते हैं, क्योंकि यह पहले से ही इंटरफ़ेस को लागू करता है और ऑनक्लिक () विधि को ओवरराइड करता है।

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-वें दृष्टिकोण का उपयोग तब किया जाता है जब कई बटन में एक ही हैंडलर होता है, और आप एक्टिविटी क्लास में एक विधि की घोषणा कर सकते हैं और इस विधि को एक्सएमएल लेआउट में कई बटन पर असाइन कर सकते हैं, आप एक बटन के लिए एक विधि भी बना सकते हैं, लेकिन इस मामले में मैं गतिविधि वर्ग के अंदर हैंडलर घोषित करना पसंद करते हैं।


1

विकल्प 1 और 2 में आंतरिक वर्ग का उपयोग करना शामिल है जो कोड को अव्यवस्थित बना देगा। विकल्प 2 गड़बड़ है, क्योंकि हर बटन के लिए एक श्रोता होगा। यदि आपके पास बटन की संख्या कम है, तो यह ठीक है। विकल्प 4 के लिए मुझे लगता है कि यह डिबग करना कठिन होगा क्योंकि आपको एक्सएमएल और जावा कोड को चौथे पर वापस जाना होगा। मैं व्यक्तिगत रूप से विकल्प 3 का उपयोग करता हूं जब मुझे कई बटन क्लिक को संभालना पड़ता है।


1

मेरा नमूना, एंड्रॉइड स्टूडियो 2.1 में परीक्षण किया गया

Xml लेआउट में बटन को परिभाषित करें

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

जावा धड़कन का पता लगाने

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

प्रश्न 2 को आसान बनाने के लिए प्रश्न 2 में कहा गया है, आप चर स्मृति को बचाने और अपने दृश्य वर्ग में ऊपर और नीचे नेविगेट करने से बचने के लिए इस तरह के लंबोदा विधि का उपयोग कर सकते हैं

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

लेकिन अगर आप एक बार में एक विधि से अपने बटन पर क्लिक घटना लागू करना चाहते हैं।

आप @D द्वारा प्रश्न 3 का उपयोग कर सकते हैं। ट्रान जवाब। लेकिन के साथ अपने विचार वर्ग को लागू करने के लिए मत भूलना View.OnClickListener

प्रश्न # 3 का सही उपयोग करने के लिए अन्य में


1
इसे आधुनिक संदर्भ को विधि संदर्भ IMO के साथ संयुक्त माना जाना चाहिए। अधिकांश अन्य उत्तर इस तथ्य को पुकारते नहीं हैं कि वे Android पर पुराने प्री जावा 8 कोड हैं।
रयान द लीच

0

प्रश्न # 1 - व्यू क्लिक को संभालने के लिए ये एकमात्र तरीका हैं।

प्रश्न 2 -
विकल्प # 1 / विकल्प # 4 - विकल्प # 1 और विकल्प # 4 के बीच बहुत अंतर नहीं है। एकमात्र अंतर जो मैं देख रहा हूं कि एक मामले में गतिविधि ओनक्लिक्लिस्टनर को लागू कर रही है, जबकि अन्य मामले में, एक अनाम कार्यान्वयन होगा।

विकल्प # 2 - इस पद्धति में एक अनाम वर्ग उत्पन्न होगा। यह विधि थोड़ी कठिन है, जैसा कि, आपको कई बार करने की आवश्यकता होगी, यदि आपके पास कई बटन हैं। बेनामी कक्षाओं के लिए, आपको मेमोरी लीक से निपटने के लिए सावधान रहना होगा।

विकल्प # 3 - हालांकि, यह एक आसान तरीका है। आमतौर पर, प्रोग्रामर किसी भी विधि का उपयोग करने की कोशिश नहीं करते हैं जब तक कि वे इसे नहीं लिखते हैं, और इसलिए इस पद्धति का व्यापक रूप से उपयोग नहीं किया जाता है। आप ज्यादातर लोगों को विकल्प # 4 का उपयोग करते देखेंगे। क्योंकि यह कोड की अवधि में क्लीनर है।


हाय गौरव, जवाब के लिए धन्यवाद। लेकिन क्या आप स्पष्ट कर सकते हैं कि आपके यहां क्या मतलब है: बेनामी कक्षाओं के लिए, आपको मेमोरी लीक से निपटने के लिए सावधान रहना होगा। कैसे स्मृति लीक यहाँ आते हैं?
बुद्ध

आपको बस इस बात से अवगत होना है कि: यदि आप एक ऐसी विधि के अंदर एक अनाम वर्ग बनाते हैं जिसे आपके ऐप के जीवनकाल में कई बार कॉल किया जा सकता है, तो एक वर्ग के एक नहीं बल्कि कई वर्ग बनाए जाएंगे जिनमें से कई उदाहरण शामिल हैं। आप नियमित रूप से आंतरिक कक्षाओं का उपयोग करके और श्रोताओं को उदाहरण क्षेत्रों के रूप में तात्कालिकता से बचा सकते हैं। कंस्ट्रक्टर की दलीलों के माध्यम से श्रोता राज्य को अवगत कराकर विभिन्न श्रोता वर्गों को कम करने का प्रयास करें। एक नियमित आंतरिक वर्ग आपको कस्टम कंस्ट्रक्टर और अन्य तरीकों का लाभ देता है।
रिसादिंह

0

विभिन्न पुस्तकालयों के रूप में उपलब्ध विकल्प भी हैं जो इस प्रक्रिया को उन लोगों से बहुत परिचित कर सकते हैं जिन्होंने अन्य MVVM फ्रेमवर्क का उपयोग किया है।

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

एक आधिकारिक पुस्तकालय का एक उदाहरण दिखाता है, जो आपको इस तरह से बटन बांधने की अनुमति देता है:

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

0

चरण 1: एक XML फ़ाइल बनाएँ:

<?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>

चरण 2: मुख्यता बनाएँ:

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!

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.