如何让SearchView填充Toolbar中的剩余空间?
解决Toolbar左侧图标+中间填充SearchView+右侧图标布局问题
我之前也踩过ActionMenuView的同款坑!默认菜单布局的逻辑确实有点“不听话”,给你两个亲测有效的方案,按需选择:
方案一:通过代码修正ActionMenuView布局(保留原有菜单配置)
如果你已经用菜单系统定义了三个菜单项,这个方案可以快速解决问题:
- 先确保你的menu.xml配置正确,用
android:orderInCategory控制菜单项顺序:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <!-- 左侧图标 --> <item android:id="@+id/action_left_icon" android:icon="@drawable/ic_left_icon" android:orderInCategory="1" app:showAsAction="always" /> <!-- 中间SearchView --> <item android:id="@+id/action_search" android:title="@string/search" android:orderInCategory="2" app:actionViewClass="androidx.appcompat.widget.SearchView" app:iconifiedByDefault="false" app:searchIcon="@drawable/search_action_bar_icon" app:showAsAction="always|collapseActionView" /> <!-- 右侧图标 --> <item android:id="@+id/action_right_icon" android:icon="@drawable/ic_right_icon" android:orderInCategory="3" app:showAsAction="always" /> </menu>
- 在Activity/Fragment的
onCreateOptionsMenu中调整布局参数:
override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.your_menu, menu) // 获取SearchView实例 val searchItem = menu.findItem(R.id.action_search) val searchView = searchItem.actionView as SearchView // 找到承载菜单项的ActionMenuView,它是Toolbar的第一个子View val actionMenuView = toolbar.getChildAt(0) as ActionMenuView // 把ActionMenuView的宽度设为MATCH_PARENT,让它填充Toolbar横向空间 actionMenuView.layoutParams = Toolbar.LayoutParams( Toolbar.LayoutParams.MATCH_PARENT, Toolbar.LayoutParams.MATCH_PARENT ) // 给SearchView的父容器设置weight(SearchView被包裹在一个容器里) val searchViewParent = searchView.parent as ViewGroup val params = searchViewParent.layoutParams as LinearLayoutCompat.LayoutParams params.width = 0 params.weight = 1f searchViewParent.layoutParams = params // 可选:去掉SearchView默认的左右内边距,让布局更紧凑 searchView.setPadding(0, 0, 0, 0) return true }
原理:默认ActionMenuView的宽度是wrap_content,导致weight属性失效。先把它改成match_parent占满Toolbar空间,再给SearchView的父容器设置weight=1,就能让SearchView自动填充中间剩余区域,左右图标自然留在两侧。
方案二:自定义Toolbar布局(完全可控)
如果觉得菜单系统限制太多,直接自定义Toolbar布局是最稳妥的方法:
- 创建自定义Toolbar布局
layout/custom_toolbar.xml:
<?xml version="1.0" encoding="utf-8"?> <androidx.appcompat.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/custom_toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" android:elevation="4dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_vertical" android:orientation="horizontal"> <!-- 左侧图标 --> <ImageView android:id="@+id/left_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="16dp" android:src="@drawable/ic_left_icon" android:clickable="true" android:focusable="true"/> <!-- 中间SearchView,通过weight填充剩余空间 --> <androidx.appcompat.widget.SearchView android:id="@+id/search_view" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:layout_marginStart="16dp" android:layout_marginEnd="16dp" app:iconifiedByDefault="false" app:searchIcon="@drawable/search_action_bar_icon"/> <!-- 右侧图标 --> <ImageView android:id="@+id/right_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="16dp" android:src="@drawable/ic_right_icon" android:clickable="true" android:focusable="true"/> </LinearLayout> </androidx.appcompat.widget.Toolbar>
- 在Activity布局中引用这个自定义Toolbar:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <include layout="@layout/custom_toolbar"/> <!-- 页面其他内容 --> </LinearLayout>
- 在Activity的
onCreate中配置Toolbar:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val toolbar = findViewById<Toolbar>(R.id.custom_toolbar) setSupportActionBar(toolbar) // 隐藏默认标题,因为我们用了自定义布局 supportActionBar?.setDisplayShowTitleEnabled(false) // 设置图标点击事件 findViewById<ImageView>(R.id.left_icon).setOnClickListener { // 左侧图标逻辑 } findViewById<ImageView>(R.id.right_icon).setOnClickListener { // 右侧图标逻辑 } // 配置SearchView的搜索监听等逻辑 val searchView = findViewById<SearchView>(R.id.search_view) }
这个方案的优势是完全掌控布局细节,不用受ActionMenuView的默认行为限制,调整内边距、大小都非常灵活。
内容的提问来源于stack exchange,提问作者Luka Govedič
相关产品推荐
相关产品推荐

