Skip to content

Latest commit

 

History

History
284 lines (221 loc) · 12.6 KB

1.MaterialToolbar简介.md

File metadata and controls

284 lines (221 loc) · 12.6 KB

1.MaterialToolbar简介

Actionbar简介

从Android 3.0(API 11)开始,所有使用默认主题背景的Activity均使用ActionBar作为应用栏。不过,经过不同Android版本的演化,原生ActionBar的行为会有所不同,具体取决于设备用的是哪个版本的Android系统。所以Android提供了Toolbar,可以让这些功能在任何设备上保持一致。 所以,你应用使用支持库中的Toolbar来实现Activity的应用栏,来确保你的应用能在最大范围的设备上保持一致的行为。

在使用的时候你会发现除了androidx.appcompat.widget.Toolbar之后还有一个com.google.android.material.appbar.MaterialToolbar。 MaterialToolbar is a Toolbar that implements certain Material features, such as elevation overlays for Dark Themes.

使用

  • 禁止Action Bar
    ToolBar相当于是ActionBar的替代版,因此需要制定一个不带ActionBar的主题, 可以通过自定义theme继承xxx.NoActionBar或者在theme中通过以下配置来进行禁用ActionBar

    <item name="windowActionBar">false</item>
    <item name="android:windowNoTitle">true</item>

    Image
    里面没有colorAccent的颜色,唯独colorAccent这个属性比较难理解,它不是用来指定Checkbox等某一个按钮的颜色,而是更多表达了一个强调的意思,比如一些控件的选中状态也会使用colorAccent的颜色。

  • 确保Activity继承自AppCompatActivity

  • 在布局文件中进行声明 menu的实现如下:

<menu 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" tools:context=".MainActivity">

        <item
            android:id="@+id/action_search"
            android:title="@string/action_search"
            android:orderInCategory="100"
            android:icon="@drawable/ic_action_search"
            app:showAsAction="ifRoom" />

        <item
            android:id="@+id/action_settings"
            android:title="@string/action_settings"
            android:orderInCategory="100"
            app:showAsAction="never" />

</menu>

app:showAsAction属性用于指定操作是否应在应用栏中显示为按钮。如果您设置了app:showAsAction="ifRoom",那么只要应用栏中有足够的空间,此操作便会显示为按钮;如果空间不足,无法容纳的操作就会被发送到溢出菜单。如果您设置了app:showAsAction="never",此操作会始终列在溢出菜单中,而不会显示在应用栏中。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.google.android.material.appbar.MaterialToolbar
        android:id="@+id/tb_main"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <com.google.android.material.textview.MaterialTextView
        android:id="@+id/mtv_main"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="hahahhd"
        android:textSize="20sp" />
</LinearLayout>
 override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val mMaterialToolbar = findViewById<MaterialToolbar>(R.id.tb_main)
        mMaterialToolbar.navigationIcon = getDrawable(R.drawable.vct_menu)
        mMaterialToolbar.inflateMenu(R.menu.menu_toolbar_main)
        mMaterialToolbar.title = "title"
        mMaterialToolbar.setNavigationOnClickListener {
            Snackbar.make(mMaterialToolbar, "click", Snackbar.LENGTH_SHORT).show()
        }
        mMaterialToolbar.setOnMenuItemClickListener {
            Log.e("@@@", "lll")
            true
        }
     
        // 将ToolBar设置为ActionBar,这样一设置后他就能像ActionBar一样直接显示menu目录中的菜单资源如果不用该方法,那ToolBar就只是一个普通的View,对menu要用inflateMenu去加载布局。
        // setSupportActionBar(mMaterialToolbar);
        // getSupportActionBar().setDisplayShowHomeEnabled(true);
    }

如果Toolbar仅仅是用来对以往的ActionBar做一次替换,那也太没创意啦!完全没必要去替换了,因为它们表现出来的都是一样的,而且并没有让我们觉得用起来比ActionBar方便。那为啥要替换呢,总应该有他的理由吧:ActionBar是固定在顶部,并不能移动,我觉得这是最大的不好,而我们的ToolBar可以让我们随便摆放,就就可以带来很多灵活性和效果啦!

接下来我们看一下ToolBar中具体有哪些内容:

Image

我们可以通过对应的方法来修改他们的属性:
Image

