- Maybe someone can deal with the problem. I have a base and a ListView that fills custom item elements with my adapter.
This is the controller:
public class ListFragment extends Fragment implements AdapterView.OnItemClickListener { private ListView mListView; private DatabaseHelper mDatabaseHelper; private Cursor mCursor; // Поле поиска private EditText mSearchEditText; // Кастомный адаптер private StationCursorAdapter stationsCursorAdapter; // Хранит направление текущего списка станций private String mDirectionType; // При клике на элемент списка, будет создаваться объект модели. private static Station mStation; // Перед записью в модель, данные нужно получить из базы. private Cursor mStationCursor; private Cursor mCityCursor; // При поиске Города из Станции нужно достать идентификатор родительского города. private Long mCityId; // Дополнение для объекта Станция public static final String EXTRA_REQUEST_STATION_OBJECT = "com.devgmail.mitroshin.totutu." + "extra_request_station_object"; // Дополнение для типа направления public static final String EXTRA_REQUEST_DIRECTION_TYPE = "com.devgmail.mitroshin.totutu." + "extra_request_direction_type"; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); mDatabaseHelper = new DatabaseHelper(getActivity().getApplicationContext()); mDatabaseHelper.open(); } @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_list, container, false); mListView = (ListView) view.findViewById(R.id.list_list_view); mListView.setOnItemClickListener(this); mSearchEditText = (EditText) view.findViewById(R.id.list_edit_search); // При отображении списка нам нужны не все данные из базы данных, а только соответствующие // выбранному пользователем направлению. Для этого с интентом передается информация о направлении mDirectionType = (String) getActivity().getIntent(). getSerializableExtra(EXTRA_DIRECTION_TYPE); // Нужно запросить из базы необходимые для отображения в элементе списка заголовки и // идентификатор, который будет передаваться для отображения подробной информации о // станции в активность Info. mCursor = mDatabaseHelper.database.rawQuery(generateDefaultQuery(mDirectionType), null); // Данные после получения результатов запроса нужно адаптировать. // Есть несколько дефолтных адаптеров, в данном случае реализован отдельный класс. stationsCursorAdapter = new StationCursorAdapter(getActivity() .getApplicationContext(), mCursor); if (!mSearchEditText.getText().toString().isEmpty()) { stationsCursorAdapter.getFilter().filter(mSearchEditText.getText().toString()); } mSearchEditText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } // При изменении текста в поле ввода, будет выполняться фильтрация @Override public void onTextChanged(CharSequence s, int start, int before, int count) { stationsCursorAdapter.getFilter().filter(s.toString()); } @Override public void afterTextChanged(Editable s) { } }); stationsCursorAdapter.setFilterQueryProvider(new FilterQueryProvider() { @Override public Cursor runQuery(CharSequence constraint) { if (constraint == null || constraint.length() == 0) { return mDatabaseHelper.database.rawQuery(generateDefaultQuery(mDirectionType), null); } else { return mDatabaseHelper.database.rawQuery(generateSearchQuery(mDirectionType), new String[] {"%" + constraint.toString() + "%"}); } } }); mListView.setAdapter(stationsCursorAdapter); return view; } @Override public void onDestroy() { super.onDestroy(); mDatabaseHelper.database.close(); mCursor.close(); } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long stationId) { // После вызова этого метода mStation бедет ссылаться на объект станции, // в котором будет храниться ссылка на идентификатор родителя. // Родительский объект будет создаваться автоматически createModelByStationId(stationId); // Вернуться к стартовой активности можно: // * нажав на кнопку Back - RESULT_CANCELED // * нажав на элемент списка - RESULT_OK // Возвращая указатель на модель, мне нужно сообщить стартовой активности тип направления, // который был передан в эту активность в качестве дополнения к интенту. Intent data = new Intent(); data.putExtra(EXTRA_REQUEST_STATION_OBJECT, mStation); data.putExtra(EXTRA_REQUEST_DIRECTION_TYPE, mDirectionType); getActivity().setResult(Activity.RESULT_OK, data); getActivity().finish(); } // Информация о ключе к расширению является частью активности ListActivity или ее фрагмента. // Т.е. родительская активность при получении интента результата должна будет открыть дополнение // с помощью ключа, но делать его доступным для всех подряд не хорошо. // Поэтому родительская активность, получая результат передает его снова в дочернюю, // чтобы дочерняя его распаковала и вернула. // Для этого и созданы следующие два метода public static Station resultStationObject(Intent result) { return result.getParcelableExtra(EXTRA_REQUEST_STATION_OBJECT); } public static String resultDirectionType(Intent result) { return result.getStringExtra(EXTRA_REQUEST_DIRECTION_TYPE); } // Так как станция без города существовать не может, то ссылка на объект родительского // Класса будет передаваться вместе с ссылкой на объект дочернего. // Сначала нужно получить информацию о Станции, так как только класс потомок, знает о // существовании родителя. В классе City нет ссылок на дочерние элементы. public void createModelByStationId(Long stationId) { mStationCursor = mDatabaseHelper.database.rawQuery("SELECT * FROM " + mDatabaseHelper.STATIONS_TABLE + " WHERE " + mDatabaseHelper.STATION_ID + " = '" + stationId + "'", null); mStationCursor.moveToFirst(); mCityId = mStationCursor.getLong(mStationCursor. getColumnIndexOrThrow(mDatabaseHelper.STATION_CITY_ID)); mCityCursor = mDatabaseHelper.database.rawQuery("SELECT * FROM " + mDatabaseHelper.CITIES_TABLE + " WHERE " + mDatabaseHelper.CITY_CITY_ID + " = '" + mCityId + "'", null); mCityCursor.moveToFirst(); // К этому моменту в курсорах City и Station хранится информация о выбранной // пользователем станции и о городе, в котором эта станция расположена mStation = new Station(mStationCursor, mCityCursor); } private String generateDefaultQuery (String directionType) { return "SELECT " + mDatabaseHelper.COUNTRY_TITLE + ", " + mDatabaseHelper.CITY_TITLE + ", " + mDatabaseHelper.STATION_TITLE + ", " + mDatabaseHelper.STATIONS_TABLE + "." + mDatabaseHelper.STATION_ID + " FROM " + mDatabaseHelper.CITIES_TABLE + ", " + mDatabaseHelper.STATIONS_TABLE + " WHERE (" + mDatabaseHelper.CITY_DIRECTION + " LIKE '" + directionType + "' OR " + mDatabaseHelper.CITY_DIRECTION + " LIKE 'Both') AND (" + mDatabaseHelper.STATION_DIRECTION + " LIKE '" + directionType + "' OR " + mDatabaseHelper.STATION_DIRECTION + " LIKE 'Both') AND (" + mDatabaseHelper.CITIES_TABLE + "." + mDatabaseHelper.CITY_CITY_ID + " = " + mDatabaseHelper.STATION_CITY_ID + ")" + "ORDER BY " + mDatabaseHelper.COUNTRY_TITLE + ", " + mDatabaseHelper.CITY_TITLE; } private String generateSearchQuery (String directionType) { return "SELECT " + mDatabaseHelper.COUNTRY_TITLE + ", " + mDatabaseHelper.CITY_TITLE + ", " + mDatabaseHelper.STATION_TITLE + ", " + mDatabaseHelper.STATIONS_TABLE + "." + mDatabaseHelper.STATION_ID + " FROM " + mDatabaseHelper.CITIES_TABLE + ", " + mDatabaseHelper.STATIONS_TABLE + " WHERE (" + mDatabaseHelper.CITY_DIRECTION + " LIKE '" + directionType + "' OR " + mDatabaseHelper.CITY_DIRECTION + " LIKE 'Both') AND (" + mDatabaseHelper.STATION_DIRECTION + " LIKE '" + directionType + "' OR " + mDatabaseHelper.STATION_DIRECTION + " LIKE 'Both') AND (" + mDatabaseHelper.CITIES_TABLE + "." + mDatabaseHelper.CITY_CITY_ID + " = " + mDatabaseHelper.STATION_CITY_ID + ")" + " AND (" + mDatabaseHelper.STATION_TITLE + " LIKE ? " + "ORDER BY " + mDatabaseHelper.COUNTRY_TITLE + ", " + mDatabaseHelper.CITY_TITLE; } } And this is the Adapter:
public class StationCursorAdapter extends CursorAdapter { private DatabaseHelper mDatabaseHelper; public StationCursorAdapter(Context context, Cursor c) { super(context, c, 0); } private FilterQueryProvider mFilterQueryProvider; private String mStringCountry; private String mStringStation; private String mStringCity; private TextView mTextCountry; private TextView mTextStation; private TextView mTextCity; @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { LayoutInflater inflater = LayoutInflater.from(context); View view = inflater.inflate(R.layout.item, null, true); return view; } @Override public void bindView(View view, Context context, Cursor cursor) { mTextCountry = (TextView) view.findViewById(R.id.item_text_country); mTextStation = (TextView) view.findViewById(R.id.item_text_station); mTextCity = (TextView) view.findViewById(R.id.item_text_city); mStringCountry = cursor.getString(cursor.getColumnIndexOrThrow(mDatabaseHelper.COUNTRY_TITLE)); mStringStation = cursor.getString(cursor.getColumnIndexOrThrow(mDatabaseHelper.STATION_TITLE)); mStringCity = cursor.getString(cursor.getColumnIndexOrThrow(mDatabaseHelper.CITY_TITLE)); mTextCountry.setText(mStringCountry); mTextStation.setText(mStringStation); mTextCity.setText(mStringCity); } @Override public Filter getFilter() { return super.getFilter(); } @Override public FilterQueryProvider getFilterQueryProvider() { return super.getFilterQueryProvider(); } @Override public void setFilterQueryProvider(FilterQueryProvider filterQueryProvider) { super.setFilterQueryProvider(filterQueryProvider); } }I did everything for this tutorial http://metanit.com/java/android/14.4.php , the only difference is my own adapter.
- For reasons that I don’t understand, when I enter text into a field, nothing happens anyway. The list is not reloaded from the database with the updated query.
- Thanks in advance for your help.