web-dev-qa-db-fra.com

Ajouter un tiroir de navigation à une activité existante

J'ai une application que j'écris et qui contient déjà beaucoup de code, j'ai décidé que je veux ajouter un tiroir de navigation à la barre d'outils d'activité principale mais je ne sais pas comment le faire sans créer un nouveau projet de tiroir de navigation et copier l'ensemble de mon projet qui me semble beaucoup de travail, existe-t-il un tutoriel pour ajouter un tiroir de navigation à un projet existant?

22
user7415791

Créer une mise en page layout_left_menu.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:orientation="vertical"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:background="@color/bgLeftMenu">

<ImageView Android:id="@+id/header"
    Android:src="@drawable/ic_launcher"
    Android:layout_width="48dp"
    Android:layout_height="48dp"
    Android:layout_marginTop="26dp"
    Android:layout_marginBottom="8dp"
    Android:layout_marginLeft="30dp"
    Android:layout_marginStart="40dp"/>

<RelativeLayout
    Android:layout_width="wrap_content"
    Android:layout_height="48dp"
    Android:layout_marginTop="26dp"
    Android:layout_marginLeft="10dp"
    Android:layout_toRightOf="@id/header">

    <LinearLayout
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:orientation="vertical"
        Android:layout_centerInParent="true">
        <TextView
            Android:id="@+id/userName"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:text="@string/app_name"
            Android:textColor="@color/pressed"/>
        <TextView
            Android:id="@+id/userEmail"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:text="@string/app_name"
            Android:layout_below="@id/userName"
            Android:layout_centerInParent="true"
            Android:textColor="@color/pressed"
            Android:visibility="gone"/>
    </LinearLayout>
</RelativeLayout>

<ListView Android:id="@+id/menu_items_list"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:layout_below="@id/header"
    Android:dividerHeight="0dp"
    Android:divider="@null"
    Android:background="@color/bgLeftMenu"/>

<ProgressBar Android:id="@+id/progress"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:layout_centerInParent="true"
    Android:visibility="gone"/>

</RelativeLayout>

Gonflez-le dans une vue personnalisée:

public class SimpleLeftMenuView extends NavigationView {
    private LayoutInflater mInflater;
    private Context mContext;

    private ListView mItemsList;
    private MenuItemsAdapter mItemsAdapter;
    private ProgressBar mProgress;

    private OnClickMenu mListener;

    private ImageView mHeader;
    private TextView userName;
    private TextView userEmail;

    //region Constructors
    public SimpleLeftMenuView(Context context) {
        super(context);
        mContext = context;
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        initLayout();

        setData();
    }

    public SimpleLeftMenuView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        initLayout();

        setData();
    }

    public SimpleLeftMenuView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        initLayout();

        setData();
    }
    //endregion

    private void initLayout(){
        mInflater.inflate(R.layout.layout_left_menu, this);
        mItemsList = (ListView) findViewById(R.id.menu_items_list);
        mProgress = (ProgressBar) findViewById(R.id.progress);

        mHeader = (ImageView) findViewById(R.id.header);
        userName = (TextView) findViewById(R.id.userName);
        userEmail = (TextView) findViewById(R.id.userEmail);

        mHeader.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // do something
            }
        });
    }

    public void setSelectedSection(String idSection) {
        mItemsAdapter.setLastSelectedSection(idSection);
    }

    public void setmListener(OnClickMenu mListener) {
        this.mListener = mListener;
    }

    private void setData() {

        List<String> sections = new ArrayList<>();

        sections.add(mContext.getString(R.string.home_id));
        sections.add(mContext.getString(R.string.login_id));
        sections.add(mContext.getString(R.string.settings_id));
        //.........
        //sections.add(mContext.getString(R.string.exit_id));

        mItemsAdapter = new MenuItemsAdapter(mContext, sections, new OnClickMenu() {
            @Override
            public void onClick(String id) {
                mItemsAdapter.setLastSelectedSection(id);

                if (mListener != null)
                    mListener.onClick(id);
            }
        });
        mItemsList.setAdapter(mItemsAdapter);
        mItemsList.setSelection(0);
        mItemsList.setItemChecked(0, true);
    }
}

