এডিটেক্সট এর বাইরে ক্লিক করার পরে অ্যান্ড্রয়েডে সফ্ট কীবোর্ড কীভাবে আড়াল করবেন?


354

ঠিক আছে সকলেই জানেন যে একটি কীবোর্ড লুকানোর জন্য আপনার প্রয়োগ করা দরকার:

InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);

তবে এখানে বড় কথা হ'ল ব্যবহারকারী কীওয়ার্ডটি কীভাবে আড়াল করবেন যখন ব্যবহারকারী কোনও EditTextবা সফট কীবোর্ড নয় এমন কোনও অন্য জায়গা স্পর্শ করে বা নির্বাচন করে?

আমি onTouchEvent()এটি আমার পিতামাতাকে ব্যবহার করার চেষ্টা করেছি Activityতবে এটি কেবল তখনই কার্যকর হয় যখন ব্যবহারকারী যদি অন্য কোনও দৃশ্যের বাইরে যায় এবং কোনও স্ক্রোলভিউ না থাকে।

আমি কোনও সাফল্য ছাড়াই একটি স্পর্শ, ক্লিক, ফোকাস শ্রোতার বাস্তবায়ন করার চেষ্টা করেছি।

এমনকি আমি আমার নিজের স্ক্রোলভিউ বাস্তবায়নের জন্য স্পর্শ ইভেন্টগুলিকে আটকাতে চেষ্টা করেছি তবে আমি কেবল ইভেন্টটির স্থানাঙ্কগুলি পেতে পারি এবং ভিউ ক্লিক করা হয়নি।

এটি করার কোনও মানক উপায় আছে ?? আইফোনে এটি সত্যিই সহজ ছিল।


আমি বুঝতে পেরেছিলাম যে স্ক্রোলভিউটি আসলে সমস্যা ছিল না, তবে যে লেবেলগুলি রয়েছে। দর্শন হিসাবে কিছু একটি উল্লম্ব বিন্যাস হল: TextView, editText, TextView, editText, ইত্যাদি .. এবং textViews আলগা ফোকাস করতে editText দেওয়া হবে না এবং লুকান কীবোর্ড
htafoya

আপনি getFields()এখানে এর জন্য সমাধান খুঁজে পেতে পারেন : stackoverflow.com/questions/7790487/…
রেটো

রিটার্ন বোতাম টিপে
কীবোর্ডটি

4
আমি এই উত্তরটি পেয়েছি: stackoverflow.com/a/28939113/2610855 সেরাটি
লেনিক্স

উত্তর:


575

নিম্নলিখিত স্নিপেটটি কেবল কীবোর্ডটি আড়াল করে:

public static void hideSoftKeyboard(Activity activity) {
    InputMethodManager inputMethodManager = 
        (InputMethodManager) activity.getSystemService(
            Activity.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(
        activity.getCurrentFocus().getWindowToken(), 0);
}

আপনি এটি কোনও ইউটিলিটি ক্লাসে রাখতে পারেন, বা যদি আপনি কোনও ক্রিয়াকলাপের মধ্যে এটি সংজ্ঞায়িত করে থাকেন তবে ক্রিয়াকলাপের পরামিতি এড়িয়ে চলুন বা কল করুন hideSoftKeyboard(this)

সবচেয়ে জটিল অংশটি কখন এটি কল করা উচিত। আপনি Viewআপনার ক্রিয়াকলাপের প্রত্যেকটির মধ্য দিয়ে পুনরাবৃত্তি হওয়া একটি পদ্ধতি লিখতে পারেন এবং এটি instanceof EditTextযদি setOnTouchListenerসেই উপাদানটিতে একটি নিবন্ধীকৃত না হয় এবং এটি সমস্ত কিছু ঠিক জায়গায় পড়ে যায় তবে তা পরীক্ষা করে দেখুন । আপনি যদি এটি কীভাবে করবেন তা ভাবছেন তবে এটি আসলে খুব সহজ। আপনি যা করেন তা এখানে, আপনি নিম্নলিখিতগুলির মতো একটি পুনরাবৃত্ত পদ্ধতি লিখেন, বাস্তবে আপনি এটি কিছু করতে যেমন ব্যবহার করতে পারেন যেমন কাস্টম টাইপফেস সেটআপ করা ইত্যাদি ... পদ্ধতিটি এখানে

public void setupUI(View view) {

    // Set up touch listener for non-text box views to hide keyboard.
    if (!(view instanceof EditText)) {
        view.setOnTouchListener(new OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                hideSoftKeyboard(MyActivity.this);
                return false;
            }
        });
    }

    //If a layout container, iterate over children and seed recursion.
    if (view instanceof ViewGroup) {
        for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
            View innerView = ((ViewGroup) view).getChildAt(i);
            setupUI(innerView);
        }
    }
}

এগুলি হ'ল, setContentViewআপনার ক্রিয়াকলাপের পরে এই পদ্ধতিটি কল করুন। আপনি যদি ভাবছেন যে আপনি কোন প্যারামিটারটি পাস করবেন, এটি idপ্যারেন্ট পাত্রে। idআপনার প্যারেন্ট পাত্রে যেমন একটি বরাদ্দ করুন

<RelativeLayoutPanel android:id="@+id/parent"> ... </RelativeLayout>

এবং কল setupUI(findViewById(R.id.parent)), এটাই।

আপনি যদি এটি কার্যকরভাবে ব্যবহার করতে চান তবে আপনি একটি প্রসারিত তৈরি করতে পারেন Activityএবং এই পদ্ধতিটি রেখে দিতে পারেন এবং আপনার অ্যাপ্লিকেশনটিতে থাকা সমস্ত অন্যান্য ক্রিয়াকলাপটি এই ক্রিয়াকলাপটি প্রসারিত করতে এবং পদ্ধতিতে কল setupUI()করতে পারেন onCreate()

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

আপনি যদি 1 টির বেশি ক্রিয়াকলাপ ব্যবহার করেন তবে সাধারণ আইডিটিকে প্যারেন্ট লেআউটে পছন্দ করে <RelativeLayout android:id="@+id/main_parent"> ... </RelativeLayout>

তারপরে একটি শ্রেণি প্রসারিত করুন Activityএবং এর setupUI(findViewById(R.id.main_parent))মধ্যে সংজ্ঞা দিন OnResume()এবং class tivity ক্রিয়াকলাপের পরিবর্তে এই শ্রেণিটি প্রসারিত করুনin your program


এখানে উপরের ফাংশনের একটি কোটলিন সংস্করণ রয়েছে:

@file:JvmName("KeyboardUtils")

fun Activity.hideSoftKeyboard() {
    currentFocus?.let {
        val inputMethodManager = ContextCompat.getSystemService(this, InputMethodManager::class.java)!!
        inputMethodManager.hideSoftInputFromWindow(it.windowToken, 0)
    }
}

আমি নিজে পরীক্ষা করে দেখিনি তবে দেখে মনে হচ্ছে এটি কাজ করবে এবং এর উচ্চ পর্যালোচনা থাকায় আমি এর গ্রহণযোগ্য উত্তর পরিবর্তন করব।
htafoya

4
খুব শক্ত হওয়া উচিত নয়? আমি এখনই অ্যান্ড্রয়েড প্রোগ্রামিংয়ের বাইরে আছি, তাই আমি ভুল হলে আমাকে সংশোধন করুন। আপনি যে কোনও মুহুর্তে কেন্দ্রীভূত সম্পাদনা পাঠ্য ট্র্যাক করতে পারেন এবং অনটচ এভেন্টের সময় এটি ফোকাসটি হারাতে অনুরোধ করেছেন?
নবনিথ জি

25
এই সমস্যাটি নিয়ে অন্য কেউ চালিত হয়েছে কিনা তা নিশ্চিত নন তবে আপনি যদি কিছু কেন্দ্রীভূত না করেন তবে হাইডসফটকিবোর্ডে কল করলে অ্যাপটি ক্রাশ হয়ে যায়। আপনি পদ্ধতির দ্বিতীয় লাইনটি ঘিরে এটি সমাধান করতে পারেনif(activity.getCurrentFocus() != null) {...}
ফ্রাঙ্ক ক্যাঙ্গিয়ালসি

14
এই পদ্ধতির সাথে সমস্যাটি হ'ল এটি ধরে নেওয়া হয় যে অন্য সমস্ত মতামত কখনও সেট করার দরকার হয় না OnTouchListener জন্য তাদের জন্য নেই। আপনি কেবলমাত্র সেই যুক্তিকে ViewGroup.onInterceptTouchEvent(MotionEvent)একটি মূল দর্শনে সেট করতে পারেন।
অ্যালেক্স.এফ

2
আমি কীবোর্ডটি উন্মুক্ত রেখে অন্যান্য নিয়ন্ত্রণগুলিতে ক্লিক করি না তখন কাজ করছে না
মহিমান

285

আপনি নিম্নলিখিত পদক্ষেপগুলি দ্বারা এটি অর্জন করতে পারেন:

  1. নিম্নলিখিত বৈশিষ্ট্যগুলি যুক্ত করে প্যারেন্ট ভিউটিকে (আপনার ক্রিয়াকলাপের সামগ্রী দর্শন) ক্লিকযোগ্য এবং ফোকাসযোগ্য করে তুলুন

        android:clickable="true" 
        android:focusableInTouchMode="true" 
  2. একটি হাইডকি-বোর্ড () পদ্ধতি প্রয়োগ করুন

        public void hideKeyboard(View view) {
            InputMethodManager inputMethodManager =(InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
        }
  3. শেষ অবধি, আপনার সম্পাদনাটির ফোকাস চ্যাঞ্জলিস্টনার সেট করুন।

        edittext.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (!hasFocus) {
                    hideKeyboard(v);
                }
            }
        });

নীচের মতামতগুলির একটিতে উল্লিখিত হিসাবে, পিতামাতার দৃষ্টিভঙ্গি যদি একটি স্ক্রোলভিউ হয় তবে এটি কাজ করতে পারে না। যেমন ক্ষেত্রে, ক্লিকযোগ্য এবং ফোকাসযোগ্য ইনটচমড সরাসরি স্ক্রোলভিউয়ের অধীনে ভিউতে যুক্ত করা যেতে পারে।


67
আমার মতে এটি সঠিক উত্তর। কম কোড, অহেতুক পুনরাবৃত্তি নেই ...
gattshjoty

14
আমি এই উত্তরটি অনেক পছন্দ করি। একটি বিষয় লক্ষণীয় যে এটি যুক্ত করার সময় clickableএবং focusableInTouchModeআমার মূল ScrollViewউপাদানটিতে আমার পক্ষে কাজ করে না । আমার প্রত্যক্ষ পিতামাতার সাথে আমাকে যুক্ত করতে EditTextহয়েছিল যা ছিল a LinearLayout
অ্যাডাম জনস

10
আমার জন্য নিখুঁতভাবে কাজ করেছেন। যদিও আপনার কাছে দুটি এডিটেক্সট উইজেট রয়েছে, আপনার অবশ্যই এটি নিশ্চিত করা দরকার যে আপনি উভয়কেই অনফোকাস সঠিকভাবে পরিচালনা করেছেন অন্যথায় আপনি অকারণে কীবোর্ডটি লুকিয়ে রাখবেন।
মার্কা এ

1
@ মারকাএ আমাকে এ নিয়ে কোনও সমস্যায় পড়েনি, যখন আমি অন্য সম্পাদনা পাঠ্য ক্লিক করি, কীবোর্ড স্থির থাকে, যদি ব্যাকগ্রাউন্ডে ক্লিক করা হয় তবে এটির মতো লুকিয়ে থাকে। আমি ফোকাস চ্যাঞ্জে অন্য কিছু পরিচালনা করেছি, ঠিক তখনই এডিটেক্সট এর ব্যাকগ্রাউন্ড পরিবর্তন করা হচ্ছে যখন এতে ফোকাস হবে, কিছুই ফেন্সি নেই।
কুলারবাইটস

3
@ শ্রীকান্ত - একাধিক সম্পাদনা পাঠের সাথে আমিও ঝাঁকুনি দেখছিলাম। আমি প্রতিটি সম্পাদনা পাঠ্যের পরিবর্তে পিতা-মাতার উপর ফোকাস চ্যাঞ্জলিস্টনার সেট করেছি এবং শর্তটি পরিবর্তন করেছি যদি (hasFocus) {hideKeyboard (v); B বিটিডব্লিউএন সম্পাদনা পাঠ্যগুলিতে স্যুইচিংয়ে আরও ঝাঁকুনি খেয়াল নেই।
মনীষা

69

ক্রিয়াকলাপে কোডের নীচে কেবল ওভাররাইড করুন

 @Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    if (getCurrentFocus() != null) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
    }
    return super.dispatchTouchEvent(ev);
}

4
সহজ সমাধান, ক্রিয়াকলাপে যুক্ত করুন এবং এটি
রোহিত মৌর্য

1
আরেকটি সমাধান হ'ল বেসঅ্যাক্টিভিটি তৈরি করা এবং এটি সমস্ত ক্রিয়াকলাপে এটি প্রসারিত করা
সিমিট সোনাওয়ানে

1
জমকালো সমাধান
আহমেদ আদেল ইসমাইল

1
কীবোর্ড বন্ধ করার সময় আপনি আমার পর্দা ঝাঁকুনি থেকে বাঁচিয়েছেন। থাম্বস আপ!
দিমাস মেন্ডেস

1
খুব ভাল, তবে এটি সত্য হওয়া খুব ভাল ছিল: সরল, খুব ছোট, এবং এটি কাজ করেছিল ... হায়, সমস্যা আছে: কীবোর্ড প্রদর্শিত হয়, প্রতিবার আমরা যখন সম্পাদনা পাঠ্য কীবোর্ডকে জিজ্ঞাসা করি তখন এটি নীচে যায় এবং স্বয়ংক্রিয়ভাবে আপ।
ক্রিসোট্রিব্যাক্স

60

আমি গ্রহণযোগ্য উত্তরটি কিছুটা জটিল বলে মনে করি।

এখানে আমার সমাধান। OnTouchListenerআপনার মূল বিন্যাসে একটি যুক্ত করুন , যেমন:

findViewById(R.id.mainLayout).setOnTouchListener(this)

এবং অন টাচ পদ্ধতিতে নিম্নলিখিত কোডটি রাখুন।

InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);

এইভাবে আপনাকে সমস্ত দর্শন থেকে পুনরাবৃত্তি করতে হবে না।


@ রাইপিট - একটি ভিউতে একটি লেআউট কাস্ট করার চেষ্টা করার জন্য আমি ক্লাসকাস্টেক্সসেপশন পাচ্ছি। আমি কিছু অনুপস্থিত করছি?
katzenhut

আপনি আপনার কোড কোথাও রেফারেন্স করতে পারেন? আমি যখন আপনার লেআউট এবং ক্রিয়াকলাপ / টুকরা এবং সেটার কোডটি দেখতে না পারি তখন আমি কী ভুল তা বলতে পারি না।
রোপিত

