একাধিক এডিটেক্সটসের জন্য কীভাবে একক পাঠ্য ওয়াচচার ব্যবহার করবেন?


উত্তর:


190

আমি সবেমাত্র এই সমস্যার মুখোমুখি হয়েছি। আমি এটি একটি অভ্যন্তর শ্রেণীর বাস্তবায়ন তৈরি করে সমাধান করেছি যা একটি ভিউটিকে TextWatcherআর্গুমেন্ট হিসাবে গ্রহণ করে। তারপরে, পদ্ধতিটি প্রয়োগের ক্ষেত্রে, Editableকোনটি আসছে তা দেখতে কেবল ভিউ স্যুইচ করুন

ঘোষণা:

private class GenericTextWatcher implements TextWatcher{

    private View view;
    private GenericTextWatcher(View view) {
        this.view = view;
    }

    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}

    public void afterTextChanged(Editable editable) {
        String text = editable.toString();
        switch(view.getId()){
            case R.id.name:
                model.setName(text);
                break;
            case R.id.email:
                model.setEmail(text);
                break;
            case R.id.phone:
                model.setPhone(text);
                break;
        }
    }
}

ব্যবহার:

name = (EditText) findViewById(R.id.name);
name.setText(model.getName());
name.addTextChangedListener(new GenericTextWatcher(name));

email = (EditText) findViewById(R.id.email);
email.setText(model.getEmail());
email.addTextChangedListener(new GenericTextWatcher(email));

phone = (EditText) findViewById(R.id.phone);
phone.setText(model.getPhone());
phone.addTextChangedListener(new GenericTextWatcher(phone));

1
উপরের কোডে 'মডেল' কী এবং কোথায় এটি ঘোষণা করতে দয়া করে বলতে পারেন?
ইউড্রয়েড

33
এই উত্তর না Single TextWatcher for multiple EditTexts। এটি একটি পাঠ্য ওয়াচচার শ্রেণীর 3 টি উদাহরণ। সুতরাং 3 টি পৃথক পাঠ্যপালনকারীরা 3 টি সম্পাদনাবেক্ষণ নিয়ন্ত্রণ করছে।
ববস

2
প্রস্তাবিত সমাধানটি কিছু এডিটেক্সটসের জন্য একটি পাঠ্য ওয়াচচার নয়। এই উত্তরটি দেখুন: stackoverflow.com/a/13787221/779408
ববস

2
মনোভাবের মতো কাজ করে, দিক-ওরিয়েন্টেশন পরিবর্তন করার সময় ডেটা হারাতে ফর্ম-এলিমেন্টযুক্ত একটি খণ্ডের সাথে এটি একত্রিত করে।
ম্যাথিজস সেগারস

1
@ ফ্রেইসমেইল সম্পূর্ণ সুষ্ঠু হওয়ার জন্য, "একক পাঠ্য ওয়াচচার" এর অর্থ অগত্যা কোনও একক উদাহরণ নয়, এটি একটি একক শ্রেণিও হতে পারে।
ম্যালকম 22

42

আপনি যদি কেবলমাত্র টেক্সটচ্যাঞ্জড সম্পাদনাযোগ্য তুলনা করার পরে ব্যবহার করতে চান:

@Override
public void afterTextChanged(Editable editable) {
    if (editable == mEditText1.getEditableText()) {
        // DO STH
    } else if (editable == mEditText2.getEditableText()) {
        // DO STH
    }
}

10
এটি কেবলমাত্র সঠিকভাবে কাজ করবে যদি আপনি ==পরিবর্তে ব্যবহার করেন .equals()
জেরেট মিল্লার্ড 21

2
আপনি প্রতিভা! এটি কেবল পয়েন্টারগুলির সাথে তুলনা করা হচ্ছে যা সম্পাদনাযোগ্যতে সঞ্চিত প্রকৃত মান নয়! হ্যাঁ!
বুড়াক তমতার্ক