Vous devez créer le MenuItemAdapter.

    public class MenuItemsAdapter extends BaseAdapter {

    private Context mContext;
    private static String lastSelectedSection;

    private List<String> mSections;
    private int currentTextcolor;
    private OnClickMenu mListener;

    public MenuItemsAdapter(Context context, List<String> sections, OnClickMenu listener) {
        mContext = context;
        mSections = sections;
        mListener = listener;

        lastSelectedSection = sections.get(0);
    }

    @Override
    public int getCount() {
        return mSections.size();
    }

    @Override
    public String getItem(int position) {
        return mSections.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        return getCustomView(position, convertView, parent);
    }

    public View getCustomView(final int position, View convertView, ViewGroup parent) {
        final MenuItemHolder holder;

        if (convertView==null){

            LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
            convertView = inflater.inflate(R.layout.layout_left_menu_item, parent, false);
            holder = new MenuItemHolder(convertView);


            convertView.setTag(holder);

        }else {

            holder = (MenuItemHolder) convertView.getTag();

        }

        Resources r = mContext.getResources();
        int pxMarginSection = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, r.getDisplayMetrics());

        holder.position = position;

        holder.mLine.setVisibility(View.GONE);
        holder.mTitle.setTextColor(mContext.getResources().getColor(R.color.primary));
        holder.mIconView.setColorFilter(mContext.getResources().getColor(R.color.primary));

        if (mSections.get(position).equals(mContext.getString(R.string.login_id))) {
            holder.mIconView.setImageResource(R.drawable.ic_login_gp);
            // holder.mIconView.setColorFilter(mContext.getResources().getColor(R.color.primary));
            holder.mTitle.setText(mContext.getString(R.string.action_login));
            holder.mLine.setVisibility(View.VISIBLE);
            holder.mLayoutItem.setPadding(0, pxMarginSection, 0, pxMarginSection);
        } else if (mSections.get(position).equals(mContext.getString(R.string.settings_id))) {
            holder.mIconView.setImageResource(R.drawable.option);
            holder.mTitle.setText(mContext.getString(R.string.action_settings));
            holder.mLayoutItem.setPadding(0, pxMarginSection, 0, pxMarginSection);
            holder.mLine.setVisibility(View.VISIBLE);
        } else if (mSections.get(position).equals(mContext.getString(R.string.exit_id))) {
            holder.mIconView.setImageResource(R.drawable.shutdown);
            holder.mTitle.setText(mContext.getString(R.string.salir));
            holder.mLayoutItem.setPadding(0, pxMarginSection, 0, pxMarginSection);
            holder.mLine.setVisibility(View.VISIBLE);
        }

        holder.mLayoutItem.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {

                switch (motionEvent.getActionMasked()){
                    case MotionEvent.ACTION_DOWN:
                        currentTextcolor = holder.mTitle.getCurrentTextColor();
                        holder.mLayoutItemSelect.setBackgroundColor(mContext.getResources().getColor(R.color.primary));
                        holder.mTitle.setTextColor(mContext.getResources().getColor(R.color.text_info));
                        holder.mIconView.setColorFilter(mContext.getResources().getColor(R.color.text_info));
                        return true;


                    case MotionEvent.ACTION_UP:

                        holder.mLayoutItemSelect.setBackgroundResource(R.color.bgLeftMenu);
                        holder.mTitle.setTextColor(currentTextcolor);
                        holder.mIconView.setColorFilter(mContext.getResources().getColor(R.color.primary));

                        mListener.onClick(mSections.get(position));
                        return true;

                    case MotionEvent.ACTION_CANCEL:

                        holder.mLayoutItemSelect.setBackgroundColor(mContext.getResources().getColor(R.color.bgLeftMenu));
                        holder.mTitle.setTextColor(currentTextcolor);
                        holder.mIconView.setColorFilter(mContext.getResources().getColor(R.color.primary));

                        return true;

                }

                return false;
            }
        });

        return convertView;

    }

    class MenuItemHolder {

        // butterKnife
        View view;
        @Bind(R.id.title)
        TextView mTitle;
        @Bind(R.id.icon)
        ImageView mIconView;
        @Bind(R.id.layoutItem)
        LinearLayout mLayoutItem;
        @Bind (R.id.rl_line)
        View mLine;
        @Bind(R.id.layoutItemSelect)
        LinearLayout mLayoutItemSelect;

        int position;

        public MenuItemHolder(View itemView) {
            ButterKnife.bind(this, itemView);
            view = itemView;
        }

    }

    public void setLastSelectedSection(String idSection) {
        lastSelectedSection = idSection;
    }
}

