亲爱的同窗们我又来了,搬好小板凳准备开车了。。。android
不知道你们平时都用什么听音乐,我我的比较喜欢网易云音乐 (不是作广告,可是我这是干啥呢?),不过如今网易云音乐不能停周董的歌了,实在有些。。。那天忽然想起最近研究的MaterialDesign,就想到的网易云音乐的标题栏是怎么实现的。后来我就各类百度,中于功夫不负有心人,总算是被我刨出来了!其实网易云音乐使用的就是标题上面说的SearchView,其实就是一个搜索的View。那么怎么实现的呢?请听下回分解!bash
开个玩笑,同窗们准备好,立刻开车了。。。app
先简单说明一下,这里主要是讲解SearchView怎么实现网易云音乐的标题栏,可是都是以来Toolbar的,若是你对Toolbar和menu不是很了解的话!ide
请看我公众号的这两篇文章(强势输出一波)布局
上面很详细的讲解了关于Toolbar和menu的使用方法和注意事项!!!this
SearchView是和Toolbar联动,经过menu进行设置的搜索的控件(不知道我这么归纳你能不能懂)。会在Toolbar的右侧出现一个搜索的按钮(系统自带的,也能够进行替换)。当你点击搜索按钮的时候,会出现相应的编辑框进行搜索。当你点击叉号的时候,本次搜索取消,还原成搜索按钮。google
这里针对menu作了一些修改,因此可能和你出现的基本效果不太同样,可是我会把相应的内容贴出来,这样便于像我同样的懒癌患者,能很快的实现效果。毕竟开发项目紧的时候我是不会管是怎么实现的!!!先看一下基本功能的效果图spa
相信你看了以前的那两篇文章的话,很快就能写出下面这个标题栏的。
<?xml version="1.0" encoding="utf-8"?>
<!--仿网易云音乐的menu实现-->
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/search"
android:icon="@drawable/ic_search_black_24dp"
android:title="搜索"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always" />
<item
android:id="@+id/other"
android:title="其余内容"
app:showAsAction="never" />
</menu>
复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
tools:context="com.jinlong.newmaterialdesign.toolbar.YunActivity">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#ff0000"
app:popupTheme="@style/ToolbarTheme"
app:navigationIcon="@mipmap/back_icon">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="云Toolbar的实现"
android:textColor="@android:color/white"
android:textSize="18sp" />
</android.support.v7.widget.Toolbar>
</LinearLayout>
复制代码
public class YunActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_yun);
initToolbar();
}
private void initToolbar() {
Toolbar toolbar = findViewById(R.id.toolbar);
toolbar.setTitle("");
setSupportActionBar(toolbar);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.menu_yun,menu);
return super.onCreateOptionsMenu(menu);
}
}
复制代码
上面代码跑一下,紧接着就能够看见上面的内容了!
由于在初始化SearcheView,须要对相应的menu进行操做,因此通常都会在
onCreateOptionsMenu(Menu menu)
中进行获取。具体代码以下:
//获取SearchView对象
MenuItem searchItem = menu.findItem(R.id.search);
mSearchView = (SearchView) searchItem.getActionView();
复制代码
这里注意一点,就是在初始化SearchView的时候,也可使用MenuItemCompat.getActionView(searchItem);
进行获取的,只不过是过期了。。。因此见到了不要说不知道就行
setOnQueryTextListener(OnQueryTextListener listener)
setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
//在文字改变的时候回调,query是改变以后的文字
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
//文字提交的时候哦回调,newText是最后提交搜索的文字
return false;
}
});
复制代码
上面的内容能够实现简单的搜索了?其实我我的以为这一个监听还不够?为何这么说呢?由于你想要控制Fragment的切换,没有相应的时间点,或者说是没找到时机进行Fragment的切换问题,当时我想了很久,后来看见源码的时候,我才发现,其实这种时机google工程是早就替咱们想好了,其实我以为咱们能想到的,google工程师会替咱们实现的!
这样就存在相应的时间点了,你在进来的时候开启一个事物,放进去一个Fragment(这里若是你想加动画效果的话,你可使用ViewPager,而后经过设置显示那个的方法进行切换.其实事物也是能够设置动画的,看你怎么选择吧)。当你点击关闭的时候。再将以前的Fragment替换掉就能够了。这里为了你们能更好的理解,我仍是用代码实现一下吧!先看下效果(虚拟机录得有点渣!)
public class YunActivity extends AppCompatActivity {
private static final String TAG = YunActivity.class.getSimpleName();
private SearchView mSearchView;
private ViewPager mVpContent;
private SearchFragment mSearchFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_yun);
Log.e(TAG, "onCreate: ");
initToolbar();
initViewPager();
}
private void initToolbar() {
Toolbar toolbar = findViewById(R.id.toolbar);
toolbar.setTitle("");
setSupportActionBar(toolbar);
}
private void initViewPager() {
mVpContent = findViewById(R.id.vp_content);
List<Fragment> list = new ArrayList<>();
DefaultFragment defaultFragment = new DefaultFragment();
list.add(defaultFragment);
mSearchFragment = new SearchFragment();
list.add(mSearchFragment);
MainVPAdapter adapter = new MainVPAdapter(getSupportFragmentManager(), list);
mVpContent.setAdapter(adapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
Log.e(TAG, "onCreateOptionsMenu: ");
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.menu_yun, menu);
//获取SearchView对象
MenuItem searchItem = menu.findItem(R.id.search);
mSearchView = (SearchView) searchItem.getActionView();
//设置相应的监听,文字变化的监听
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
//在文字改变的时候回调,query是改变以后的文字
mSearchFragment.setSearchStr(query);
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
//文字提交的时候哦回调,newText是最后提交搜索的文字
return false;
}
});
mSearchView.setOnSearchClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//开始搜索的时候,设置显示搜索页面
mVpContent.setCurrentItem(1);
}
});
mSearchView.setOnCloseListener(new SearchView.OnCloseListener() {
@Override
public boolean onClose() {
//关闭搜索按钮的时候,设置显示默认页面
mVpContent.setCurrentItem(0);
return false;
}
});
return super.onCreateOptionsMenu(menu);
}
}
复制代码
这里最主要的就是那几个监听,只要你理解了那几个监听的话基本上就没有问题了。
public class SearchFragment extends Fragment {
private TextView mTvSearch;
public SearchFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_search, container, false);
mTvSearch = rootView.findViewById(R.id.tv_search);
return rootView;
}
/**
* 搜索的内容
*/
public void setSearchStr(String query) {
if (!TextUtils.isEmpty(query))
mTvSearch.setText("搜索的内容是" + query);
}
}
复制代码
这样就能实现相应的效果了。怎么样?不错吧!!!
上面的图是没有提示文字时候显示的样子,怎么添加提示文字呢?
searchView.setQueryHint("相应的提示内容");
复制代码
经过上面的代码就能够添加搜索的提示文字了。
这个搜索按钮是在输入框的内部,当你设置内容的时候,搜索按钮会消失。这个我感受我描述的不太正确,管他呢?大家理解就好。。。
有的产品经理总会有奇葩的需求,想要去掉那个搜索后面的叉号。说不人性。。。只能默默的改了。。。其实个人心里是崩溃的。。。
虽然你能关闭这个图标,可是这样就存在一个问题了,以前写好的关闭切换Fragment的操做在这里就会失效了。怎么解决呢?想了半天,只有处理返回事件了,要不我根本就没有办法知道用户真么时候搜索完成啊?那就只有何时执行返回操做何时算他结束了呗!
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mSearchAutoComplete.isShown()) {
try {
mSearchAutoComplete.setText("");//清除文本
//利用反射调用收起SearchView的onCloseClicked()方法
Method method = mSearchView.getClass().getDeclaredMethod("onCloseClicked");
method.setAccessible(true);
method.invoke(mSearchView);
} catch (Exception e) {
e.printStackTrace();
}
} else {
finish();
}
}
});
复制代码
加上这段代码的话,经过反射拿到SearchView的onDloseClicked(),调用一下就能够了
产品又说了,进到这个页面,默认应该是显示搜索对话框的,用户少操做一步,用户体验好,当时我就说了。那用户就要那样呢?产品说那样的奇葩用户不用管。。。(当时的我啊!满脑壳黑线)
老根产品过不去也不行吧!这里本身看了看搜索图标以为小了,想更改一下!怎么办呢?
就是在页面的Activity的主题中,添加相应的searchViewStyle属性,这个属性能够本身设置的。
<!--SearchView的主题设置-->
<item name="searchViewStyle">@style/SearchViewStyle</item>
<!--SearchView的主题设置-->
<style name="SearchViewStyle" parent="Widget.AppCompat.SearchView">
<!--修改图标的图片-->
<item name="searchIcon">@mipmap/ic_directions_bike_white_24dp</item>
<!--去掉图标-->
<!--<item name="searchHintIcon">@null</item>-->
</style>
复制代码
这里的图片就看你发挥了。。。
当你以为输入框的文字或者提示的文字是黑色比较难看的时候,那么你能够像下面这样修改
//修改searchView的文字颜色
SearchView.SearchAutoComplete mSearchAutoComplete = mSearchView.findViewById(R.id.search_src_text);
//设置输入框内提示文字样式
mSearchAutoComplete.setHintTextColor(getResources().getColor(android.R.color.white));//设置提示文字颜色
mSearchAutoComplete.setTextColor(getResources().getColor(android.R.color.white));//设置内容文字颜色
复制代码
不知道还有没有什么其余的了,我感受有了这些对付大家产品经理就已经足够了,不行桌子上放把刀、要不放个二维码啥的就能够了。。。
但愿个人文章对你有帮助!但愿咱们共同进步。。。see you!
若是你感兴趣,请关注个人二维码