Добавить навигационный ящик в существующую деятельность

У меня есть приложение, которое я пишу, и в нем уже содержится много кода. Я решил добавить ящик для навигации в панель инструментов основной деятельности, но я не знаю, как это сделать, не создавая новый навигационный ящик проект и скопируйте мой весь проект на него, который, похоже, много работает, есть ли учебное пособие, чтобы добавить ящик для навигации в существующий проект?

Ответ 1

Создайте макет 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>

Надуйте это в пользовательском представлении:

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);
    }
}

Вы должны создать 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;
    }
}

Теперь вам нужно изменить текущую активность:

  1. Измените свой основной макет деятельности, чтобы использовать DrawerLayout, и добавьте свой собственный вид "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. Класс деятельности:

Добавьте глобальные переменные:

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

Установите слушателя onclick. Вы можете сделать действие зависит от идентификатора:

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();
            }

        }
    });

Я создал свой собственный интерфейс OnClickMenu:

public interface OnClickMenu {

   void onClick(String id);

}

И добавьте действие, чтобы открыть ящик из значка меню:

@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);
}

Меню:

@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);
}

добавить в приложение build.gradle

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

Изменить все @Bind на @BindView

Ответ 2

Самый простой способ для вас - использовать эту библиотеку.

Его очень легко реализовать и очень гибко.

Если вы хотите сделать это самостоятельно, подумайте о том, чтобы прочитать официальное docs о создании навигационного ящика.

Ответ 3

Я попробовал библиотеку MaterialDrawer, как предложено @yury-dombaev, и я должен признать, что реализовать ее гораздо проще, чем официальный навигационный ящик.

Это возможно реализовать либо с зависимостями Android X, либо с обычными.

В моем случае, поскольку у меня есть нормальные, я должен придерживаться MaterialDrawer 6.0.9v. Хотя есть руководство по миграции, которое я посмотрю.

Для реализации библиотеки в вашей текущей деятельности выполните следующие действия:

  1. Добавьте зависимости в ваше build.gradle приложения, как описано в настройке 1 v 6.0.9 библиотеки: https://github.com/mikepenz/MaterialDrawer/tree/v6.0.9
  2. Добавьте свой ящик в метод onCreate() вашего Activity: new DrawerBuilder().withActivity(this).build(); ,
  3. Теперь у вас есть основное (и бесполезное) боковое меню. Итак, настало время продолжить чтение документации к материалам и добавить элементы меню :)