web-dev-qa-db-fra.com

Fermer le clavier lorsque vous cliquez en dehors de EditText dans Android

J'ai une EditText appelée myTextview. Je souhaite que le clavier virtuel apparaisse lorsque je clique sur la variable EditText, puis que je le ferme si je clique en dehors de la variable EditText. J'utilise donc la méthode ci-dessous. Mais le clavier ne disparaît pas lorsque je clique en dehors de la vue (je clique sur une TextView). Comment puis-je réparer ce code?

myTextview.setOnFocusChangeListener(new OnFocusChangeListener() {

        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (hasFocus) {
                getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
            } else {
                InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(myTextview.getWindowToken(), 0);
            }

        }
    });
16
user3093402

J'ai trouvé une meilleure solution:

Remplacez la méthode dispatchTouchEvent dans votre activité.

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    View v = getCurrentFocus();

    if (v != null && 
            (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_MOVE) && 
            v instanceof EditText && 
            !v.getClass().getName().startsWith("Android.webkit.")) {
        int scrcoords[] = new int[2];
        v.getLocationOnScreen(scrcoords);
        float x = ev.getRawX() + v.getLeft() - scrcoords[0];
        float y = ev.getRawY() + v.getTop() - scrcoords[1];

        if (x < v.getLeft() || x > v.getRight() || y < v.getTop() || y > v.getBottom())
            hideKeyboard(this);
    }
    return super.dispatchTouchEvent(ev);
}

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

Ceci est applicable même si vous travaillez avec Webview.

43
Felipe R. Saruhashi

Peut-être un peu plus facile:

Définissez un focusChangedListener sur votre texte d'édition, puis masquez simplement le clavier si vous n'avez pas le focus.

yourEditText.setOnFocusChangeListener(new OnFocusChangeListener() {

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if(!hasFocus){
            hideKeyboard();
        }               
    }
});

private void hideKeyboard() {
    InputMethodManager imm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(yourEditText.getWindowToken(), 0);
}
15
pat

utilisez le code suivant.

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

ça marche pour moi.

3
Ganpat Kaliya

De cette façon, le clavier ne disparaît que lorsque vous touchez une vue pouvant faire la mise au point. Je vous suggère de faire ce qui suit:

Créez un ViewGroup personnalisé comme ceci:

public class TouchLayout extends LinearLayout {

    private OnInterceptTouchEventListener mListener;

    public TouchLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        if(mListener != null) {
            return mListener.onInterceptTouchEvent(event);
        }
        return super.onInterceptTouchEvent(event);
    }

    public void setOnInterceptTouchEventListener(OnInterceptTouchEventListener listener) {
        mListener = listener;
    }

    public interface OnInterceptTouchEventListener {
        public boolean onInterceptTouchEvent(MotionEvent event);
    }
}

Ajoutez ensuite la vue personnalisée en tant que racine de votre mise en page XML:

<com.example.TouchLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/root"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:orientation="vertical" >

        <EditText
            Android:id="@+id/text"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content" />

Et dans votre activité, vous devriez faire ce qui suit:

final TouchLayout root = (TouchLayout) findViewById(R.id.root);
final EditText text = (EditText) findViewById(R.id.text);
final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);