সেখানে সেরা উত্তর, এখনও আমার মাথা এটি কীভাবে কাজ করে তা মোড়ানোর চেষ্টা করে।
ব্যবহারকারী 40797

আপনি যদি অ্যাপটির শিরোনাম বারটি ক্লিক করেন তবে এটি কাজ করবে?
ব্যবহারকারী1506104

1
এটি কীবোর্ডটি লুকানোর জন্য পুরোপুরি কাজ করে! নোট করুন যে এটি আসলে সম্পাদনা পাঠ্য ফোকাস করে না, এটি কেবল কীবোর্ডটি আড়াল করে। সম্পাদনা পাঠ্যকে ফোকাস করতে, উদ্বোধনী android:onClick="stealFocusFromEditTexts"ভিউ এর এক্সএমএল এবং public void stealFocusFromEditTexts(View view) {}তার ক্রিয়াকলাপে উদাহরণ যুক্ত করুন । অন-ক্লিক পদ্ধতিতে কিছু করার দরকার নেই, কেবলমাত্র পিতামাতার দৃষ্টিভঙ্গিটিকে দৃষ্টি নিবদ্ধযোগ্য / নির্বাচনযোগ্য করার জন্য এটির উপস্থিতি থাকতে হবে, যা শিশু থেকে ফোকাস চুরি করার জন্য প্রয়োজনীয়
জ্যাকব আর

40

কীবোর্ডটি আড়াল করার জন্য আমি আরও একটি সমাধান পেয়েছি:

InputMethodManager imm = (InputMethodManager) getSystemService(
    Activity.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);

এখানে পাস HIDE_IMPLICIT_ONLYএর অবস্থানে showFlagএবং 0এর অবস্থানে hiddenFlag। এটি শক্তভাবে নরম কীবোর্ডটি বন্ধ করবে close


3
ধন্যবাদ এটির কাজ ..... সর্বোপরি আমি চেষ্টা করেছিলাম কিন্তু ডায়লগবক্স এডিটেক্সট পাঠ্য এনডি ক্লোসিং ডায়ালগবক্স থেকে মূল্য পাওয়ার সময় এটি কাজ করছে না ...
পঙ্কজঅ্যান্ড্রয়েড

ধন্যবাদ, এটি কেবলমাত্র কাজ করছে, এবং এটি ওপরের অন্যটি থেকে আরও পরিষ্কার পরিচ্ছন্ন! +1
এডমন্ড তমাস

এটা কাজ করছে হিসাবে প্রত্যাশিত, আপনার সমাধান +1 টি করার জন্য আপনাকে ধন্যবাদ
tryp

আমার জন্য একটি যাদুমন্ত্র মত কাজ করে। মার্জিত সমাধানের জন্য +1।
সন্তজব

2
দুঃখিত, তবে এই পদ্ধতিটি টগল, সুতরাং যদি কীবোর্ডের
স্টেটটি

16

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

 /**
 * Called to process touch screen events. 
 */
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {

    switch (ev.getAction()){
        case MotionEvent.ACTION_DOWN:
            touchDownTime = SystemClock.elapsedRealtime();
            break;

        case MotionEvent.ACTION_UP:
            //to avoid drag events
            if (SystemClock.elapsedRealtime() - touchDownTime <= 150){  

                EditText[] textFields = this.getFields();
                if(textFields != null && textFields.length > 0){

                    boolean clickIsOutsideEditTexts = true;

                    for(EditText field : textFields){
                        if(isPointInsideView(ev.getRawX(), ev.getRawY(), field)){
                            clickIsOutsideEditTexts = false;
                            break;
                        }
                    }

                    if(clickIsOutsideEditTexts){
                        this.hideSoftKeyboard();
                    }               
                } else {
                    this.hideSoftKeyboard();
                }
            }
            break;
    }

    return super.dispatchTouchEvent(ev);
}

সম্পাদনা: গেটফিল্ডস () পদ্ধতিটি কেবলমাত্র এমন একটি পদ্ধতি যা ভিউতে পাঠ্যক্ষেত্রের সাথে অ্যারে প্রদান করে। প্রতিটি স্পর্শে এই অ্যারে তৈরি এড়াতে, আমি এসফিল্ডস নামে একটি স্ট্যাটিক অ্যারে তৈরি করেছি, যা গেটফিল্ডস () পদ্ধতিতে ফিরে আসে। এই অ্যারেটি অন স্টার্ট () পদ্ধতিগুলিতে যেমন আরম্ভ করা হয়:

sFields = new EditText[] {mUserField, mPasswordField};


এটি নিখুঁত নয়, ড্র্যাগ ইভেন্টের সময়টি কেবলমাত্র হিউরিস্টিকের উপর ভিত্তি করে তাই কখনও কখনও দীর্ঘ ক্লিকগুলি সম্পাদন করার সময় এটি লুকিয়ে রাখে না এবং আমি প্রতি ভিউতে সমস্ত সম্পাদনাপত্রগুলি পাওয়ার জন্য একটি পদ্ধতি তৈরি করেও শেষ করেছি; অন্যথায় অন্যান্য সম্পাদনা পাঠ্য ক্লিক করার সময় কীবোর্ডটি লুকিয়ে দেখাবে।

তবুও, ক্লিনার এবং সংক্ষিপ্ত সমাধানগুলি স্বাগত


8
ভবিষ্যতে অন্যদের সহায়তা করার জন্য, আপনি কি আপনার getFields()পদ্ধতিতে অন্তর্ভুক্ত করার জন্য কোডটির উত্তরটি সম্পাদনা করার কথা বিবেচনা করবেন ? এটি সঠিক হতে হবে না, কেবলমাত্র কিছু মন্তব্য সহ এটি উদাহরণস্বরূপ যে এটি EditTextবস্তুর একটি অ্যারে প্রদান করে।
স্কোঙ্ক

14

অনফোকাস চ্যাঞ্জলিস্টনার ব্যবহার করুন

উদাহরণ স্বরূপ:

editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (!hasFocus) {
            hideKeyboard();
        }
    }
});

আপডেট : আপনি onTouchEvent()আপনার ক্রিয়াকলাপকে ওভাররাইড করতে এবং স্পর্শের স্থানাঙ্কগুলিও পরীক্ষা করতে পারেন । স্থানাঙ্কগুলি সম্পাদনা পাঠের বাইরে থাকলে কী-বোর্ডটি আড়াল করুন।


9
সমস্যাটি হ'ল আমি যখন কোনও লেবেল বা অন্য দৃষ্টিভঙ্গিগুলিতে ফোকাসযোগ্য নয় এমন ক্লিক করি তখন সম্পাদনাটি ফোকাসটি আলগা করে না।
htafoya

এক্ষেত্রে আমার আরও একটি সমাধান রয়েছে। আমি উত্তর আপডেট করেছি।
সের্গেই গ্লোটোভ

2
onTouchEvent অনেকবার কল করা হয়েছে তাই এটিও একটি ভাল অনুশীলন নয়
যিশু ডিম্রিক্স

13

আমি এটি করার জন্য ক্রিয়াকলাপে ডিসপ্যাচটচ এভেন্ট বাস্তবায়ন করেছি:

private EditText mEditText;
private Rect mRect = new Rect();
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    final int action = MotionEventCompat.getActionMasked(ev);

    int[] location = new int[2];
    mEditText.getLocationOnScreen(location);
    mRect.left = location[0];
    mRect.top = location[1];
    mRect.right = location[0] + mEditText.getWidth();
    mRect.bottom = location[1] + mEditText.getHeight();

    int x = (int) ev.getX();
    int y = (int) ev.getY();

    if (action == MotionEvent.ACTION_DOWN && !mRect.contains(x, y)) {
        InputMethodManager input = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        input.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
    }
    return super.dispatchTouchEvent(ev);
}

এবং আমি এটি পরীক্ষা, নিখুঁত কাজ করে!


কাজ করে, তবে এতে সমস্যাটি হ'ল আমাদের যদি একাধিক এডিটেক্সট থাকে তবে আমাদের এটিও বিবেচনা করা দরকার তবে আমি আপনার উত্তরটি পছন্দ করেছি :-)
ললিত পপতানি

getActionMasked (ev) অবমূল্যায়ন করা হয়েছে, সুতরাং এখন ব্যবহার করুন: ফাইনাল ইন অ্যাকশন = ev.getActionMasked (); প্রথম লাইনের জন্য
অ্যান্ড্রু

12

আরো Kotlin & মেটারিয়াল ডিজাইন পথ ব্যবহার TextInputEditText (এই পদ্ধতির সঙ্গে এছাড়াও সামঞ্জস্যপূর্ণ EditTextView ) ...

1. নিম্নলিখিত বৈশিষ্ট্যগুলি যুক্ত করে প্যারেন্ট ভিউ (আপনার ক্রিয়াকলাপ / অংশবিশেষের সামগ্রীর দর্শন) ক্লিকযোগ্য এবং ফোকাসযোগ্য করুন

android:focusable="true"
android:focusableInTouchMode="true"
android:clickable="true"

২. সমস্ত দর্শনর জন্য একটি এক্সটেনশন তৈরি করুন (উদাহরণস্বরূপ একটি ভিউ এক্সটেনশন.কিটি ফাইলের অভ্যন্তরে):

fun View.hideKeyboard(){
    val inputMethodManager = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
    inputMethodManager.hideSoftInputFromWindow(this.windowToken, 0)
}

৩. একটি বেসটেক্সট ইনপুট এডিটটেক্সট তৈরি করুন যা টেক্সটইনপুট এডিটটেক্সটের উত্তরাধিকার সূত্রে প্রাপ্ত। ভিউটি ফোকাস না করা অবস্থায় কীবোর্ডটি লুকানোর জন্য ফোকাসচ্যাঞ্জড পদ্ধতিটি প্রয়োগ করুন:

class BaseTextInputEditText(context: Context?, attrs: AttributeSet?) : TextInputEditText(context, attrs){
    override fun onFocusChanged(focused: Boolean, direction: Int, previouslyFocusedRect: Rect?) {
        super.onFocusChanged(focused, direction, previouslyFocusedRect)
        if (!focused) this.hideKeyboard()
    }
}

4. মাত্র আপনার এক্সএমএলে আপনার ব্র্যান্ডের নতুন কাস্টম ভিউটিতে কল করুন:

<android.support.design.widget.TextInputLayout
        android:id="@+id/textInputLayout"
        ...>

        <com.your_package.BaseTextInputEditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            ... />

    </android.support.design.widget.TextInputLayout> 

এখানেই শেষ. এই পুনরাবৃত্তিযোগ্য কেসটি পরিচালনা করতে আপনার নিয়ন্ত্রণকারীদের (টুকরা বা ক্রিয়াকলাপ) পরিবর্তন করার দরকার নেই


হ্যাঁ ভাল তবে আমার ইচ্ছা ছিল আরও সহজ উপায় ছিল!
দেবডিজেয়

11

যে কোনও ক্রিয়াকলাপে (বা ক্রিয়াকলাপের শ্রেণি প্রসারিত) সর্বজনীন বুলিয়ান প্রেরণা টাচইভেন্ট (মোশনইভেন্ট ইভেন্ট) ওভাররাইড করুন

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
    View view = getCurrentFocus();
    boolean ret = super.dispatchTouchEvent(event);

    if (view instanceof EditText) {
        View w = getCurrentFocus();
        int scrcoords[] = new int[2];
        w.getLocationOnScreen(scrcoords);
        float x = event.getRawX() + w.getLeft() - scrcoords[0];
        float y = event.getRawY() + w.getTop() - scrcoords[1];

        if (event.getAction() == MotionEvent.ACTION_UP 
 && (x < w.getLeft() || x >= w.getRight() 
 || y < w.getTop() || y > w.getBottom()) ) { 
            InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(getWindow().getCurrentFocus().getWindowToken(), 0);
        }
    }
 return ret;
}

এবং এটিই আপনার করা দরকার


এটি সবচেয়ে সহজ উপায় যা আমি এটি কাজ করে দেখলাম। একাধিক EditTexts এবং ScrollView সাথে কাজে
RJH

একাধিক এডিটেক্সেটস দিয়ে এটি পরীক্ষা করা হয়েছে; এটা কাজ করে! একমাত্র অসুবিধাটি হ'ল আপনি যখন কোনও টানুন আন্দোলন করেন তখন তাও লুকিয়ে থাকে।
রোমিনাভি 13'16

9

আমি এন্ড্রে লুইস আইএম এর সমাধানটি সংশোধন করেছি:

আমি সফ্ট কীবোর্ডটি গোপন করতে একটি ইউটিলিটি পদ্ধতি তৈরি করেছি ঠিক একইভাবে আন্দ্রে লুইজ আইএম:

public static void hideSoftKeyboard(Activity activity) {
    InputMethodManager inputMethodManager = (InputMethodManager)  activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}

তবে প্রতিটি দৃশ্যের জন্য একটি অনটচলিস্টিনারের নিবন্ধন না করে, যা একটি খারাপ পারফরম্যান্স দেয়, আমি কেবলমাত্র রুট ভিউর জন্য অনটচলিস্টনার নিবন্ধভুক্ত করেছি। যেহেতু ইভেন্টটি এটি গ্রাস না হওয়া অবধি বুদবুদ হয় (এডিটেক্সট এটির একটি ভিউ যা ডিফল্টরূপে এটি গ্রহন করে), এটি যদি রুট ভিউতে পৌঁছে, কারণ এটি গ্রাস করা হয়নি, তাই আমি নরম কীবোর্ডটি বন্ধ করি।

findViewById(android.R.id.content).setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        Utils.hideSoftKeyboard(activity);
        return false;
    }
});

1
এটি আমার কাছে নিরাপদ বলে মনে হচ্ছে।
superarts.org

9

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

আমার সমস্ত ক্রিয়াকলাপের জন্য আমার এই আচরণটি প্রয়োজন, তাই আমি ক্লাস ক্রিয়াকলাপ থেকে উত্তরাধিকারসূত্রে একটি শ্রেণি কাস্টমঅ্যাক্টিভিটি তৈরি করেছি এবং ডিসপ্যাচটুভেন্ট ফাংশনটি "হুক" করেছি " যত্ন নিতে প্রধানত দুটি শর্ত রয়েছে:

  1. যদি ফোকাসটি অপরিবর্তিত থাকে এবং কেউ বর্তমান ইনপুট ক্ষেত্রের বাইরে ট্যাপ করছে তবে আইএমই বরখাস্ত করুন
  2. যদি ফোকাস পরিবর্তন হয়ে যায় এবং পরবর্তী ফোকাসযুক্ত উপাদানটি কোনও ধরণের ইনপুট ক্ষেত্রের উদাহরণ না হয় তবে আইএমই বরখাস্ত করুন