3
এমডিডিটেক্সট 1 এবং এমএডিটটেক্সট 2 এর একই পাঠ্য থাকলে কী হবে?
তাস

@ এই কারণে তারা মানের পরিবর্তে রেফারেন্সের সাথে তুলনা করা হয়
জোয়াকিম

1
@ টমাসজ কীভাবে এটি কাজ করে? আপনি কি টেক্সট ওয়াচার প্রয়োগ করেছেন? আপনি যদি তিনটি পদ্ধতি ওভাররাইড করতে চান না?
একাকী

10

মাল্টি টেক্সট ওয়াচার বাস্তবায়ন

public class MultiTextWatcher {

    private TextWatcherWithInstance callback;

    public MultiTextWatcher setCallback(TextWatcherWithInstance callback) {
        this.callback = callback;
        return this;
    }

    public MultiTextWatcher registerEditText(final EditText editText) {
        editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                callback.beforeTextChanged(editText, s, start, count, after);
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                callback.onTextChanged(editText, s, start, before, count);
            }

            @Override
            public void afterTextChanged(Editable editable) {
                callback.afterTextChanged(editText, editable);
            }
        });

        return this;
    }

    interface TextWatcherWithInstance {
        void beforeTextChanged(EditText editText, CharSequence s, int start, int count, int after);

        void onTextChanged(EditText editText, CharSequence s, int start, int before, int count);

        void afterTextChanged(EditText editText, Editable editable);
    }
}

ব্যবহার

    new MultiTextWatcher()
            .registerEditText(editText1)
            .registerEditText(editText2)
            .registerEditText(editText3)
            .setCallback(new TextWatcherWithInstance() {
                @Override
                public void beforeTextChanged(EditText editText, CharSequence s, int start, int count, int after) {
                    // TODO: Do some thing with editText
                }

                @Override
                public void onTextChanged(EditText editText, CharSequence s, int start, int before, int count) {
                    // TODO: Do some thing with editText
                }

                @Override
                public void afterTextChanged(EditText editText, Editable editable) {
                    // TODO: Do some thing with editText
                }
            });

আপনি কেবল তাদের চেইন আপ করার জন্য কেন অন্য ক্লাস তৈরি করবেন ?! মানে আপনি এখনও জানেন না কোনটি TextViewপরিবর্তন আসছে।
ফরিদ

10

আপনি ব্যবহার করতে চান তাহলে onTextChanged তুলনা hashCode()নিচে উল্লিখিত -

@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
    if(charSequence.hashCode() == first_edit_text.getText().hashCode()){
        // do other things 
    }

    if(charSequence.hashCode() == second_edit_text.getText().hashCode()){
       // do other things 
    }

}

অথবা

আপনি ব্যবহার করতে চান তাহলে afterTextChanged তুলনা Editableনিচে উল্লিখিত -

@Override
public void afterTextChanged(Editable editable) {
    if (editable == first_edit_text.getEditableText()) {
        // do other things 
    } else if (editable == second_edit_text.getEditableText()) {
       // do other things 
    }
}

9

এটি এই কোড সহ কাজ করবে

TextWatcher watcher = new TextWatcher() {
  @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            //YOUR CODE
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            //YOUR CODE
        }

        @Override
        public void afterTextChanged(Editable s) {
          String outputedText = s.toString();

  mOutputText.setText(outputedText);

        }
    };

তারপরে এটি অনক্রিয়েটে যুক্ত করুন

  mInputText.addTextChangedListener(watcher);
        e2.addTextChangedListener(watcher);
        e3.addTextChangedListener(watcher);
        e4.addTextChangedListener(watcher);

তাহলে কোথা থেকে এমআউটপুটটেক্সট?
কিমি চিউ

5

আমি জানি এটি একটি পুরানো সমস্যা, এবং সঠিক সিদ্ধান্ত আছে। আমি তাদের নিজস্ব লিখব, সম্ভবত এটি কাউকে সহায়তা করবে।

