【问题标题】:SearchView implementation inside a particular Fragment特定片段内的 SearchView 实现
【发布时间】:2020-01-09 08:44:00
【问题描述】:

我在我的项目中使用了导航组件。它有一个导航抽屉,只有一个 Activity 和几个片段。问题是,我想将 SearchView 实现到一个特定的片段,该片段将只在该特定片段中可见.. ...... 我怎样才能做到这一点?

我的片段代码:

public class HomeFragment extends Fragment {
FragmentHomeBinding homeBinding;
SharedPreferences preferences;
private DatabaseReference databaseReference;
List<Book> bookList;
RecyclerView.LayoutManager layoutManager;
BookAdapterHome adapter;
String user_key;
NavController navController;


public HomeFragment() {
    // Required empty public constructor
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    homeBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_home, container, false);
    return homeBinding.getRoot();
}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    navController = Navigation.findNavController(view);
    layoutManager = new LinearLayoutManager(getActivity());
    bookList = new ArrayList<>();
    adapter = new BookAdapterHome(bookList);
    homeBinding.allBooksRV.setLayoutManager(layoutManager);
    homeBinding.allBooksRV.setAdapter(adapter);
    databaseReference = FirebaseDatabase.getInstance().getReference("Books");

    preferences = this.getActivity().getSharedPreferences("MyPref", Context.MODE_PRIVATE);
    Boolean hasData = preferences.contains("user_key");
    if (hasData) {
        user_key = preferences.getString("user_key", "");

        PreparingAllData();
        settingUpListView();

    }


}

private void PreparingAllData() {
    databaseReference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            bookList.clear();
            for (DataSnapshot singleBook : dataSnapshot.getChildren()) {
                Book book = singleBook.getValue(Book.class);
                bookList.add(book);
            }
            adapter.notifyDataSetChanged();

        }


        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });


}

private void settingUpListView() {
    adapter.setOnBookClickListener(new BookClickListener() {
        @Override
        public void onBookClick(int position, View v) {
            String bookId = bookList.get(position).getBookId();
            HomeFragmentDirections.ActionHomeToBookDetailsFragment action = HomeFragmentDirections.actionHomeToBookDetailsFragment();
            action.setBookId(bookId);
            navController.navigate(action);


        }

        @Override
        public void onBookLongClick(int position, View v) {


        }
    });

}

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

}

}

我的适配器代码:

public class BookAdapterHome extends RecyclerView.Adapter<BookAdapterHome.BookHolder>  implements Filterable {
List<Book> bookList;
List<Book> bookListFull;
private static BookClickListener bookClickListener;

public BookAdapterHome(List<Book> bookList) {

    this.bookList = bookList;
    bookListFull=new ArrayList<>(bookList);
}

@NonNull
@Override
public BookHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    LayoutInflater layoutInflater =
            LayoutInflater.from(parent.getContext());
    SingleBookBinding bookBinding= DataBindingUtil.inflate(layoutInflater,R.layout.single_book,parent,false);
    return new BookHolder(bookBinding);
}

@Override
public void onBindViewHolder(@NonNull BookHolder holder, final int position) {
    final Book book=bookList.get(position);
    Picasso.get().load(book.getCoverLink()).placeholder(R.drawable.book_place_holder).into(holder.singleBookBinding.bookIV);
    holder.singleBookBinding.bookTitleTV.setText(book.getTitle());
    holder.singleBookBinding.bookEditionTV.setText("Edition: "+book.getEdition());
    holder.singleBookBinding.bookAuthorTV.setText("Author "+book.getAuthor());


}

@Override
public int getItemCount() {
    return bookList.size();
}

@Override
public Filter getFilter() {
    return bookFilter;
}

public class BookHolder extends RecyclerView.ViewHolder{
    private SingleBookBinding singleBookBinding;

    public BookHolder(@NonNull final SingleBookBinding bookBinding) {
        super(bookBinding.getRoot());
        this.singleBookBinding=bookBinding;
         bookBinding.getRoot().setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
                 bookClickListener.onBookClick(getAdapterPosition(),v);
             }
         });

    }
}

public void setOnBookClickListener(BookClickListener listener){
    bookClickListener =listener;
}
Filter bookFilter=new Filter() {
    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        List<Book> filteredBook=new ArrayList<>();
        if(constraint==null ||constraint.length()==0){
            filteredBook.addAll(bookListFull);
        }
        else{
            String filterPattern=constraint.toString().toLowerCase().trim();
            for(Book item:bookListFull){
              if(item.getBorrowerId().toLowerCase().contentEquals(filterPattern)){
                  filteredBook.add(item);
              }
            }
        }
        FilterResults results=new FilterResults();
        results.values=filteredBook;
        Log.e("constrain",constraint+" "+filteredBook.toString());
        return results;
    }

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        bookList.clear();
        bookList.addAll((List)results.values);
        notifyDataSetChanged();

    }
};

}

【问题讨论】:

  • 只隐藏其他片段的搜索视图
  • 为什么不在fragment 中实现选项菜单而不是activity
  • 在 MainActivity 中实现了另一个选项菜单。这些选项菜单对所有其他片段可见。但我希望只有一个片段可见的搜索视图。如果有可用的代码示例会很有帮助

标签: android android-fragments navigation searchview


【解决方案1】:

要实现fragment 特定选项menu 除了activity 的选项menu,您还必须在fragment 中实现选项menu

活动:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_menu, menu);
    return super.onCreateOptionsMenu(menu);
}

片段:

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true); // It's important here
}

@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
    inflater.inflate(R.menu.fragment_menu, menu);
    super.onCreateOptionsMenu(menu, inflater);
}

但是在toolbar 中订购您的menu 商品时出现问题。您可以使用android:orderInCategory 指定工具栏中menu 项目的位置。

activity_menu:

<item
    android:id="@+id/action_menu1"
    android:title="Menu1"
    android:orderInCategory="2"
    app:showAsAction="always" />

fragment_menu:

<item
    android:id="@+id/action_search"
    android:title="Search"
    android:orderInCategory="1"
    app:showAsAction="always"
    app:actionViewClass="androidx.appcompat.widget.SearchView" />

输出:

【讨论】:

    【解决方案2】:

    简单的方法是在特定的 Fragment 中实现一个工具栏

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState); 
        setHasOptionsMenu(true);
    }
    

    你可以像下面这样得到 SearchView

    @Override
    public void onPrepareOptionsMenu(Menu menu) {
        MenuItem mSearchMenuItem = menu.findItem(R.id.mi_search);
        SearchView searchView = (SearchView) mSearchMenuItem.getActionView();
    }
    

    要检索结果,请在 onTextChange 中添加适配器

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            adapter.getFilter().filter(s);
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-31
      • 2015-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多