এটি আমার ফলাফল:

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    if(ev.getAction() == MotionEvent.ACTION_UP) {
        final View view = getCurrentFocus();

        if(view != null) {
            final boolean consumed = super.dispatchTouchEvent(ev);

            final View viewTmp = getCurrentFocus();
            final View viewNew = viewTmp != null ? viewTmp : view;

            if(viewNew.equals(view)) {
                final Rect rect = new Rect();
                final int[] coordinates = new int[2];

                view.getLocationOnScreen(coordinates);

                rect.set(coordinates[0], coordinates[1], coordinates[0] + view.getWidth(), coordinates[1] + view.getHeight());

                final int x = (int) ev.getX();
                final int y = (int) ev.getY();

                if(rect.contains(x, y)) {
                    return consumed;
                }
            }
            else if(viewNew instanceof EditText || viewNew instanceof CustomEditText) {
                return consumed;
            }

            final InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);

            inputMethodManager.hideSoftInputFromWindow(viewNew.getWindowToken(), 0);

            viewNew.clearFocus();

            return consumed;
        }
    }       

    return super.dispatchTouchEvent(ev);
}

পার্শ্ব দ্রষ্টব্য: অতিরিক্তভাবে আমি প্রতিটি বৈশিষ্ট্যগুলির ইনপুট ক্ষেত্রে ফোকাস সাফ করা এবং ইনপুট ক্ষেত্রগুলিকে ক্রিয়াকলাপের সূচনায় ফোকাস অর্জনকে প্রতিরোধ করা (সামগ্রীটিকে "ফোকাস ক্যাচার" তৈরি করা) প্রতিরোধ করার জন্য মূল বৈশিষ্ট্যগুলিতে এই বৈশিষ্ট্যগুলি নির্ধারণ করি:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    final View view = findViewById(R.id.content);

    view.setFocusable(true);
    view.setFocusableInTouchMode(true);
}

সুপার তার কাজ সূক্ষ্ম ধন্যবাদ !! আমি আপনার উত্তরের জন্য একটি আপভোট রেখেছি
বিজয়

2
আমি মনে করি এটি জটিল লেআউটের জন্য সেরা সমাধান তবে আমি এখনও অবধি 2 টি অসুবিধাগুলি খুঁজে পেয়েছি: ১। সম্পাদনা পাঠ্য প্রসঙ্গে মেনুটি আপোনাযোগ্য - এটির যে কোনও ক্লিক এডিটেক্সট ২ থেকে ফোকাস হারাতে সক্ষম করে When কীবোর্ডটি দেখানো হয়েছে যে আমাদের "ক্লিক পয়েন্ট" কীবোর্ডে রয়েছে,
এডিট টেক্সটে

@ সোসাইট, আমি মনে করি আমি আমার উত্তরে এই সীমাবদ্ধতাগুলিকে সম্বোধন করেছি; এটা দেখ.
অ্যান্ডি ডেনি

6

আমি dispatchTouchEventhtafoya দ্বারা কল কল করার পদ্ধতির পছন্দ , কিন্তু:

  • আমি টাইমার অংশটি বুঝতে পারি না (কেন জানি না ডাউনটাইম পরিমাপ করা কেন প্রয়োজনীয়?)
  • আমি প্রতিটি ভিউ-চেঞ্জের সাথে সমস্ত সম্পাদনাপত্রগুলি নিবন্ধিত / নিবন্ধভুক্ত করতে পছন্দ করি না (জটিল শ্রেণিবিন্যাসে বেশিরভাগ ভিউ চেঞ্জ এবং এডিটেক্সট হতে পারে)

সুতরাং, আমি এটি কিছুটা সহজ সমাধান করেছি:

@Override
public boolean dispatchTouchEvent(final MotionEvent ev) {
    // all touch events close the keyboard before they are processed except EditText instances.
    // if focus is an EditText we need to check, if the touchevent was inside the focus editTexts
    final View currentFocus = getCurrentFocus();
    if (!(currentFocus instanceof EditText) || !isTouchInsideView(ev, currentFocus)) {
        ((InputMethodManager) getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE))
            .hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
    }
    return super.dispatchTouchEvent(ev);
}

/**
 * determine if the given motionevent is inside the given view.
 * 
 * @param ev
 *            the given view
 * @param currentFocus
 *            the motion event.
 * @return if the given motionevent is inside the given view
 */
private boolean isTouchInsideView(final MotionEvent ev, final View currentFocus) {
    final int[] loc = new int[2];
    currentFocus.getLocationOnScreen(loc);
    return ev.getRawX() > loc[0] && ev.getRawY() > loc[1] && ev.getRawX() < (loc[0] + currentFocus.getWidth())
        && ev.getRawY() < (loc[1] + currentFocus.getHeight());
}

এর একটি অসুবিধা রয়েছে:

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


এই পদ্ধতিটি আমার ফ্র্যাগমেন্টএটিভিটির সাথে কেবল প্লাগ-এন্ড-প্লে করতে সক্ষম হওয়ার ক্ষেত্রে সর্বোত্তম কাজ করেছে।
বিলিআরাইক্রাস

ধন্যবাদ, এটি সেরা উপায়! আমি কেবল ইভেন্ট ক্রিয়াকলাপের জন্য যাচাই করা যুক্ত করেছি: int ক্রিয়া = ev.getActionMasked (); যদি (কর্ম == MotionEvent.ACTION_DOWN || কর্ম == MotionEvent.ACTION_POINTER_DOWN) {...}
sergey.n

ধন্যবাদ! আপনি আমার সময় সাশ্রয় করেছেন ... সর্বোত্তম উত্তর।
I.d007

6

প্লিয়া: আমি বুঝতে পারি আমার কোনও আটকানো নেই, তবে দয়া করে আমার উত্তরটি গুরুত্ব সহকারে নিন।

সমস্যা: কীবোর্ড থেকে দূরে ক্লিক করার সময় নরম কীবোর্ড খারিজ করুন বা ন্যূনতম কোড সহ পাঠ্য সম্পাদনা করুন।

সমাধান: বাহ্যিক গ্রন্থাগার বাটারক্নাইফ নামে পরিচিত

এক লাইন সমাধান:

@OnClick(R.id.activity_signup_layout) public void closeKeyboard() { ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0); }

আরও পঠনযোগ্য সমাধান:

@OnClick(R.id.activity_signup_layout) 
public void closeKeyboard() {
        InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}

ব্যাখ্যা: অনক্লিক শ্রোতাকে ক্রিয়াকলাপের এক্সএমএল লেআউট প্যারেন্ট আইডিটিতে আবদ্ধ করুন, যাতে বিন্যাসে যে কোনও ক্লিক (সম্পাদনা পাঠ্য বা কীবোর্ডে নয়) কোডটির সেই স্নিপেট চালাবে যা কীবোর্ডটি আড়াল করবে।

উদাহরণ: যদি আপনার লেআউট ফাইলটি R.layout.my_layout হয় এবং আপনার লেআউট আইডিটি R.id.my_layout_id হয়, তবে আপনার বাটারনিফ বাইন্ড কলটি দেখতে হবে:

(@OnClick(R.id.my_layout_id) 
public void yourMethod {
    InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}

বাটারকনিফ ডকুমেন্টেশন লিঙ্ক: http://jakewharton.github.io/butterknife/

প্লাগ: বাটারকনিফ আপনার অ্যান্ড্রয়েড বিকাশে বিপ্লব আনবে। এটা বিবেচনা.

দ্রষ্টব্য: বহিরাগত গ্রন্থাগার বাটারকনিফ ব্যবহার না করে একই ফলাফল অর্জন করা যেতে পারে। উপরে বর্ণিত হিসাবে প্যারেন্ট লেআউটে কেবল একটি অনক্লিকলিস্টনার সেট করুন।


দুর্দান্ত, নিখুঁত সমাধান! ধন্যবাদ.
নালফ্লাফাই

6

কোটলিনে, আমরা নিম্নলিখিতটি করতে পারি। সমস্ত দর্শন পুনরাবৃত্তি করার প্রয়োজন নেই। এটি খণ্ডগুলির জন্যও কাজ করবে।

override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
    currentFocus?.let {
        val imm: InputMethodManager = getSystemService(
            Context.INPUT_METHOD_SERVICE
        ) as (InputMethodManager)
        imm.hideSoftInputFromWindow(it.windowToken, 0)
    }
    return super.dispatchTouchEvent(ev)
}


