You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android自定义Adapter无法过滤MySQL数据源数据求助

Hey there! Let's fix your SearchView filtering issue step by step. I’ve gone through your code and spotted a few key gaps and tweaks needed to get the filtering working properly.

First, the Core Issue: Missing Filter Logic in Your Adapter

Your CustomStockList has a skeleton getFilter() method, but there’s no actual logic to check if an item matches the search query. Plus, there’s a bug in how you initialize your original and filtered lists (they’re pointing to the same reference, which will cause unexpected behavior).

Step 1: Fix the Adapter Initialization & Filter Logic

Update your CustomStockList with these changes:

private Activity activity;
private LayoutInflater inflater;
private List<StockData> originalItems; // Store original unfiltered data
private List<StockData> filteredItems;
private static class ViewHolder { // Add ViewHolder to optimize ListView performance
    TextView model;
    TextView stock;
}

public CustomStockList(Activity activity, List<StockData> items) {
    this.activity = activity;
    this.inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    // Create copies of the original list to avoid reference issues
    this.originalItems = new ArrayList<>(items);
    this.filteredItems = new ArrayList<>(items);
}

@Override
public int getCount() {
    return filteredItems.size();
}

@Override
public Object getItem(int location) {
    return filteredItems.get(location);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if (convertView == null) {
        convertView = inflater.inflate(R.layout.activity_custom_stock_list, parent, false);
        holder = new ViewHolder();
        holder.model = convertView.findViewById(R.id.model);
        holder.stock = convertView.findViewById(R.id.stock);
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    StockData item = filteredItems.get(position);
    holder.model.setText(item.getModelno());
    holder.stock.setText(item.getStock());
    return convertView;
}

@Override
public Filter getFilter() {
    return new Filter() {
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            filteredItems = (List<StockData>) results.values;
            notifyDataSetChanged(); // This updates the ListView with filtered data
        }

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults results = new FilterResults();
            List<StockData> tempFilteredList = new ArrayList<>();

            if (constraint == null || constraint.length() == 0) {
                // No filter applied: use original full list
                tempFilteredList.addAll(originalItems);
            } else {
                // Lowercase the query to make filtering case-insensitive
                String filterQuery = constraint.toString().toLowerCase().trim();
                // Check each item against the query
                for (StockData item : originalItems) {
                    if (item.getModelno().toLowerCase().contains(filterQuery)) {
                        tempFilteredList.add(item);
                    }
                }
            }

            results.values = tempFilteredList;
            results.count = tempFilteredList.size();
            return results;
        }
    };
}

Key changes here:

  • Created separate originalItems and filteredItems lists (no more shared references)
  • Added actual filtering logic to match the search query against modelno (case-insensitive)
  • Implemented ViewHolder pattern to optimize ListView scrolling performance
  • Fixed the filter’s performFiltering method to return the correct filtered results

Step 2: Fix Null Pointer & Adapter Initialization in ListActivity

Your current code tries to call customStockList.getFilter() in onCreate() before the adapter is actually initialized (it’s created later in onPostExecute). Let’s fix that:

First, declare your adapter as a global variable in StockList:

public class StockList extends AppCompatActivity {
    private ListView lv3;
    private SearchView sv;
    private CustomStockList customStockList;
    private List<StockData> stockList = new ArrayList<>(); // Initialize empty list upfront

    // ... rest of your code
}

Then update the onPostExecute method to properly initialize the adapter:

@Override
protected void onPostExecute(Void aVoid) {
    try {
        JSONObject object = new JSONObject(result);
        JSONArray jsonArray = object.getJSONArray("itemstock");
        for (int i = 0; i < jsonArray.length(); i++) {
            JSONObject obj = jsonArray.getJSONObject(i);
            StockData stockData = new StockData();
            stockData.setModelno(obj.getString("modelno"));
            stockData.setStock(obj.getString("stock"));
            stockList.add(stockData);
        }
    } catch (JSONException e) {
        Log.e("log_tag", "Error parsing data " + e.toString());
    }
    // Initialize adapter and assign to global variable
    customStockList = new CustomStockList(StockList.this, stockList);
    lv3.setAdapter(customStockList);
}

Finally, tweak the SearchView listener to avoid null pointers and remove redundant code:

sv.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
    @Override
    public boolean onQueryTextSubmit(String s) {
        return false;
    }

    @Override
    public boolean onQueryTextChange(String s) {
        if (customStockList != null) {
            customStockList.getFilter().filter(s);
            // No need for notifyDataSetChanged here - the filter handles it
        }
        return true; // Indicate we've handled the text change event
    }
});

Why This Works

  • The adapter now keeps a copy of the original full dataset, so filtering can always reset to the complete list
  • The filter logic checks if the item’s modelno contains the search query (case-insensitive for better user experience)
  • We fixed the timing issue where you tried to use the adapter before it was initialized
  • The ViewHolder pattern reduces unnecessary view inflation, making your ListView smoother

Give these changes a try, and your SearchView should start filtering the ListView items as expected!

内容的提问来源于stack exchange,提问作者Arpan Sarkar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:48:24