活动工具栏中的SearchView并过滤到片段

问题描述 投票:0回答:2

我在活动中给了 SearchView 自定义工具栏,并且过滤器数据进入片段。当我单击搜索图标时,工具栏尺寸增大。该活动中使用了导航栏,可能是问题? 它正在处理没有导航栏的单独活动。vb

这是我的代码: 活动.xml:

<android.support.design.widget.AppBarLayout
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="wrap_content"
app:elevation="5dp">

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    style="@style/Toolbar"
    app:contentInsetEnd="5dp"
    app:contentInsetLeft="15dp"
    app:contentInsetRight="5dp"
    app:contentInsetStart="15dp"
    app:theme="@style/AppTheme.Toolbar"
    app:popupTheme="@style/AppTheme.PopupOverlay"
    app:contentInsetStartWithNavigation="15dp"
    app:titleTextColor="@color/colorWhite"
    tools:targetApi="lollipop">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/toolbar_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_centerInParent="true"
            android:layout_gravity="start"
            android:gravity="center"
            android:text=""
            android:textAllCaps="false"
            android:textColor="@color/colorWhite"
            android:textSize="16sp"
            android:textStyle="bold"
            tools:ignore="RelativeOverlap" />


        <TextView
            android:id="@+id/toolbar_student_details"
            android:layout_width="120dp"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:layout_gravity="end"
            android:gravity="center"
            android:text=""
            android:textAllCaps="false"
            android:textColor="@color/colorWhite"
            android:textSize="16sp"
            tools:ignore="RelativeOverlap" />

        <Spinner
            android:id="@+id/toolbar_student_details_spinner"
            android:spinnerMode="dropdown"
            android:layout_width="120dp"
            android:backgroundTint="@color/colorWhite"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:layout_gravity="end"
            android:textAllCaps="false"
            android:textColor="@color/colorWhite"
            android:textSize="16sp"
            tools:ignore="RelativeOverlap"
            android:visibility="gone"
            >
        </Spinner>

        <ImageView
            android:id="@+id/admin_image"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:layout_marginEnd="10dp"
            android:layout_marginRight="10dp"
            android:contentDescription="@string/app_name"
            android:visibility="gone" />
    </RelativeLayout>


</android.support.v7.widget.Toolbar>

    </android.support.design.widget.AppBarLayout>

片段代码:

   @Override
   public View onCreateView(@NonNull LayoutInflater inflater, 
 ViewGroup 
container, Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View rootView= 
       inflater.inflate(R.layout.fragment_staff_fragment_admin, 
            container, false);
    setHasOptionsMenu(true);
    ButterKnife.bind(this, rootView);
    return rootView;
}

    @Override
   public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {

    getBaseActivity().getMenuInflater().inflate(R.menu.menu_main, 
     menu);
    SearchView searchView;
    // Associate searchable configuration with the SearchView
    SearchManager searchManager = (SearchManager)getBaseActivity(). 
   getSystemService(Context.SEARCH_SERVICE);
    searchView = (SearchView) menu.findItem(R.id.action_search)
            .getActionView();
    assert searchManager != null;
    searchView.setSearchableInfo(searchManager
            .getSearchableInfo(getBaseActivity().getComponentName()));
    searchView.setMaxWidth(Integer.MAX_VALUE);

    // listening to search query text change
    searchView.setOnQueryTextListener(new 
     SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            // filter recycler view when query submitted
            mAdapter.getFilter().filter(query);
            return false;
        }

        @Override
        public boolean onQueryTextChange(String query) {
            // filter recycler view when text is changed
            mAdapter.getFilter().filter(query);
            return false;
        }
    });
 }

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_search) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

enter image description here

android android-fragments searchview
2个回答
0
投票

您应该监听

Activity
中的变化并将结果发送到您的
Fragment
,因为您的
SearchView
位于
Activity
内(在自定义
Toolbar
中)。您可能面临的问题之一是,当您调用它时,searchview 为空。

如果您使用

Android 架构组件
MVVM 模式,我建议您通过 ViewModel 执行此操作,如下所示:

  1. 聆听您的活动
  2. 的变化
// listening to search query text change
    searchView.setOnQueryTextListener(new 
     SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            //filter the data in step 2
            return false;
        }

        @Override
        public boolean onQueryTextChange(String query) {
            // filter data in step 2
            return false;
        }
    });
  1. 将查询发送到 ViewModel 函数以过滤数据

在您的活动中:

        ...
        @Override
        public boolean onQueryTextSubmit(String query) {
            //filter the data
            viewModel.filterData(query);
            return false;
        }
        ...

在你的ViewModel中:

       public List<String> listOfData = getListOfData();
       public LiveData<List<String>> searchResults = new MutableLiveData(listOfData);

       // filter list of data when query submitted
       public void filterData(String query) {
            //filter outside of your RecyclerView Adapter through your listOfData variable
            searchResults.value = getFilter().filter(query);
       }

       public LiveData<List<String>> getSearchResults() {
            return searchResults;
       }

通过

LiveData
将结果设置在你的
searchResults.value
上,你可以直接从你的
Fragment
听到它的变化,从而完成步骤 3 中通过这个变量,你的
Activity
和你的
Fragment
RecyclerView
之间的通信.

  1. 观察
    ViewModel
    内的
    Fragment
    变量并更新适配器

在您的片段中

        override fun onActivityCreated(savedInstanceState: Bundle?) {
            super.onActivityCreated(savedInstanceState)


            viewModel.getSearchResults().observe(this, { searchResults->
                Log.w("onActivityCreated()", "new search list received :" +searchResults)
                mAdapter.updateList(searchResults)
                listItemsAdapter.notifyDataSetChanged()
            });

    }

通过这些更改,您可以从 Activity

SearchView
进行过滤,并将结果发送到应该可以工作的
Fragment RecyclerView
。如果您使用其他模式,重要的是将查询从您的
Activity
发送到您的
Fragment
,而不是仅在您的
Fragment
中监听。

如果您尚未使用这些,我建议您查看 AACMVVM。您可以在Android 开发者文档中找到有关这些概念的更多信息。

希望这有帮助,祝你好运。


0
投票

在我的应用程序中,我在 ViewPager + TabLayout 中有几个片段。我不明白你如何基本上实时过滤 RecyclerView 。对我来说,你的概念似乎只是过滤一次,即只要你不再次调用该方法,列表就不会被过滤。您还有更多见解吗?

© www.soinside.com 2019 - 2024. All rights reserved.