এটি কাজ করে তবে এটিতে একটি বাগ রয়েছে। উদাহরণস্বরূপ, আমি যদি টেক্সটভিউতে পাঠ্য আটকে দিতে চাই, কীবোর্ডটি আড়াল করে তারপরে প্রদর্শিত হবে। এটি কিছুটা বিরক্তিকর।
জর্জ শালভাশভিলি

তাই আমাকে সেরা সমাধানটি বলুন ..
সায়

4

ফেজে-র উত্তরে এখানে আরও একটি পরিবর্তন রয়েছে যা সোসাইটের দ্বারা উত্থাপিত সমস্যাগুলি সম্বোধন করে।

এখানে ধারণাটি হ'ল ক্রিয়াকলাপের dispatchTouchEventপদ্ধতিতে ডাউন এবং আপ উভয়ই পরিচালনা করে । ডাউন ক্রিয়াটিতে, আমরা বর্তমানে ফোকাস করা ভিউ (যদি থাকে) এবং স্পর্শটি এর ভিতরে ছিল কিনা তা নোট করে রাখি, পরে উভয়ের জন্য তথ্যের বিটগুলি সংরক্ষণ করে।

আপ অ্যাকশনটিতে, আমরা প্রথমে প্রেরণ করি, যাতে অন্য একটি ভিউ সম্ভাব্যভাবে ফোকাস নিতে দেয়। যদি এর পরে, বর্তমানে দৃষ্টি নিবদ্ধ করা ভিউটি মূলত ফোকাস করা ভিউ এবং ডাউন ভিউটি সেই ভিউটির ভিতরে ছিল, তবে আমরা কীবোর্ডটি খোলা রাখি।

যদি বর্তমানে ফোকাস করা ভিউটি মূলত ফোকাস করা ভিউ এবং থেকে আলাদা হয় এটি একটি হয় EditTextতবে আমরা কীবোর্ডটিও খোলা রাখি।

অন্যথায় আমরা এটি বন্ধ।

সুতরাং, সংক্ষেপে, এটি নিম্নলিখিত হিসাবে কাজ করে:

  • যখন বর্তমানে একটি ফোকাস ভিতরে ভিতরে স্পর্শ EditText কীবোর্ডটি খোলা থাকে
  • যখন EditTextঅন্য থেকে কেন্দ্রীভূত হয়EditText সময় কীবোর্ডটি খোলা থাকে (বন্ধ হয় না / আবার খোলে না)
  • যখন বর্তমানে কোনও ফোকাসের বাইরে যে কোনও জায়গায় স্পর্শ করা অন্য কোনও EditTextনয়EditText করলে কীবোর্ডটি বন্ধ হয়
  • EditTextপ্রাসঙ্গিক অ্যাকশন বার (কাট / অনুলিপি / পেস্ট বোতামগুলির সাহায্যে) আনার জন্য যখন দীর্ঘক্ষণ টিপুন তখন কীবোর্ডটি খোলা থাকে, যদিও ইউপি ক্রিয়াকলাপের বাইরে ঘটেছিল EditText(যা সিএবির জন্য জায়গা তৈরিতে নিচে সরানো হয়েছিল) । দ্রষ্টব্য, যদিও, আপনি যখন সিএবির একটি বোতামে আলতো চাপুন, এটি কীবোর্ডটি বন্ধ করবে। এটি পছন্দসই বা নাও হতে পারে; আপনি যদি একটি ক্ষেত্র থেকে কাটা / অনুলিপি করতে চান এবং অন্যটিতে আটকান, এটি হবে। আপনি যদি আবার একই পেস্ট করতে চান তবে EditTextতা হবে না।
  • যখন ফোকাসটি EditTextস্ক্রিনের নীচে থাকে এবং আপনি এটি নির্বাচন করতে কিছু পাঠ্যে দীর্ঘ-ক্লিক করেন, EditTextফোকাস রাখে এবং তাই আপনার পছন্দ মতো কীবোর্ডটি খোলে কারণ আমরা "স্পর্শটি দেখার সীমার মধ্যে থাকি" ডাউন ক্রিয়াটি পরীক্ষা করে দেখি না, আপ ক্রিয়া না।

    private View focusedViewOnActionDown;
    private boolean touchWasInsideFocusedView;
    
    
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                focusedViewOnActionDown = getCurrentFocus();
                if (focusedViewOnActionDown != null) {
                    final Rect rect = new Rect();
                    final int[] coordinates = new int[2];
    
                    focusedViewOnActionDown.getLocationOnScreen(coordinates);
    
                    rect.set(coordinates[0], coordinates[1],
                            coordinates[0] + focusedViewOnActionDown.getWidth(),
                            coordinates[1] + focusedViewOnActionDown.getHeight());
    
                    final int x = (int) ev.getX();
                    final int y = (int) ev.getY();
    
                    touchWasInsideFocusedView = rect.contains(x, y);
                }
                break;
    
            case MotionEvent.ACTION_UP:
    
                if (focusedViewOnActionDown != null) {
                    // dispatch to allow new view to (potentially) take focus
                    final boolean consumed = super.dispatchTouchEvent(ev);
    
                    final View currentFocus = getCurrentFocus();
    
                    // if the focus is still on the original view and the touch was inside that view,
                    // leave the keyboard open.  Otherwise, if the focus is now on another view and that view
                    // is an EditText, also leave the keyboard open.
                    if (currentFocus.equals(focusedViewOnActionDown)) {
                        if (touchWasInsideFocusedView) {
                            return consumed;
                        }
                    } else if (currentFocus instanceof EditText) {
                        return consumed;
                    }
    
                    // the touch was outside the originally focused view and not inside another EditText,
                    // so close the keyboard
                    InputMethodManager inputMethodManager =
                            (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                    inputMethodManager.hideSoftInputFromWindow(
                        focusedViewOnActionDown.getWindowToken(), 0);
                    focusedViewOnActionDown.clearFocus();
    
                    return consumed;
                }
                break;
        }
    
        return super.dispatchTouchEvent(ev);
    }

4

এটি খুব সহজ, আপনার সাম্প্রতিক লেআউটটিকে ক্লিকযোগ্যভাবে এই কোডটির দ্বারা মনোযোগ দেওয়ার যোগ্য করুন:

android:id="@+id/loginParentLayout"
android:clickable="true"
android:focusableInTouchMode="true"

এবং তারপরে এই লেআউটের জন্য একটি পদ্ধতি এবং একটি অনক্লিকলিস্টনার লিখুন, যাতে উপরেরতম লেআউটটি স্পর্শ করা হয় যেখানে এটি কোনও পদ্ধতিতে কল করবে যেখানে আপনি কীবোর্ড খারিজ করার জন্য কোড লিখবেন। নিম্নলিখিত উভয় জন্য কোড; // আপনাকে এটি অনক্রিয়েটে লিখতে হবে ()

 yourLayout.setOnClickListener(new View.OnClickListener(){
                @Override
                public void onClick(View view) {
                    hideKeyboard(view);
                }
            });

