web-dev-qa-db-fra.com

Masquage de la "barre de navigation inférieure" lorsque le clavier est présent - Android

J'ai une petite application d'interface utilisateur de chat de démonstration. Cette application possède une barre de navigation inférieure. J'ai besoin que la barre de navigation du bas se cache lorsque le clavier apparaît.

Voici un exemple de l'interface utilisateur de chat

Comme vous pouvez le voir lorsque vous cliquez sur l'élément EditText, le clavier apparaît mais la barre de navigation inférieure reste visible. J'ai essayé des méthodes telles que cette méthode de mesure , mais les éléments de l'interface utilisateur scintillent comme ceci .

Existe-t-il un moyen approprié de masquer la barre de navigation inférieure lorsque le clavier est visible?

EDIT: Dans l'activité ci-dessous, vous pouvez voir où j'ai défini l'écouteur du clavier pour ajuster la position des éléments de l'interface utilisateur lorsque le clavier est déterminé comme étant visible.

Ceci est mon code d'activité, utilise la méthode setKeyboardListener du lien ci-dessus et le définit dans onCreateView:

package uk.cal.codename.projectnedry.TeamChatFragment;

import Android.annotation.SuppressLint;
import Android.content.Context;
import Android.content.res.Configuration;
import Android.content.res.Resources;
import Android.graphics.Rect;
import Android.net.Uri;
import Android.os.Build;
import Android.os.Bundle;
import Android.support.v4.app.Fragment;
import Android.support.v7.app.AppCompatActivity;
import Android.support.v7.widget.LinearLayoutManager;
import Android.support.v7.widget.RecyclerView;
import Android.text.Layout;
import Android.util.DisplayMetrics;
import Android.util.Log;
import Android.util.TypedValue;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
import Android.view.ViewTreeObserver;
import Android.view.Window;
import Android.view.WindowManager;
import Android.view.inputmethod.InputMethodManager;
import Android.widget.Button;
import Android.widget.EditText;
import Android.widget.FrameLayout;
import Android.widget.ImageButton;
import Android.widget.LinearLayout;
import Android.widget.RelativeLayout;
import Android.widget.Toast;

import com.roughike.bottombar.BottomBar;

import Java.util.ArrayList;

import butterknife.BindView;
import butterknife.ButterKnife;
import uk.cal.codename.projectnedry.R;
import uk.cal.codename.projectnedry.TeamChatFragment.ListAdapter.TeamChatListAdapter;
import uk.demo.cal.genericmodelviewpresenter.GenericMvp.GenericMvpFragment;

import static Android.view.View.GONE;

/**
 * A simple {@link Fragment} subclass.
 * Activities that contain this fragment must implement the
 * {@link TeamChatView.OnFragmentInteractionListener} interface
 * to handle interaction events.
 * Use the {@link TeamChatView#newInstance} factory method to
 * create an instance of this fragment.
 */
public class TeamChatView extends GenericMvpFragment implements TeamChatContract.RequiredViewOps {

    private OnFragmentInteractionListener mListener;
    @BindView(R.id.teamChatList)
    RecyclerView mTeamChatRecyclerView;
    @BindView(R.id.teamChatSendButton)
    ImageButton mTeamChatSendButton;
    @BindView(R.id.messageTextInput)
    EditText mMessageTextInput;
    TeamChatListAdapter mTeamChatListAdapter;
    TeamChatListAdapter.ClickListener mTeamChatListClickListener;
    private ArrayList<String> mTestMessageList;

    public interface OnKeyboardVisibilityListener {
        void onVisibilityChanged(boolean visible);
    }

    public final void setKeyboardListener(final OnKeyboardVisibilityListener listener) {
        final View activityRootView = ((ViewGroup) getActivity().findViewById(Android.R.id.content)).getChildAt(0);

        activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

            private boolean wasOpened;

            private final int DefaultKeyboardDP = 100;

            // From @nathanielwolf answer...  Lollipop includes button bar in the root. Add height of button bar (48dp) to maxDiff
            private final int EstimatedKeyboardDP = DefaultKeyboardDP + (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop ? 48 : 0);

            private final Rect r = new Rect();

            @Override
            public void onGlobalLayout() {
                // Convert the dp to pixels.
                int estimatedKeyboardHeight = (int) TypedValue
                        .applyDimension(TypedValue.COMPLEX_UNIT_DIP, EstimatedKeyboardDP, activityRootView.getResources().getDisplayMetrics());

                // Conclude whether the keyboard is shown or not.
                activityRootView.getWindowVisibleDisplayFrame(r);
                int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
                boolean isShown = heightDiff >= estimatedKeyboardHeight;

                if (isShown == wasOpened) {
                    Log.d("Keyboard state", "Ignoring global layout change...");
                    return;
                }

                wasOpened = isShown;
                listener.onVisibilityChanged(isShown);
            }
        });
    }

    public TeamChatView() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @return A new instance of fragment TeamChatView.
     */
    public static TeamChatView newInstance() {
        TeamChatView fragment = new TeamChatView();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    @SuppressLint("MissingSuperCall")
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(TeamChatPresenter.class, TeamChatModel.class, savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        final View view = inflater.inflate(R.layout.fragment_team_chat_view, container, false);
        this.mUnbinder = ButterKnife.bind(this, view);

        mTestMessageList = new ArrayList<>();
        this.mTeamChatListAdapter = new TeamChatListAdapter(mTestMessageList);
        this.mTeamChatRecyclerView.setAdapter(this.mTeamChatListAdapter);
        final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
        this.mTeamChatRecyclerView.setLayoutManager(linearLayoutManager);

        this.mTeamChatSendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(!String.valueOf(mMessageTextInput.getText()).equals("")) {
                    getSpecificImpOfGenericPresenter().sendMessage(String.valueOf(mMessageTextInput.getText()));
                    mMessageTextInput.setText("");
                    mTeamChatRecyclerView.smoothScrollToPosition(mTestMessageList.size());
                }
            }
        });

        setKeyboardListener(new OnKeyboardVisibilityListener(){
            @Override
            public void onVisibilityChanged(boolean visible) {
                RelativeLayout contentFrame = (RelativeLayout) getActivity().findViewById(R.id.content_company_navigation);
                BottomBar lowerNavigationBar = (BottomBar) getActivity().findViewById(R.id.bottomBar);
                if (visible) { // if more than 100 pixels, its probably a keyboard...
                    lowerNavigationBar.setVisibility(GONE);
                    contentFrame.setPadding(0, 0, 0, 0);
                    mTeamChatRecyclerView.smoothScrollToPosition(mTestMessageList.size());
                } else {
                    contentFrame.setPadding(0, 0, 0, convertDpToPixel(60, getContext()));
                    mTeamChatRecyclerView.smoothScrollToPosition(mTestMessageList.size());
                    lowerNavigationBar.setVisibility(View.VISIBLE);
                }
            }
        });
        return view;
    }

    /**
     * This method converts dp unit to equivalent pixels, depending on device density.
     *
     * @param dp A value in dp (density independent pixels) unit. Which we need to convert into pixels
     * @param context Context to get resources and device specific display metrics
     * @return A float value to represent px equivalent to dp depending on device density
     */
    public static int convertDpToPixel(float dp, Context context){
        Resources resources = context.getResources();
        DisplayMetrics metrics = resources.getDisplayMetrics();
        int px = (int) (dp * ((float)metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT));
        return px;
    }

    public void addToTestMessageList(String str){
        this.mTestMessageList.add(str);
        this.mTeamChatListAdapter.notifyDataSetChanged();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
       // getView().getViewTreeObserver().removeGlobalOnLayoutListener(test);
    }

    @Override
    public TeamChatPresenter getSpecificImpOfGenericPresenter() {
        return (TeamChatPresenter) this.mPresenter;
    }
}

