如何在加载JSON数据的ListView中使用Floating Search View并实现搜索
Hey there! Let's walk through adding a Floating Search View to your ListView with custom search functionality step by step. I’ll break this down into actionable parts that fit your existing setup:
First, make sure you include the library in your project. Open your app-level build.gradle file and add this dependency:
dependencies { implementation 'com.github.arimorty:floatingsearchview:2.1.1' }
If you’re using Android Studio Arctic Fox or newer, you’ll also need to add JitPack to your project-level settings.gradle file:
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() maven { url 'https://jitpack.io' } } }
Modify your existing layout to include the Floating Search View above your ListView. Wrap both in a RelativeLayout or ConstraintLayout to position them correctly:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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"> <!-- Floating Search View --> <com.arlib.floatingsearchview.FloatingSearchView android:id="@+id/floating_search_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" app:fsv_searchHint="Search your items..." app:fsv_showSearchKey="false" app:fsv_showMenuAction="false" /> <!-- Your Existing ListView --> <ListView android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@id/floating_search_view" /> </RelativeLayout>
Adjust the app: attributes as needed—for example, fsv_searchHint sets the placeholder text, and hiding the search key/menu action keeps the UI clean if you don’t need those features.
Assuming you already have your JSON data loaded into a list (let’s call it originalDataList), we’ll add a filtered list and connect the search view to update the ListView dynamically.
First, declare these variables in your MainActivity:
private FloatingSearchView mSearchView; private ListView mListView; private YourCustomAdapter mAdapter; private ArrayList<YourModelClass> originalDataList; // Your loaded JSON data private ArrayList<YourModelClass> filteredDataList; // For search results
Then initialize everything in onCreate():
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.your_main_layout); mSearchView = findViewById(R.id.floating_search_view); mListView = findViewById(R.id.listView); // Assume originalDataList is already populated via your HttpHandler originalDataList = new ArrayList<>(); filteredDataList = new ArrayList<>(); filteredDataList.addAll(originalDataList); // Initialize your adapter with the filtered list mAdapter = new YourCustomAdapter(this, filteredDataList); mListView.setAdapter(mAdapter); // Setup search functionality setupSearchView(); }
Add the setupSearchView() method to handle input changes and filtering:
private void setupSearchView() { // Trigger filtering as the user types mSearchView.setOnQueryChangeListener(new FloatingSearchView.OnQueryChangeListener() { @Override public void onSearchTextChanged(String oldQuery, final String newQuery) { filteredDataList.clear(); if (newQuery.isEmpty()) { // Show full list when search is cleared filteredDataList.addAll(originalDataList); } else { // Filter items based on the search query String lowerCaseQuery = newQuery.toLowerCase().trim(); for (YourModelClass item : originalDataList) { // Customize this condition to match your model's fields // Example: search by item name or description if (item.getName().toLowerCase().contains(lowerCaseQuery) || item.getDescription().toLowerCase().contains(lowerCaseQuery)) { filteredDataList.add(item); } } } // Update the ListView with filtered results mAdapter.notifyDataSetChanged(); } }); // Optional: Handle search submission (if needed) mSearchView.setOnSearchListener(new FloatingSearchView.OnSearchListener() { @Override public void onSuggestionClicked(SearchSuggestion searchSuggestion) { // Handle suggestion taps if you implement search suggestions } @Override public void onSearchAction(String currentQuery) { // Do something when the user presses the search button } }); // Optional: Clear search when back button is pressed mSearchView.setOnBackButtonClickListener(new FloatingSearchView.OnBackButtonClickListener() { @Override public void onBackButtonClicked() { mSearchView.setSearchText(""); } }); }
Make sure your custom adapter uses the filteredDataList so it updates when search results change. Your adapter should look something like this:
public class YourCustomAdapter extends ArrayAdapter<YourModelClass> { private ArrayList<YourModelClass> mItems; public YourCustomAdapter(Context context, ArrayList<YourModelClass> items) { super(context, 0, items); mItems = items; } @Override public View getView(int position, View convertView, ViewGroup parent) { // Your existing view binding logic here YourModelClass item = mItems.get(position); // Populate views with item data return convertView; } }
- If the library won’t sync: Double-check that JitPack is added to your project-level repositories.
- Search isn’t filtering correctly: Verify that you’re referencing the correct fields from your model class, and that you’re normalizing text to lowercase (to avoid case sensitivity).
- ListView doesn’t update: Ensure you call
mAdapter.notifyDataSetChanged()after modifying the filtered list.
内容的提问来源于stack exchange,提问作者khouloud