ক্লাসিক উদাহরণটি অনুকরণ করা হচ্ছে যেখানে আমাদের এন এডিটেক্সট রয়েছে এবং আমরা সমস্ত ক্ষেত্র পূরণ করা থাকলে বোতামটি প্রদর্শন করতে চাই show এই উদাহরণটি বোধগম্য হয়, বিশেষত যদি আরও প্রত্যেকের জন্য বৈধকারক ব্যবহার করে।

আমি ইস্যুটি সম্পর্কে শ্রদ্ধা সহ একটি উদাহরণ তৈরি করেছি, তবে আপনি যে কোনও সেট করতে পারেন

MultiEditText.class

public class MultiEditText extends AppCompatActivity{

EditText ed_1, ed_2, ed_3;
Button btn_ok;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.multi_edit_text);

    ed_1 = (EditText) findViewById(R.id.ed_1);
    ed_2 = (EditText) findViewById(R.id.ed_2);
    ed_3 = (EditText) findViewById(R.id.ed_3);
    btn_ok = (Button) findViewById(R.id.btn_ok);
    btn_ok.setEnabled(false);

    //if want more here can cycle interface List

     EditText[] edList = {ed_1, ed_2, ed_3};
     CustomTextWatcher textWatcher = new CustomTextWatcher(edList, btn_ok);
     for (EditText editText : edList) editText.addTextChangedListener(textWatcher);

    }
}

এটা এখন খুব সহজ দেখাচ্ছে

CustomTextWatcher.class

public class CustomTextWatcher implements TextWatcher {

View v;
EditText[] edList;

public CustomTextWatcher(EditText[] edList, Button v) {
    this.v = v;
    this.edList = edList;
}

@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}

@Override
public void afterTextChanged(Editable s) {
    for (EditText editText : edList) {
        if (editText.getText().toString().trim().length() <= 0) {
            v.setEnabled(false);
            break;
        }
        else v.setEnabled(true);
    }
  }
}

আমি একটি বিন্যাস যুক্ত করব, যাতে আপনি সময় নষ্ট করবেন না

multi_edit_text.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">

<EditText
    android:id="@+id/ed_1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="8dp" />

<EditText
    android:id="@+id/ed_2"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/ed_1"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="8dp" />

<EditText
    android:id="@+id/ed_3"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/ed_2"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="8dp" />

<Button
    android:id="@+id/btn_ok"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/ed_3"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="8dp"
    android:text="OK" />
</RelativeLayout>

5

আপনার শ্রেণিটি ক্রিয়াকলাপ থেকে উত্তরাধিকারী হোন এবং পাঠ্য ওয়াচচার প্রয়োগ করুন।

তারপরে পলিমারফিজমের যাদুটির মাধ্যমে আপনাকে কেবল ইভেন্টগুলিতে সাবস্ক্রাইব করতে হবে।

এটি আপনাকে টেক্সটএডিট কী পরিবর্তন করেছে তা বলবে না, তবে এটি এবং স্কাই কেলসির উত্তরটির সংমিশ্রণটি ব্যবহার করে আপনি এটিকে সুন্দরভাবে সাজিয়ে ফেলতে পারেন।

public YourActivity extends Activity implements TextWatcher {

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

        //Subscribe to the events
        EditText txt1 = (EditText) findViewById(R.id.txt1);
        txt1.addTextChangedListener(this);

        EditText txt2 = (EditText) findViewById(R.id.txt2);
        txt2.addTextChangedListener(this);
    }

        @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

            EditText txt1 = (EditText) findViewById(R.id.txt1);
            EditText txt2 = (EditText) findViewById(R.id.txt2);
            // You probably only want the text value from the EditText. But you get the idea. 
                doStuff(txt1,txt2);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.calc, menu);
        return true;
    }

    @Override
    public void afterTextChanged(Editable s) {
        // TODO Auto-generated method stub
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        // TODO Auto-generated method stub
    }
}