Voici ma disposition XML:

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:orientation="vertical"
    tools:context="uk.cal.codename.projectnedry.TeamChatFragment.TeamChatView">

    <Android.support.v7.widget.RecyclerView
        Android:layout_above="@+id/chatViewMessageEntryLayout"
        Android:id="@+id/teamChatList"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:layout_alignParentTop="true"
        Android:isScrollContainer="false"
        Android:paddingTop="10dp"
        Android:scrollbars="vertical" />    

    <RelativeLayout
        Android:id="@+id/chatViewMessageEntryLayout"
        Android:layout_width="match_parent"
        Android:layout_height="60dp"
        Android:layout_alignParentBottom="true"
        Android:orientation="horizontal">

        <View
            Android:id="@+id/chatViewMessageEntrySeperator"
            Android:layout_width="match_parent"
            Android:layout_height="1dp"
            Android:background="#e3e3e8" />

        <EditText
            Android:id="@+id/messageTextInput"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:layout_gravity="center_vertical"
            Android:layout_below="@+id/chatViewMessageEntrySeperator"
            Android:layout_toLeftOf="@+id/teamChatSendButton"
            Android:background="@Android:color/transparent"
            Android:hint="Enter message"
            Android:inputType="textCapSentences|textMultiLine"
            Android:maxLength="1000"
            Android:maxLines="4"
            Android:paddingLeft="10dp" />

        <ImageButton
            Android:id="@+id/teamChatSendButton"
            Android:layout_width="50dp"
            Android:layout_height="match_parent"
            Android:layout_alignParentRight="true"
            Android:layout_gravity="center"
            Android:background="#00B9EF"
            Android:src="@drawable/ic_send_white_24dp" />

    </RelativeLayout>

</RelativeLayout>
17
Calco

J'ai fini par utiliser la méthode de mesure de la hauteur qui semble être la méthode standard de détection de clavier souple décrite dans cette réponse . Cependant, j'ai utilisé cette bibliothèque implémentation de celui-ci, car c'est toujours la même ViewTreeObserver.OnGlobalLayoutListener méthode, bien implémentée et m'a permis d'extraire le code de la base de code principale de mes applications.

Lorsque cet écouteur de visibilité du clavier est déclenché, je cache/affiche ensuite la barre de navigation inférieure (que j'ai expliquée ici ).

6
Calco

L'implémentation la plus simple, Ajouter AndroidManifest.xml dans

<activity Android:windowSoftInputMode="adjustPan"/>

j'espère que cela aide quelqu'un. Prendre plaisir !

46

vous ajoutez simplement ce code dans votre manifeste de cette façon ..

 <activity Android:name=".MainActivity"
        Android:windowSoftInputMode="adjustPan">

cela fonctionne pour moi .. codage heureux

10

Dans mon cas, j'utilise DrawerLayout comme vue parent avec du contenu de mise en page et une barre de navigation inférieure. Dans le fichier manifeste, ajoutez "Android: windowSoftInputMode =" adjustPan "ce TAG avec Activity et cela fonctionne bien.

2
ajay singh Qualwebs

Ajoutez cette ligne dans onResume() de votre Activity ou Fragment.

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);

C'est travaillé pour moi. Essayez-le une seule fois.

1
mahesh kumar

Ajoutez l'attribut: Android:windowSoftInputMode="adjustResize"" dans votre manifeste à l'intérieur de la balise activity:

 <activity
        Android:name=".YourActivity"
        Android:windowSoftInputMode="adjustResize"/>

NB: Je suggère, vous devriez utiliser NestedScrollView comme disposition parent.

J'espère que cela t'aides.

0
tahsinRupam