最近在用toolbar,然后在使用searchview搜索的时候,遇到一个问题,无论如何,那个toolbar中通过menu还是不能修改searchview的图标和其他一些颜色属性的。
如图:
解决方法:
//通过找到search view里面的一个叫做appcompatImageViewbutton来修改图标和颜色
AppCompatImageViewbutton=(AppCompatImageView)searchView.findViewById(android.support.v7.appcompat.R.id.search_button);
button.setImageResource(R.mipmap.ic_search);
//搜索的那个X的删除图标也是可以通过这种方式来修改的
//下面是在搜索栏的字体,设置为白色,默认也是黑色
TextViewtextView=(TextView)searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
textView.setTextColor(Color.WHITE);
解决思路:
如果你看到上面的解决方法已经解决了问题,那就祝贺你。如果有兴趣的话可以看看这里的解决思路,它可以帮助你在以后遇到其他问题的时候,根据相同的思路来思考解决问题
这个问题肯定大家也会遇到,因为我在网上搜解决方法的时候也看到了许多的问题贴,甚至是stackoverflow上面也搜过,也有一些解决方案。
最多的三种:
第一种
int search_mag_icon_id = mSearchView.getContext().getResources().getIdentifier("android:id/search_mag_icon", null, null);
ImageView mSearchViewIcon = (ImageView) mSearchView.findViewById(search_mag_icon_id);// 获取搜索图标
mSearchViewIcon.setImageResource(R.drawable.ic_menu_search_holo_dark);
mSearchView.setIconifiedByDefault(false);(设置搜索图标在编辑框外,ture时在框内)。
用此方法修改时成功了,但是只要一设置mSearchView.setIconifiedByDefault(true),搜索图标就右成了系统的图标。
第二种
第三种
第一种方法我试过,不行,会报空指针,因为通过identifier("")来找到对应的id,我调试过,id能够找到,但是不确定是不是对的,不过你还是不能通过searchview.findviewbyid 来找到所谓的imageview textview什么的,空指针。
当时我就照着这种思路,然后在调试的时候去看了searchview的mChildern、mChildren的mChildren,子孙都去找了,然后看了一下他们的id好像已经不是所谓的android:id/search_mag_icon 了,而是app:id/search_mag_icon, 不信你可以看看
但是,即便是改成后面那个也不行,还是找不到,依旧空指针,我也不知道怎么回事了。
第二种我也试过,对于我而言不行。大家都知道现在基本很多都是用appcompatActivity了,所以现在所用的主题一般也都是appcompat相关的主题了。没有谁还在用老主题的。
即便你还在用老主题,但是,它也只是根据老主题的两种 holo.light 、dark来改变searchview 那个搜索图标的颜色,白色、黑色,但是根本满足不了我们的要求。
还有,如果要用这种修改主题的方式的话,就必须使用actionbar,但是你知道现在我们都是用toolbar来替换actionbar,这个没话说,如果在activity中直接使用setActionbar就可以了。
但是,我们在fragment里面使用toolbar呢?那就不行了,因为多数情况下,我们的主题都是 noActionbar的,因为我们要自定义toolbar呀。而且对于现在这种 一个activity下面装多个fragment来实现那种底部导航的潮流结构中,一般我们的每个fragment的toolbar都是不一样的,所以不可能用一个activity的toolbar来动态切换或者改变,那样太复杂了。
第三种,亲测过,也是没有什么用,因为其实他修改的是toolbar的字体颜色,还有一些默认图标的颜色,但是它不可以修改,searchview展开之后的搜索的框中的字体颜色
所以的所以,总而又言之就是,上述三种亲测,不适用。
解决核心思路:
重点来了,既然主题什么的不行,那我们可以依照第一种方法的思路来换个角度试试。
很多时候你会发现,官方的一些组件,里面有很多成员变量或者里面有很多子view,但是只暴露出很少的方法去让你修改一些属性。很多是private的方法,这时候你会想如果是public该多好啊。
所以,你就会想要去继承重写什么的,但是那样我觉得有点麻烦。
于是,我就想,你看,如果找到里面的子view,那不就可以通过子view来修改里面的内容了啊。比如,searchview里面的那个放大镜的那个图标,肯定应该是一个imageview吧,如果我们能通过什么方式找出来,那么就可以修改了嘛。
很常见的就是通过findviewbyId,所以就去找ID吧。
那么现在就要去看看源码了,看了searchview的源码。
id的名字你也看见了,不过它们没有在自己的工程里,它是在support.v7里面的。
于是去里面找,找android.support.v7.appcompat.R.id.search_button就能找到了,
基本就大功告成了,然后你就通过search findviewbyid 找出来,然后就可以随意设置了,真爽!!
其他的一些子view也是一样,都可以找出来然后自己随意改!
好爽!总结一下:
如果一个组件是很多子view混合构成的,你就可以通过找到子view,然后去修改子view,就能达到修改组件的效果了。
希望对大家有用,谢谢