侧滑布局

848 阅读3分钟

DrawerLayout+NavigationView 来实现,记录自己出现的问题。

1.侧滑布局

创建侧滑布局可使用DrawerLayout作为容器,需要特殊配置的是android:fitsSystemWindows="true"让其占满窗口,以及tools:openDrawer="start"属性。 页面主布局必须是DrawerLayout中的第一个子View,可以使用include的layout引入,这样可以单独调整主布局而不受抽屉的影响。 抽屉布局可以是任何view,只要为其设置android:layout_gravity="start"来确定滑出方向即可,此处使用NavigationView作为侧滑菜单。

NavigationView 是最常用于抽屉布局的控件,需要引入com.android.support:design库。特殊配置有app:headerLayout="@layout/tasks_nav_header"用于配置抽屉头部显示,header布局中的view可以通过id来查找,也可以通过getHeaderView方法来获取header;app:menu="@menu/tasks_nav_menu"用于配置显示的菜单。

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".tasks.MainActivity"
    tools:openDrawer="start">

    <include layout="@layout/tasks_activity_content"/>

    <android.support.design.widget.NavigationView
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/tasks_nav_header"
        app:menu="@menu/tasks_nav_menu">

    </android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/tasks_nav_menu_list"
        android:icon="@drawable/tasks_nav_menu_list_ico_24dp"
        android:title="@string/tasks_nav_menu_list"></item>
    <item
        android:id="@+id/tasks_nav_menu_statistics"
        android:icon="@drawable/tasks_nav_menu_statistic_ico_24dp"
        android:title="@string/tasks_nav_menu_statistic"></item>
</menu>
// 为侧边栏菜单按钮设置事件响应
NavigationView navigationView = findViewById(R.id.tasks_nav);
if (navigationView != null) {
        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            switch (item.getItemId()) {
                case R.id.tasks_nav_menu_list:
                    break;
                case R.id.tasks_nav_menu_statistics:
                    Toast.makeText(MainActivity.this, "statics", Toast.LENGTH_SHORT).show();
                    break;
                default:
                    break;
            }
            item.setChecked(true);
            mDrawerLayout.closeDrawers();
            // 事件处理完毕
            return true;
        }
    });
}

2.Toolbar使用

  • 为APP选一个NoActionBar的主题
<style name="Base.AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>
  • 在布局文件中加入toolbar控件
    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <android.support.v7.widget.Toolbar
            android:id="@+id/tasks_toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?attr/colorPrimaryDark"
            android:theme="@style/Toolbar"
            app:title="@string/tasks_toolbar_title"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

    </android.support.design.widget.AppBarLayout>
  • 在Activity中设置ActionBar,并设置home键监听事件
    // 使用Toolbar代替ActionBar
    Toolbar toolbar = (Toolbar) findViewById(R.id.tasks_toolbar);
    setSupportActionBar(toolbar);
    ActionBar actionBar = getSupportActionBar();

    if (actionBar != null) {
        // 设置actionBar左侧图标按钮
        actionBar.setHomeAsUpIndicator(R.drawable.tasks_actionbar_home_ico_24dp);
        actionBar.setDisplayHomeAsUpEnabled(true);
    }

    // 监听点击事件
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                mDrawerLayout.openDrawer(GravityCompat.START);
                return true;
            default:
                break;
        }
        return super.onOptionsItemSelected(item);
    }

3.配置Menu

Menu中有两种标签,Item标签有常用属性有id、title、icon、orderInCategory等,Group标签常用属性有id、menuCategory、orderInCategory、visible、enable等属性。 特殊属性是:app:actionViewClass以及 app:actionProviderClass 这两个属性都可以配置自定义View在Toolbar在customView区域。

首先需要继承ActionProvider类,然后在menu的item中配置app:actionProviderClass="com.test.www.mytitletest.UploadActionProvider"该属性。

public class UploadActionProvider extends ActionProvider {

    private EditText mEditText;
    private Button mButton;

    public UploadActionProvider(Context context) {
        super(context);
    }

    @Override
    public View onCreateActionView() {
        // 初始化自己定义的View
        LayoutInflater layoutInflater = LayoutInflater.from(getContext());
        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(500, 80);
        View view = layoutInflater.inflate(R.layout.layout_search_bar, null);
        view.setLayoutParams(layoutParams);
        // 获取要用的控件
        mEditText=view.findViewById(R.id.et_search);
        mButton=view.findViewById(R.id.btn_send);
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String result=mEditText.getText().toString();
                // 事件处理
            }
        });
        return view;
    }
}
  • 在Activity中配置menu,其他事件监听和fragment中的一样。
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.toolbar_menu, menu);
        return super.onCreateOptionsMenu(menu);
    }
  • 在fragment中设置optionMenu,并配置响应事件。以下代码在fragment中。
    // 添加菜单 第一步
    setHasOptionsMenu(true);
    /**
     * 添加菜单 第二步
     *
     * @param menu
     * @param inflater
     */
    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.tasks_frag_menu, menu);
    }

    /**
     * 添加菜单 第三步
     *
     * @param item
     * @return
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.tasks_frag_menu_filter:
                showFilteringPopUpMenu();
                break;
            case R.id.tasks_frag_menu_clear_completed:
                break;
            case R.id.tasks_frag_menu_refresh:
                break;
            default:
                break;
        }
        return true;
    }

4.TabLayout和ViewPager的使用

TabLayout+ViewPager+Fragment是实现Tab页面切换的常用方式,常见用法如下: 首先是布局方案,比较简单。

<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.support.design.widget.TabLayout
        android:id="@+id/tablayout"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:layout_marginTop="8dp"
        app:tabIndicatorColor="@color/colorAccent"
        app:tabIndicatorHeight="5dp"
        app:tabIndicatorGravity="bottom"
        app:tabIndicatorFullWidth="false"
        app:tabMode="scrollable"
        app:tabSelectedTextColor="#f16821"
        app:layout_constraintTop_toTopOf="parent"></android.support.design.widget.TabLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintTop_toBottomOf="@+id/tablayout"></android.support.v4.view.ViewPager>
</android.support.constraint.ConstraintLayout>

初始化控件主要包括创建tab项,为其添加点击事件监听,创建要用的Fragment对象,为ViewPager创建adapter,关联tab与viewpager,主要代码如下:

    mTabLayout = findViewById(R.id.tablayout);
    mViewPager = findViewById(R.id.viewpager);
    titles=new ArrayList<>();

    titles.add("闰土");
    titles.add("鲁迅");
    titles.add("周树人");

    for (int i = 0; i < 2; i++) {
        TabLayout.Tab tab = mTabLayout.newTab();
        tab.setText(titles.get(i));
        mTabLayout.addTab(tab);
    }

    mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            Toast.makeText(MainActivity.this, tab.getText(), Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {

        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });

    mFragmentArrayList = new ArrayList<>();
    mFragmentArrayList.add(CommonFragment.newInstance("kk", "cav"));
    mFragmentArrayList.add(SnFragment.newInstance("rr", "tt"));

    mViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) {
        @Override
        public Fragment getItem(int i) {
            return mFragmentArrayList.get(i);
        }

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

    mTabLayout.setupWithViewPager(mViewPager);