关于SearchView这个控件还是想要使用搜索功能的时候知道的,之前准备自定义做一个,但是每次自定义控件的时候就头疼的要死,何况还不一定成功,所以直接拿V7库里面的SearchView来用啦。
首先是在网上查阅的资料,看到一篇写的非常好的教学文章,可以说是该怎么用基本上一目了然了,下面是文章地址:
http://www.jianshu.com/p/7c1e78e91506
好了,接下来准备使用这个控件了,大概做成的效果就是输入想要查询的东西,然后从根据API返回结果。
首先做一个搜索按钮去进入搜索界面:
<ImageButton
android:id="@+id/ib_search_button"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_alignParentRight="true"
android:layout_marginRight="14dp"
android:layout_marginTop="14dp"
android:background="@drawable/search_selector"/>
然后是点击的效果:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false" android:drawable="@drawable/search_black" />
<item android:state_focused="true" android:drawable="@drawable/search_black" />
<item android:state_pressed="true" android:drawable="@drawable/search_white" />
</selector>
看一下点击效果吧:
这个做好后就是点击该按钮进入另外一个活动,用于显示搜索界面了,需要用到RecyclerView显示搜索到的新闻条目,以及这篇笔记的主角————SearchView。同时,为了美观一点,也使用到了CoordinatorLayout搭配AppBarLayout,至于需要添加哪些库就不再说了,下面就是布局文件activity_search.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@android:color/holo_blue_light"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/Theme.AppCompat.Dialog"
app:layout_scrollFlags="scroll|enterAlways|snap">
<android.support.v7.widget.SearchView
android:id="@+id/sv_start_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
<LinearLayout
android:gravity="center"
android:id="@+id/ll_search_result"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="空空如也"
android:id="@+id/tv_search_status"
android:textColor="@android:color/holo_red_dark"
android:gravity="center"
android:textSize="30sp"
android:visibility="visible"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<ProgressBar
android:id="@+id/pb_search_loading"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
之后就是如何去使用SearchView了,关于SearchView有几个关键的东西是需要知道的:
/*------------------ SearchView有三种默认展开搜索框的设置方式,区别如下: ------------------*/
//设置搜索框直接展开显示。左侧有放大镜(在搜索框中) 右侧有叉叉 可以关闭搜索框
mSearchView.setIconified(false);
//设置搜索框直接展开显示。左侧有放大镜(在搜索框外) 右侧无叉叉 有输入内容后有叉叉 不能关闭搜索框
mSearchView.setIconifiedByDefault(false);
//设置搜索框直接展开显示。左侧有无放大镜(在搜索框中) 右侧无叉叉 有输入内容后有叉叉 不能关闭搜索框
mSearchView.onActionViewExpanded();
上面就直接复制粘贴人家的成果了,然后还有SearchView的一些监听事件:
//搜索框展开时后面叉叉按钮的点击事件
mSearchView.setOnCloseListener(new SearchView.OnCloseListener() {
@Override
public boolean onClose() {
Toast.makeText(getApplicationContext(), "Close", Toast.LENGTH_SHORT).show();
return false;
}
});
//搜索图标按钮(打开搜索框的按钮)的点击事件
mSearchView.setOnSearchClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "Open", Toast.LENGTH_SHORT).show();
}
});
//搜索框文字变化监听
mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String s) { //提交最终结果的监听
Log.e("CSDN_LQR", "TextSubmit : " + s);
return false;
}
@Override
public boolean onQueryTextChange(String s) { //输入文字变化时候的监听
Log.e("CSDN_LQR", "TextChange --> " + s);
return false;
}
});
好了,下面是最后的代码,首先是RecyclerView适配器的部分,RecyclerView的用法我老记不住,所以好记星不如烂笔头,就记录于此:
public class MySearchNewsRecyclerAdapter extends RecyclerView.Adapter<MySearchNewsRecyclerAdapter.ViewHolder> {
private Context context;
private List<NewsSearchResultBean.ResultBeanX.ResultBean.ListBean> dataList;
public MySearchNewsRecyclerAdapter(Context context, List<NewsSearchResultBean.ResultBeanX.ResultBean.ListBean> dataList) {
this.context = context;
this.dataList = dataList;
}
static class ViewHolder extends RecyclerView.ViewHolder{
TextView tv_title;
TextView tv_time;
ImageView iv_icon;
CardView cardview;
public ViewHolder(View itemView) {
super(itemView);
tv_title = (TextView) itemView.findViewById(R.id.tv_title);
tv_time = (TextView) itemView.findViewById(R.id.tv_time);
iv_icon = (ImageView) itemView.findViewById(R.id.iv_icon);
cardview = (CardView) itemView.findViewById(R.id.listview_cardview);
}
}
@Override
public MySearchNewsRecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (context != null){
context = parent.getContext();
}
View view = View.inflate(context, R.layout.listview_detail, null);
final ViewHolder viewHolder = new ViewHolder(view);
viewHolder.cardview.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = viewHolder.getAdapterPosition();
Intent intent = new Intent(context, NewsDetailActivity.class);
intent.putExtra("Content", dataList.get(position).getContent());
intent.putExtra("ImageUrl", dataList.get(position).getPic());
intent.putExtra("Title", dataList.get(position).getTitle());
context.startActivity(intent);
}
});
return viewHolder;
}
@Override
public void onBindViewHolder(MySearchNewsRecyclerAdapter.ViewHolder holder, int position) {
NewsSearchResultBean.ResultBeanX.ResultBean.ListBean data = dataList.get(position);
String title = data.getTitle();
String time = data.getTime();
String imageUrl = data.getPic();
holder.tv_title.setText(title);
holder.tv_time.setText(time);
if (imageUrl != null){
Glide.with(context).load(imageUrl)
.diskCacheStrategy(DiskCacheStrategy.RESULT)
.placeholder(R.drawable.default_pic)
.skipMemoryCache(false)
.dontAnimate()
.error(R.drawable.no_picture)
.into(holder.iv_icon);
}
}
@Override
public int getItemCount() {
return dataList.size();
}
}
最后是SearchActivity的全部代码:
public class SearchActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private Toolbar toolbar;
private LinearLayout ll_search_result;
private SearchView searchView;
private ProgressBar pb_search_loading;
private TextView tv_search_status;
private List<NewsSearchResultBean.ResultBeanX.ResultBean.ListBean> dataList;
private GridLayoutManager layoutManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
initView();
initData();
setListener();
}
private void initView(){
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
layoutManager = new GridLayoutManager(this, 1);
recyclerView.setLayoutManager(layoutManager);
toolbar = (Toolbar) findViewById(R.id.toolbar);
tv_search_status = (TextView) findViewById(R.id.tv_search_status);
ll_search_result = (LinearLayout) findViewById(R.id.ll_search_result);
searchView = (SearchView) findViewById(R.id.sv_start_search);
pb_search_loading = (ProgressBar) findViewById(R.id.pb_search_loading);
toolbar.setTitle("搜索");
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if(actionBar != null){
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
private void initData(){
}
private void setListener(){
searchView.setIconified(false); //设置默认展开
searchView.setQueryHint("请输入想要搜索的新闻"); //设置输入框提示语
//设置文本监听
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
LogUtil.e("提交结果" + query);
String url = Constants.getNewsSearchResult(query);
LogUtil.e(url);
pb_search_loading.setVisibility(View.VISIBLE);
tv_search_status.setText("查询中...");
getDataFromNet(url);
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
LogUtil.e(newText);
return false;
}
});
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case android.R.id.home:
finish();
break;
default:break;
}
return true;
}
private void getDataFromNet(String url){
HttpUtil.sendOkHttpRequest(url, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
LogUtil.e("请求网络失败" + e.getMessage());
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(SearchActivity.this, "请求网络失败,请重试", Toast.LENGTH_SHORT).show();
pb_search_loading.setVisibility(View.GONE);
tv_search_status.setText("空空如也");
}
});
}
@Override
public void onResponse(Call call, Response response) throws IOException {
LogUtil.e("请求网络成功");
String data = response.body().string();
LogUtil.e(data);
NewsSearchResultBean bean = HttpUtil.parsedNewsSearchJsonWithGson(data);
final String msg = bean.getMsg();
dataList = bean.getResult().getResult().getList();
runOnUiThread(new Runnable() {
@Override
public void run() {
if (msg.equals("查询成功")){
Toast.makeText(SearchActivity.this, "查询成功", Toast.LENGTH_SHORT).show();
// ll_search_result.setVisibility(View.GONE);
recyclerView.setAdapter(new MySearchNewsRecyclerAdapter(SearchActivity.this, dataList));
pb_search_loading.setVisibility(View.GONE);
tv_search_status.setVisibility(View.GONE);
// tv_search_status.setText(dataList.get(0).getContent());
} else {
Toast.makeText(SearchActivity.this, "查询失败", Toast.LENGTH_SHORT).show();
pb_search_loading.setVisibility(View.GONE);
tv_search_status.setText("空空如也");
}
}
});
}
});
}
}
看一下最终效果吧: