Как включить функцию поиска, чтобы найти все значения из списка?

Rve спросил: 31 июля 2018 в 09:35 в: java

Я создаю приложение для Android в Android Studio, и я пытаюсь найти значение String в Listview, заполненном облачным SQL-сервером. Я использую API 26 для Android 8.0. Пока что он работает и находит некоторые значения.

Проблема - при достижении моего последнего (третьего) действия на эмуляторе и вставки строкового значения в поле поиска он не находит все и всю ценность Например, у меня есть список, полный значений (Apple, Orange, Red Apple, Grapes и т. Д.). При поиске продукта Apple, что происходит, заключается в том, что после ввода "ap" он находит его и исчезает сразу после ввода "приложения". Кроме того, пытаясь найти Orange, он ничего не показывает при вводе первой буквы o.

Это похоже на то, что он не находит все значения внутри карты.

вы пытались отладить Loop в моем адаптере. Кажется, что правильно понимают ограничение, получаем правильный счетчик для "i" и находим все результаты, содержащие определенное ограничение.

Мой адаптер:

package com.example.user.sortiment;import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;/**
 * Created by User
 */public class SortimentAdapter extends BaseAdapter {LayoutInflater mInflator;
List<Sortiment> map;
List<Sortiment> filterMap;    public void performFiltering(CharSequence constraint) {        String filterString = constraint.toString().toLowerCase();
        if (Objects.equals(filterString, "")) {
            filterMap.clear();
            filterMap.addAll(map);
            notifyDataSetChanged();
            return;
        }        int count = map.size();
        filterMap.clear();        for (int i = 0; i < count; i++) {
            Sortiment filterableSortiment = map.get(i);
            if (filterableSortiment.name.toLowerCase().contains(filterString)) {
                filterMap.add(filterableSortiment);
            }
        }        notifyDataSetChanged();    }public SortimentAdapter(Context c, List<Sortiment> inputMap) {
    mInflator = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    filterMap = new ArrayList<>();
    filterMap.addAll(inputMap);
    map = new ArrayList<>();
    map.addAll(inputMap);
}@Override
public int getCount() {
    return filterMap.size();
}@Override
public Object getItem(int position) {
    return filterMap.get(position);
}@Override
public long getItemId(int position) {
    return position;
}@Override
public View getView(int position, View convertView, ViewGroup parent) {    ViewHolder viewHolder;    if (convertView == null) {
        convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false);
        viewHolder = new ViewHolder(convertView);
        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }    Sortiment viewObject = filterMap.get(position);
    viewHolder.nameTextView.setText(viewObject.name);
    viewHolder.priceTextView.setText(viewObject.ean.toString());    return convertView;
}
private class ViewHolder {
    TextView nameTextView;
    TextView priceTextView;    public ViewHolder(View view) {
        nameTextView = (TextView)view.findViewById(R.id.nameTextView);
        priceTextView = (TextView) view.findViewById(R.id.priceTextView);
    }
}
}

и моя активность:

package com.example.user.sortiment;import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SearchView;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;public class SortimentActivity extends AppCompatActivity {List<Sortiment> sortimentMap = new ArrayList<>();
SortimentAdapter sortimentAdapter;
Context thisContext;
EditText edtSearch;
ListView myListView;@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sortiment);    Integer selectedStoreId = getIntent().getExtras().getInt("store_id");    edtSearch = (EditText)findViewById(R.id.edtSearch);
    myListView = (ListView) findViewById(R.id.storesListView);
    thisContext = this;    edtSearch.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {        }        @Override
        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            if (sortimentAdapter != null){
                sortimentAdapter.performFiltering(charSequence);
            }
        }        @Override
        public void afterTextChanged(Editable editable) {        }
    });    GetSortimentForStore retrieveData = new GetSortimentForStore();
    retrieveData.execute(selectedStoreId);}public void performFiltering(CharSequence constraint) {    List<Sortiment> filteredList = new ArrayList<>();    String filterString = constraint.toString().toLowerCase();
    if (Objects.equals(filterString, "")) {
        filteredList.addAll(sortimentMap);
        sortimentAdapter.notifyDataSetChanged();
        return;
    }    int count = sortimentMap.size();
    filteredList.clear();    for (int i = 0; i < count; i++) {
        Sortiment filterableSortiment = sortimentMap.get(i);
        if (filterableSortiment.name.toLowerCase().contains(filterString)) {
            filteredList.add(filterableSortiment);
        }
    }    sortimentAdapter = new SortimentAdapter(thisContext, filteredList);    sortimentAdapter.notifyDataSetChanged();}private class GetSortimentForStore extends AsyncTask<Integer,String,String> {    String msg = "";
    // JDBC Driver name and database URL
    static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
    // Example 10.20.30.40:3306
    static final String DB_URL = "jdbc:mysql://" +
            DbStrings.DATABASE_URL + "/" +
            DbStrings.DATABASE_NAME;    @Override
    protected void onPreExecute() {        //progressTextView.setText("Connecting...");
    }    @Override
    protected String doInBackground(Integer... selectedStores) {        Connection conn = null;
        Statement stmt = null;        try {
            Integer selectedStore = selectedStores[0];
            Class.forName(JDBC_DRIVER);
            conn = DriverManager.getConnection(DB_URL, DbStrings.USERNAME, DbStrings.PASSWORD);            stmt = conn.createStatement();
            String sql = "select id, store_id, name, ean, description from myproject.sortiments WHERE store_id = " + selectedStore;
            ResultSet rs = stmt.executeQuery(sql);
            while (rs.next()) {
                Sortiment newSortiment = new Sortiment();
                newSortiment.id = rs.getInt("id");
                newSortiment.name = rs.getString("name");
                newSortiment.store_id = rs.getInt("store_id");
                newSortiment.ean = rs.getString("ean");
                newSortiment.description = rs.getString("description");
                sortimentMap.add(newSortiment);
            }            rs.close();
            stmt.close();
            conn.close();        } catch (SQLException connError) {
            msg = "An exception was thrown for JDBC.";
            connError.printStackTrace();
        } catch (ClassNotFoundException e) {
            msg = "A class not found exception was thrown.";
            e.printStackTrace();
        } finally {            try {
                if (stmt != null) {
                    stmt.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }            try {
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }        }        return null;
    }    @Override
    protected void onPostExecute(String msg) {
        sortimentAdapter = new SortimentAdapter(thisContext, sortimentMap);
        myListView.setAdapter(sortimentAdapter);    }}
}

и часть AndroidManifest:

    <activity android:name=".SortimentActivity"
        android:windowSoftInputMode="stateHidden">
    </activity>

Любые идеи о том, как я могу реализовать эту функцию поиска в лучший способ заставить его искать каждую строку?


1 ответ

kAliert ответил: 31 июля 2018 в 10:03

Пока вы не используете метод executeFiltering в своей деятельности, я не вижу никаких проблем (в данном примере вы не вызываете этот метод, поэтому он не нужен и может быть удален) , Проблема с методом executeFiltering заключается в том, что вы создаете новый адаптер, но не присваиваете его списку, что, я думаю, было бы плохой практикой. Вы должны инициализировать свой адаптер один раз и использовать его для манипулирования вашими данными в виде списка.

Кстати: пожалуйста, назовите ваши переменные значащими. В вашем классе адаптеров у вас есть два списка, которые называются картами. Это сбивает с толку.

Rve ответил: 31 июля 2018 в 10:21
Благодарю. Как заменить публичный void PerformFiltering (ограничение Charsequence)?
kAliert ответил: 31 июля 2018 в 10:38
Просто используйте метод в вашем адаптере.