Vous devez maintenant modifier votre activité actuelle:

  1. Modifiez la disposition de votre activité principale pour utiliser DrawerLayout et ajoutez votre vue personnalisée "SimpleLeftMenuView":

    <Android.support.v4.widget.DrawerLayout
    Android:id="@+id/drawerLayout"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:background="#EDEDED">
    
    // YOUR CURRENT LAYOUT
    
    <yourpackage.custom.SimpleLeftMenuView
        Android:id="@+id/navigation_view"
        Android:layout_width="wrap_content"
        Android:layout_height="match_parent"
        Android:layout_gravity="start"
        Android:background="@color/bgLeftMenu"/>
    
    
    </Android.support.v4.widget.DrawerLayout>
    
  2. Classe d'activité:

Ajoutez des variables globales:

protected @Bind(R.id.navigation_view) SimpleLeftMenuView mLeftMenuView;
protected @Bind(R.id.drawerLayout) DrawerLayout mDrawerLayout;

Définissez l'écouteur onclick. Vous pouvez faire une action dépend de l'id:

mLeftMenuView.setmListener(new OnClickMenu() {
        @Override
        public void onClick(String id) {
            Log.d("MENU", "ic_menu_hamburger clicked: " + id);

            closeDrawer(null);

            if (id.equals(getString(R.string.settings_id))) {
                Intent intent = new Intent(MainActivity.this,
                        SettingsActivity.class);
                MainActivity.this.startActivity(intent);
            } else if (id.equals(getString(R.string.exit_id))) {
                // salir
                showRateDialogBeforeExit();
            }

        }
    });

J'ai créé ma propre interface OnClickMenu:

public interface OnClickMenu {

   void onClick(String id);

}

Et ajoutez une action pour ouvrir le tiroir à partir de l'icône de menu:

@Override
public void onBackPressed() {
    if((mDrawerLayout) != null && (mDrawerLayout.isDrawerOpen(GravityCompat.START)))
        closeDrawer(null);
    else {
        super.onBackPressed();
    }
}

public void closeDrawer(DrawerLayout.DrawerListener listener) {
    mDrawerLayout.setDrawerListener(listener);
    mDrawerLayout.closeDrawers();
}

public void openDrawer() {
    mDrawerLayout.setDrawerListener(null);
    mDrawerLayout.openDrawer(GravityCompat.START);
}

Menu:

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    getMenuInflater().inflate(R.menu.menu_home, menu);

    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case Android.R.id.home:
            openDrawer();
            return true;
    }
    return super.onOptionsItemSelected(item);
}

ajouter à l'application build.gradle

compile 'com.Android.support:design:26.0.0'
compile 'com.jakewharton:butterknife:8.6.0'

Changer tout @Bind en @BindView

6
anthorlop

La manière la plus simple pour vous serait d'utiliser la bibliothèque this .

C'est vraiment facile à mettre en œuvre et très flexible.

Si vous voulez le faire vous-même, pensez à lire --- docs officiel sur la création du tiroir de navigation.

3
Yury Dombaev

J'ai essayé la bibliothèque MaterialDrawer, comme suggéré par @ yury-dombaev et je dois admettre qu'elle est beaucoup plus facile à mettre en œuvre que le tiroir de navigation officiel.

Il est possible d'implémenter soit avec les dépendances Android X, soit avec les normales.

Dans mon cas, puisque j'ai les normales, je dois m'en tenir au MaterialDrawer 6.0.9v. Bien qu'il existe un guide de migration que je vais jeter un œil.

Pour implémenter la bibliothèque dans votre activité actuelle, procédez comme suit:

  1. Ajoutez les dépendances dans votre application build.gradle comme expliqué dans la configuration 1 de la v 6.0.9 de la bibliothèque: https://github.com/mikepenz/MaterialDrawer/tree/v6.0.9
  2. Ajoutez votre tiroir dans la méthode onCreate () de votre Activity: new DrawerBuilder().withActivity(this).build();.
  3. Vous avez maintenant un menu latéral de base (et inutile). Il est donc temps de continuer à lire la documentation de Material Drawer et d'ajouter des éléments de menu :)
1
xarlymg89