root.setOnInterceptTouchEventListener(new OnInterceptTouchEventListener() {

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        final View v = getCurrentFocus();
        if(v != null && v.equals(text)) {
            final int screenCords[] = new int[2];
            text.getLocationOnScreen(screenCords);
            final Rect textRect = new Rect(screenCords[0], screenCords[1], screenCords[0] + text.getWidth(), screenCords[1] + text.getHeight());
            if(!textRect.contains(event.getRawX(), event.getRawY() {
                imm.hideSoftInputFromWindow(myTextview.getWindowToken(), 0);
                // Optionally you can also do the following:
                text.setCursorVisible(false);
                text.clearFocus(); 
            }
        }
        return false;
    }
};
3
diegocarloslima

Plaidoyer: Je reconnais ne pas avoir de poids, mais prenez ma réponse au sérieux. 

Problème: Fermez le clavier logiciel lorsque vous cliquez loin du clavier ou modifiez le texte avec un code minimal.

Solution: Bibliothèque externe appelée Butterknife.

_ {One Line Solution:} _

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

Solution plus lisible:

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

Explication: Liez OnClick Listener à l'ID parent de la disposition XML de l'activité, de sorte que tout clic sur la disposition (et non sur le texte ou le clavier édité) exécute cet extrait de code masquant le clavier.

Exemple: Si votre fichier de mise en page est R.layout.my_layout et votre identifiant de mise en page est R.id.my_layout_id, votre appel de reliure Butterknife doit alors ressembler à ceci:

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

Butterknife Documentation Lien:http://jakewharton.github.io/butterknife/

Plug: Butterknife va révolutionner votre développement Android. Considère-le.

2
Charles Woodson

Code Android Xamarin pour cela:

  public override bool DispatchTouchEvent(MotionEvent ev)
    {
        try
        {
            View view = CurrentFocus;
            if (view != null && (ev.Action == MotionEventActions.Up || ev.Action == MotionEventActions.Move) && view is EditText && !view.Class.Name.StartsWith("Android.webkit."))
            {
                int[] Touch = new int[2];
                view.GetLocationOnScreen(Touch);
                float x = ev.RawX + view.Left - Touch[0];
                float y = ev.RawY + view.Top - Touch[1];
                if (x < view.Left || x > view.Right || y < view.Top || y > view.Bottom)
                    ((InputMethodManager)GetSystemService(InputMethodService)).HideSoftInputFromWindow((Window.DecorView.ApplicationWindowToken), 0);
            }
        }
        catch (System.Exception ex)
        {

        }

        return base.DispatchTouchEvent(ev);
    }
0
G.hakim

Un événement tactile sur une vue commencera par ACTION_DOWN après avoir été passé de haut en bas à cette hiérarchie de vues en vue. Remplacez dispatchTouchEvent pour effectuer des tâches supplémentaires. Voici un exemple à partir de FrameLayout in kotlin:

class TLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet?=null):
        FrameLayout(context, attrs){

    var preDispatchTouchEvent: ((ev: MotionEvent?)->Boolean)? = null

    override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
        if (preDispatchTouchEvent==null || !preDispatchTouchEvent!!.invoke(ev)) {
            super.dispatchTouchEvent(ev)
        }
        return true
    }

}

Enveloppez votre EditText et tout autre nom relatif Views sous cette présentation, puis définissez preDispatchTouchEvent de manière à exclure EditText lorsque l'événement n'est pas supérieur.

Consultez cette question du système d'exploitation et le document officiel pour avoir une compréhension plus profonde de la fourniture d'événements tactiles.

0
Lym Zoy

J'utilise ci-dessous Process. Cela fonctionne parfaitement pour moi. Ajouter la fonction ci-dessous dans votre classe d'activité.

  override fun dispatchTouchEvent(event: MotionEvent): Boolean {
    if (event.action == MotionEvent.ACTION_DOWN) {
        val v = currentFocus
        if (v is EditText) {
            val outRect = Rect()
            v.getGlobalVisibleRect(outRect)
            if (!outRect.contains(event.rawX.toInt(), event.rawY.toInt())) {
                Log.d("focus", "touchevent")
                v.clearFocus()
                val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                imm.hideSoftInputFromWindow(v.windowToken, 0)
            }
        }
    }
    return super.dispatchTouchEvent(event)
}

Ensuite, je vérifierai le statut de la mise au point dans mon fragment.

appCompatEditText.onFocusChangeListener = View.OnFocusChangeListener { view, hasFocus ->
                if (!hasFocus) {
                    toast("Focus Off")
                }else {
                    toast("Focus On")
                }
            }

J'ai été vérifié en fragment. J'avais besoin du statut Focus pour mon besoin de tâche. Focus Out j'avais besoin d'une tâche.

0
Shohel Rana