3
TextWatcher watcher = new TextWatcher(){

    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
    }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
    }

    @Override
    public void afterTextChanged(Editable editable) {
    }
};

তারপর:

editText1.addTextChangedListener(watcher);
editText2.addTextChangedListener(watcher);
editText3.addTextChangedListener(watcher);

2
(ঝকঝকে পোস্টের সতর্কতা) সমস্ত কন্ট্রোলের জন্য তার সম্ভবত খুব অনুরূপ বৈধতা কোড রয়েছে এবং এটি 3 বার অনুলিপি করে আটকানোতে চায় না :) আমি এর আগে এটি হিট করেছি, তারা কেন ক্লিকটি ক্লিক করতে পারে যে ক্লিকটি লিঙ্কস্টারে ক্লিক করেছে এবং না টেক্সটওয়াচারের মতো জিনিসের উপর ... আমি কেবলমাত্র কাজটিই ভাবতে পারি যে 3 টি টেক্সট ওয়াচারস তৈরি করতে পারে যা একই পদ্ধতিটিকে কল করে তবে তাদের সম্পাদনা নিয়ন্ত্রণগুলিতে পয়েন্টার সহ।
টর্প

1
@Torp, @bie এই উত্তর আগ্রহের হতে পারে: stackoverflow.com/questions/4283062/... না নিশ্চিত এটা ঠিক এখানে সমস্যা বিবৃত solves, কিন্তু করা হয়, অর্থাত্ আপনি CustomTextWatcher আপনা থেকেই অন্য একটি ফাংশন যা লাগে কল হতে পারে সম্পাদনযোগ্য পাস।
কেভিন কপক

3
public class MainActivity extends AppCompatActivity{
    EditText value1, value2;

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

        //instantiate EditText controls
        value1 = (EditText)findViewById(R.id.txtValue1);
        value2 = (EditText)findViewById(R.id.txtValue2);

        //set up text changed listener
        value1.addTextChangedListener(new TextChange(value1));               
        value2.addTextChangedListener(new TextChange(value2));                       

        //inner class
        private class TextChange implements TextWatcher {

             View view;
             private TextChange (View v) {
                 view = v;
             }

             @Override
             public void beforeTextChanged(CharSequence s, int start, int count, int after) {

             }


             @Override
             public void onTextChanged(CharSequence s, int start, int before, int count) {

                 switch (view.getId()) {
                     case R.id.txtValue1:
                         //insert your TextChangedListener codes here
                         break;

                     case R.id.txtValue2:
                         //insert your TextChangedListener codes here
                         break;
                 }
             }   
         }
     }
}

3

কোটলিনের জন্য এটি আমার সমাধান। একই জিনিসটি পরীক্ষা করতে আপনি কেবল রেফারেনশিয়াল সমতা (===) ব্যবহার করতে পারেন এবং এটি পুরোপুরি কাজ করছে।

val mTextWatcher = object : TextWatcher {
        override fun afterTextChanged(et: Editable?) {

            when {
                et === et1.editableText -> {
                    Toast.makeText(this@MainActivity, "EditText 1", Toast.LENGTH_LONG).show()
                }
                et === et2.editableText -> {
                    Toast.makeText(this@MainActivity, "EditText 2", Toast.LENGTH_LONG).show()
                }

            }
        }

        override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
        }
        override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
        }
    }
    et1.addTextChangedListener(mTextWatcher)
    et2.addTextChangedListener(mTextWatcher)

0

আমি জানি এই প্রশ্নটি পুরানো, তবে আমি আমার একটি সমাধান (কোটলিনে) ভাগ করতে চেয়েছি। আমার সমাধানটি @ শোয়ার্জ আন্দ্রেয়ের উত্তরের একটি উন্নতি, আপনি যদি বেশি জিনিস / বস্তু চালিত করতে চান তবে আমার কারণটি ছিল।