তালিকার কাছ থেকে আহবান করা পদ্ধতি: -

 public void hideKeyboard(View view) {
     InputMethodManager imm =(InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
    }

4

আমি এই সাধারণ প্রয়োজনের জন্য গৃহীত উত্তর বিট জটিল বলে মনে করি। কোনও ত্রুটি ছাড়াই আমার পক্ষে যা কাজ করেছে তা এখানে।

findViewById(R.id.mainLayout).setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
            return false;
        }
    });

1
আপনি যদি NestedScrollViewজটিল লেআউট ব্যবহার করেন বা গৃহীত উত্তরটি দেখুন: stackoverflow.com/a/11656129/2914140 । আপনার জানা উচিত যে অন্যান্য পাত্রে স্পর্শ গ্রহণ করতে পারে।
কুলমাইন্ড

3

আইফোন একই ইস্যু উপর ভিত্তি করে একটি সহজ পদ্ধতির আছে। স্পর্শ ইভেন্টে ব্যাকগ্রাউন্ডের বিন্যাসটি কেবল ওভাররাইড করুন, যেখানে সম্পাদনা পাঠ্য রয়েছে। ক্রিয়াকলাপের অনক্রিটে এই কোডটি কেবল ব্যবহার করুন (লগইন_ফন্ডো মূল বিন্যাস):

    final LinearLayout llLogin = (LinearLayout)findViewById(R.id.login_fondo);
    llLogin.setOnTouchListener(
            new OnTouchListener()
            {
                @Override
                public boolean onTouch(View view, MotionEvent ev) {
                    InputMethodManager imm = (InputMethodManager) mActivity.getSystemService(
                            android.content.Context.INPUT_METHOD_SERVICE);
                    imm.hideSoftInputFromWindow(mActivity.getCurrentFocus().getWindowToken(), 0);
                    return false;
                }
            });

1
যেমনটি আমি বলেছি এবং আমার মনে আছে, এটি কেবল তখনই কাজ করে যদি ফর্মটি কোনও স্ক্রোলভিউয়ের মধ্যে না থাকে।
htafoya

1
যদি পটভূমিতে অন্য শিশুদের লেআউট থাকে তবে এটি খুব ভাল কাজ করে না।
এক্সেফেক্ট

মনে করিয়ে দেওয়ার জন্য ধন্যবাদ যে অনক্লিক একমাত্র বিকল্প ছিল না।
হরপ্রীত

3

সফট কীবোর্ড প্রদর্শন / লুকানোর জন্য পদ্ধতি

InputMethodManager inputMethodManager = (InputMethodManager) currentActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
    if (isShow) {
        if (currentActivity.getCurrentFocus() == null) {
            inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
        } else {
            inputMethodManager.showSoftInput(currentActivity.getCurrentFocus(), InputMethodManager.SHOW_FORCED);    
        }

    } else {
        if (currentActivity.getCurrentFocus() == null) {
            inputMethodManager.toggleSoftInput(InputMethodManager.HIDE_NOT_ALWAYS, 0);
        } else {
            inputMethodManager.hideSoftInputFromInputMethod(currentActivity.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);    
        }

    }

আমি আশা করি তারা কার্যকর হয়েছে


3

এটি আমার জন্য সবচেয়ে সহজ সমাধান (এবং আমার দ্বারা কাজ করা)।

কীবোর্ডটি আড়াল করার জন্য এই পদ্ধতি।

public void hideKeyboard(View view){
        if(!(view instanceof EditText)){
            InputMethodManager inputMethodManager=(InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),0);
        }
    }

এখন hideKeyboardআপনার এক্সএমএল ফাইলের ডিজাইন ভিউ থেকে বা আপনার এক্সএমএল ফাইলের টেক্সট ভিউতে কোডের নীচে লিখিতভাবে ক্রিয়াকলাপের প্যারেন্ট লেআউটটির অনক্লিক বৈশিষ্ট্যটি উপরের পদ্ধতিতে সেট করুন।

android:onClick="hideKeyboard"

2

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

public static void serachAndHideSoftKeybordFromView(View view, final Activity act) {
    if(!(view instanceof EditText)) {
        view.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                hideSoftKeyboard(act);
                return false;
            }
        });
    }
    if (view instanceof ViewGroup) {
        for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
            View nextViewInHierarchy = ((ViewGroup) view).getChildAt(i);
            serachAndHideSoftKeybordFromView(nextViewInHierarchy, act);
        }
    }
}
public static void hideSoftKeyboard (Activity activity) {
    InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}

তারপরে বলুন উদাহরণস্বরূপ আপনার এটিকে ক্রিয়াকলাপ থেকে কল করতে হবে, নীচে এটি কল করুন;

UIutils.serachAndHideSoftKeybordFromView(findViewById(android.R.id.content), YourActivityName.this);

বিজ্ঞপ্তি

findViewByID (android.R.id.content)

এটি আমাদের বর্তমান গোষ্ঠীর রুট ভিউ দেয় (আপনি অবশ্যই মূল ভিউতে আইডি সেট করবেন না)।

চিয়ার্স :)


2

আপনার ক্রিয়াকলাপের windowSoftInputModeমান হিসাবে স্টেটহাইডে রাখার চেষ্টা করুন

http://developer.android.com/reference/android/R.attr.html#windowSoftInputMode

আপনার ক্রিয়াকলাপের জন্য উদাহরণস্বরূপ:

this.getWindow().setSoftInputMode(
    WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);

2

কার্যকলাপ

 @Override
 public boolean dispatchTouchEvent(MotionEvent ev) {
     ScreenUtils.hideKeyboard(this, findViewById(android.R.id.content).getWindowToken());
     return super.dispatchTouchEvent(ev);
 }

ScreenUtils

 public static void hideKeyboard(Context context, IBinder windowToken) {
     InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
     imm.hideSoftInputFromWindow(windowToken, InputMethodManager.HIDE_NOT_ALWAYS);
 }

3
এই কোডটি সহজ, তবে এটিতে একটি সুস্পষ্ট সমস্যা রয়েছে: যে কোনও জায়গায় স্পর্শ করলে এটি কীবোর্ডটি বন্ধ করে দেয় । এটি হ'ল যদি আপনি ইনপুট কার্সারটি সরিয়ে নিতে সম্পাদনা পাঠ্যের কোনও আলাদা অবস্থানটি ট্যাপ করেন তবে এটি কীবোর্ডটি লুকিয়ে রাখে এবং কীবোর্ডটি সিস্টেমের মাধ্যমে আবার পপ আপ হয়।
অভিশাপ শাকসবজি

2

ক্লাসে এই কোডটি যুক্ত করুন @ ওভারাইড