ActionBar最左侧的这个按钮就叫做HomeAsUp按钮,它默认的图标是一个返回的箭头,含义是返回上一个活动,可以通过setDisplayHomeAsUpEnabled来让导航按钮显示出来。 可以在onOptionsItemSelected()方法中对HomeAsUp安阿牛的点击事件进行处理,HomeAsUp按钮的id永远都是android.R.id.home。 如需在 Activity 中支持向上功能,您需要声明 Activity 的父级。为此,您可以在应用清单中设置 android:parentActivityName 属性。 例如,假设应用有一个名为 MainActivity 的主 Activity 和一个子 Activity。以下清单代码声明了这两个 Activity,并指定了父/子关系:

 <application ... >
        ...

        <!-- The main/home activity (it has no parent activity) -->

        <activity
            android:name="com.example.myfirstapp.MainActivity" ...>
            ...
        </activity>

        <!-- A child of the main activity -->
        <activity
            android:name="com.example.myfirstapp.MyChildActivity"
            android:label="@string/title_activity_child"
            android:parentActivityName="com.example.myfirstapp.MainActivity" >

            <!-- Parent activity meta-data to support 4.0 and lower -->
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="com.example.myfirstapp.MainActivity" />
        </activity>
    </application>

如需为具有父 Activity 的 Activity 启用“向上”按钮,请调用应用栏的 setDisplayHomeAsUpEnabled() 方法。通常,您需要在创建 Activity 时调用此方法。例如,以下 onCreate() 方法将 Toolbar 设置为 MyChildActivity 的应用栏,然后启用该应用栏的“向上”按钮。

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_my_child)

        // my_child_toolbar is defined in the layout file
        setSupportActionBar(findViewById(R.id.my_child_toolbar))

        // Get a support ActionBar corresponding to this toolbar and enable the Up button
        supportActionBar?.setDisplayHomeAsUpEnabled(true)
    }
    

​您不需要在 Activity 的 onOptionsItemSelected() 方法中捕获向上操作。相反,该方法应该调用其父类,如响应操作中所示。该父类方法会根据应用清单的规定,通过导航到父 Activity 响应“向上”操作。

对于ToolBar中的Menu部分我们可以通过一下方法来设置:

toolbar.inflateMenu(R.menu.menu_main);
toolbar.setOnMenuItemClickListener();

或者也可以直接在ActivityonCreateOptionsMenuonOptionsItemSelected来处理。

DrawerLayout+Toolbar

Image

现在想实现侧边栏结合Toolbar的效果。

<style name="Theme.JetpackSample.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />

<style name="Theme.JetpackSample.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.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:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <com.google.android.material.appbar.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            // 指定状态栏的theme,例如状态栏中文字是灰还是白                                                         
            android:theme="@style/Theme.JetpackSample.AppBarOverlay">

            <com.google.android.material.appbar.MaterialToolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                // 指定menu等弹出的效果                                                
                app:popupTheme="@style/Theme.JetpackSample.PopupOverlay" />

        </com.google.android.material.appbar.AppBarLayout>

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#00f" />

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_marginEnd="16dp"
            android:layout_marginBottom="16dp"
            app:srcCompat="@android:drawable/ic_dialog_email" />

    </androidx.coordinatorlayout.widget.CoordinatorLayout>

    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>

把Toolbar设置成ActionBar,可以让我们少处理很多点击逻辑。

class MainActivity : BaseActivity() {
    private val binding by viewBinding(ActivityMainBinding::inflate)
    private lateinit var actionBarDrawerToggle: ActionBarDrawerToggle
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding.fab.setOnClickListener { view ->
            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                .setAction("Action", null).show()
        }

        actionBarDrawerToggle = ActionBarDrawerToggle(
            this,
            binding.drawerLayout,
            binding.toolbar,
            R.string.open,
            R.string.close
        )
        binding.drawerLayout.addDrawerListener(actionBarDrawerToggle)
        actionBarDrawerToggle.syncState()
        setSupportActionBar(binding.toolbar)
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        // Inflate the menu; this adds items to the action bar if it is present.
        menuInflater.inflate(R.menu.main, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        // navigation icon的点击交给actionbardrawertoggle来处理
        if (actionBarDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        // 处理其他menu的点击事件
        when (item.itemId) {
            R.id.action_settings -> Log.e("@@@", "settings")
        }
        return super.onOptionsItemSelected(item);
    }
}

ActionBarDrawerToggle 的作用:

  • 改变android.R.id.home返回图标。

  • Drawer拉出、隐藏,带有android.R.id.home动画效果。

  • 监听Drawer拉出、隐藏;

  • 下一篇:2.NavigationView简介