উভয় list of EditTextsএবং a Buttonপ্যারাম হিসাবে পাস করার পরিবর্তে , আপনি কেবল আপনার পাস করতে চাই list of editText। তারপরে আপনার কাস্টম শ্রেণীর মধ্যে আপনি একটি ল্যাম্বডা প্রয়োগ করবেন:

var hasFilled:((Boolean)->Unit)? = null 

তারপরে আপনি এটিটি সেট আপ বা এর ভিতরে বাড়িয়ে তুলবেন afterTextChanged

override fun afterTextChanged(p0: Editable?) {
       for (edit in _editTextList) {
           if (edit?.text.toString().trim().isEmpty()) {
                 hasFilled?.invoke(false) //<-- here 
               break
           } else {
               hasFilled?.invoke(true) //<--- here 
           }
       }
   }

তাই প্রতিবার, কিছু এডিটেক্সট-এ পরিবর্তন হয় আপনার ল্যাম্বদা ডাকে

        val editTexts = listOf(emailEditText,passwordEditText) // your list of editText
        val textWatcher = customTextWatcher(editTexts) // initialize your custom object 
        editTexts.forEach { it -> it?.addTextChangedListener(textWatcher) } // each editText would listen for changes 


        textWatcher.hasFilled = { value ->  // now you have access to your lambda 
            if (value != true)  {
               // change the state of the button to unable 
              // do other things 
            } else {
              // change the state of the button to enable 
              // do other things 
            }
        }

0

আমি এটি কীভাবে করেছি তা এখানে:

এডিটেক্সটসের একটি অ্যারেলিস্ট তৈরি করুন এবং তারপরে সমস্ত এডিটেক্সটসের জন্য টেক্সটওয়াটার প্রয়োগ করার জন্য লুপের জন্য ব্যবহার করুন, যদি সমস্ত সম্পাদনাটেক্সটগুলির জন্য আপনার একটি আচরণ থাকে তবে কেবল এটি সেখানে প্রয়োগ করুন, যদি আপনি কিছু নির্দিষ্ট সম্পাদনাটেক্সটের জন্য নির্দিষ্ট আচরণ করে থাকেন তবে আপনি যদি একটি ব্যবহার করতে পারেন তবে পৃথক editTexts নির্বাচন এবং প্রয়োগ করতে বিবৃতি।

আমার কোডটি এখানে:

ArrayList<EditText> editTexts = new ArrayList<>(); // Container list

editText1 = (EditText) findViewById(R.id.editText1);
editText2 = (EditText) findViewById(R.id.editText2);
editText3 = (EditText) findViewById(R.id.editText3);

editTexts.add(editText1); // editTexts[0]
editTexts.add(editText2); // editTexts[1]
editTexts.add(editText3); // editTexts[2]

for (final EditText editText : editTexts) { //need to be final for custom behaviors 
    editText.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            //Apply general behavior for all editTexts

            if (editText == editTexts.get(1)) {
                //Apply custom behavior just for this editText                           
            }
        }
    });

}

আশাকরি এটা সাহায্য করবে


উত্তরের জন্য ধন্যবাদ, তবে এটি কি এটি করার একমাত্র উপায়? আমি বোঝাতে চাইছি এটি সম্পাদনা onTextChangedপাঠ্যসূচীর মতো সাধারণ কোনও কিছুর জন্য একরকম জটিল বলে মনে হচ্ছে । onFocusChangeএকাধিক উইজেটের জন্য একটি যুক্ত করা অনেক সহজ, কারণ এটি পদ্ধতি কলটির সাথে প্রেরককে পাস করেছে। তারপরে আপনি পরীক্ষা করতে পারবেন কোন বস্তু কলটি ট্রিগার করেছে এবং সেখান থেকে এটি পরিচালনা করতে পারে।
বিডিআর
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.