public boolean dispatchTouchEvent(MotionEvent ev) {
    View view = getCurrentFocus();
    if (view != null && (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_MOVE) && view instanceof EditText && !view.getClass().getName().startsWith("android.webkit.")) {
        int scrcoords[] = new int[2];
        view.getLocationOnScreen(scrcoords);
        float x = ev.getRawX() + view.getLeft() - scrcoords[0];
        float y = ev.getRawY() + view.getTop() - scrcoords[1];
        if (x < view.getLeft() || x > view.getRight() || y < view.getTop() || y > view.getBottom())
            ((InputMethodManager)this.getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow((this.getWindow().getDecorView().getApplicationWindowToken()), 0);
    }
    return super.dispatchTouchEvent(ev);
}

3
যদিও এটি প্রশ্নের উত্তর দিতে পারে, উত্তরের প্রয়োজনীয় অংশগুলি এবং সম্ভবত ওপিএস কোডটিতে কী সমস্যা ছিল তা ব্যাখ্যা করা ভাল।
pirho

হ্যাঁ @ পিরহো আমিও আপনার সাথে একমত, হাসিবের যথাযথ উত্তর দেওয়ার ক্ষেত্রে মনোনিবেশ করা দরকার।
দিলিপ

2
@ দিলিপ আপনি কি জানেন যে আপনি যে মতামতগুলি সম্মত করেছেন সেগুলিও উত্সাহিত করতে পারেন? এটি কেবল মন্তব্য বিভাগকে পরিষ্কার রাখার জন্য যাতে অনেকগুলি মন্তব্য আসলে একই পয়েন্টটি না রাখে।
pirho

2

সমস্ত দর্শনগুলির মাধ্যমে পুনরাবৃত্তি করা বা ডিসপ্যাচ টাচ ইভেন্টকে ওভাররাইড করার পরিবর্তে।

ক্রিয়াকলাপের কেবলমাত্র ইউজারআইনটারাকশন () ওভাররাইড করা হবে না কেন এটি ব্যবহারকারী যখনই সম্পাদনা পাঠের বাইরে ট্যাপ করে তা নিশ্চিত করে কীবোর্ডকে বরখাস্ত করবে।

সম্পাদনা পাঠ্য স্ক্রোলভিউয়ের অভ্যন্তরে থাকা অবস্থায়ও কাজ করবে।

@Override
public void onUserInteraction() {
    if (getCurrentFocus() != null) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
    }
}

এই আরও ভাল উত্তর
ovluca

হ্যাঁ! এটি একটি সুপার ক্লিন উত্তর। এবং যদি আপনি এমন একটি অ্যাবস্ট্রাক্ট অ্যাক্টিভিটি তৈরি করেন যা আপনার অন্যান্য ক্রিয়াকলাপগুলি প্রসারিত করে তবে আপনি এটিকে আপনার অ্যাপ্লিকেশন জুড়ে ডিফল্ট আচরণ হিসাবে বেক করতে পারেন।
ওয়াইল্ডক্যাট 12

1

ফার্নান্দো কামারাগো সমাধানে সামান্য বৈকল্পিকের সাথে আমি এই কাজটি পেয়েছি। আমার অনক্রিয়েট পদ্ধতিতে আমি রুট ভিউতে একটি একক অন টাচলিস্টনার সংযুক্ত করি তবে যুক্তি হিসাবে কার্যকলাপের পরিবর্তে ভিউটি প্রেরণ করি।

        findViewById(android.R.id.content).setOnTouchListener(new OnTouchListener() {           
        public boolean onTouch(View v, MotionEvent event) {
            Utils.hideSoftKeyboard(v);
            return false;
        }
    });

একটি পৃথক ইউটিস শ্রেণিতে রয়েছে ...

    public static void hideSoftKeyboard(View v) {
    InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); 
    imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}

1

এটি পুরানো হতে পারে তবে আমি একটি কাস্টম ক্লাস চাপিয়ে এই কাজটি পেয়েছি

public class DismissKeyboardListener implements OnClickListener {

    Activity mAct;

    public DismissKeyboardListener(Activity act) {
        this.mAct = act;
    }

    @Override
    public void onClick(View v) {
        if ( v instanceof ViewGroup ) {
            hideSoftKeyboard( this.mAct );
        }
    }       
}

public void hideSoftKeyboard(Activity activity) {
        InputMethodManager imm = (InputMethodManager)
        getSystemService(Activity.INPUT_METHOD_SERVICE);
        imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
}

এখানে সর্বোত্তম অনুশীলন হেল্পার ক্লাস তৈরি করা এবং প্রতিটি ধারক আপেক্ষিক / লিনিয়ার লেআউটগুলি এটি প্রয়োগ করা উচিত।

**** নোট করুন কেবলমাত্র প্রধান পাত্রে এই শ্রেণিটি প্রয়োগ করা উচিত (অপ্টিমাইজেশনের জন্য) ****

এবং এটি এর মতো বাস্তবায়ন করুন:

Parent.setOnClickListener( new DismissKeyboardListener(this) ); 

এই কীওয়ার্ডটি ক্রিয়াকলাপের জন্য। সুতরাং আপনি যদি খণ্ডে থাকেন তবে আপনি getActivity () এর মতো ব্যবহার করেন;

থাম্বস আপ যদি এটি আপনাকে সহায়তা করে ... --- চিয়ার্স র‌্যাল্ফ ---


1

এটি fje এর উত্তরের একটি সামান্য পরিবর্তিত সংস্করণ যা বেশিরভাগ নিখুঁতভাবে কাজ করে।

এই সংস্করণটি ACTION_DOWN ব্যবহার করে সুতরাং একটি স্ক্রোল ক্রিয়া সম্পাদন করা কীবোর্ডটি বন্ধ করে দেয়। আপনি অন্য সম্পাদনা পাঠ্য ক্লিক না করা হলে এটি ইভেন্টটির প্রচারও করে না। এর অর্থ হ'ল আপনার সম্পাদনা পাঠের বাইরে অন্য যে কোনও ক্লিকযোগ্য স্থানে ক্লিক করা কেবল কীবোর্ডটি বন্ধ করে দেয়।

@Override
public boolean dispatchTouchEvent(MotionEvent ev)
{
    if(ev.getAction() == MotionEvent.ACTION_DOWN)
    {
        final View view = getCurrentFocus();

        if(view != null)
        {
            final View viewTmp = getCurrentFocus();
            final View viewNew = viewTmp != null ? viewTmp : view;

            if(viewNew.equals(view))
            {
                final Rect rect = new Rect();
                final int[] coordinates = new int[2];

                view.getLocationOnScreen(coordinates);

                rect.set(coordinates[0], coordinates[1], coordinates[0] + view.getWidth(), coordinates[1] + view.getHeight());

                final int x = (int) ev.getX();
                final int y = (int) ev.getY();

                if(rect.contains(x, y))
                {
                    super.dispatchTouchEvent(ev);
                    return true;
                }
            }
            else if(viewNew instanceof EditText || viewNew instanceof CustomEditText)
            {
                super.dispatchTouchEvent(ev);
                return true;
            }

            final InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);

            inputMethodManager.hideSoftInputFromWindow(viewNew.getWindowToken(), 0);

            viewNew.clearFocus();

            return true;
        }
    }
    return super.dispatchTouchEvent(ev);
}

কিছু এখানে ঠিক দেখাচ্ছে না; আপনি উভয়কে viewএবং নিয়োগ viewTmpদিচ্ছেন getCurrentFocus(), যাতে তারা সর্বদা একই মান হতে চলেছে।
অ্যান্ডি ডেনি

1

আমি এইভাবে করেছি:

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
   View view = getCurrentFocus();
   if (view != null && (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_MOVE) && view instanceof EditText && !view.getClass().getName().startsWith("android.webkit.")) {
            int scrcoords[] = new int[2];
            view.getLocationOnScreen(scrcoords);
            float x = ev.getRawX() + view.getLeft() - scrcoords[0];
            float y = ev.getRawY() + view.getTop() - scrcoords[1];
            if (x < view.getLeft() || x > view.getRight() || y < view.getTop() || y > view.getBottom())
                hideKeyboard(this);
        }
    return super.dispatchTouchEvent(ev);
}

কীবোর্ড কোডটি লুকান :

public static void hideKeyboard(Activity act) {
    if(act!=null)
      ((InputMethodManager)act.getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow((act.getWindow().getDecorView().getApplicationWindowToken()), 0);
  }

সম্পন্ন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.