Как остановить тосты и alertDialog потерять фокус на мой фильтр EditText

ОБНОВИТЬ:

Последнее обновление – добавлен метод getChanges ().

Второе обновление – я добавил весь класс ShoppingList.java.

Первое обновление. После того, как 2 человека понравились вопросу, но нет ответов, я открыл щедрость для этого вопроса.

Вопрос:

У меня были схожие проблемы, когда я не могу повторно фильтровать свой ListView, когда начинаю новое намерение, а затем возвращаюсь на исходную страницу. Это было решено с помощью переопределения метода onResume () и вызова кода фильтра из другого метода фильтрации.

Последней проблемой, с которой я сталкиваюсь, является то, что на моей странице приложения должно быть использовано диалоговое окно или тост-сообщение, затем еще раз текст фильтра пуст, т.е. любой текст, введенный в мой фильтр, EditText игнорируется моим фильтром.

Вот несколько скриншотов, чтобы выделить проблему:

Загруженный ListView элементов:

Введите описание изображения здесь

Поисковый запрос вводится в фильтр EditText и правильно фильтруется:

Введите описание изображения здесь

Первый элемент «A» отредактирован до «AB». Тост-сообщение подтверждает действие:

Введите описание изображения здесь

В этом и заключается проблема, диалоговое построитель (как отредактирован элемент) и тост-сообщение завершены, новый новый термин фильтра вводится в EditText, и фильтр больше не фильтрует:

Введите описание изображения здесь

Вот мой код фильтра:

package com.example.flybaseapp; public class ShoppingList extends ListActivity implements OnClickListener { Button AddItem; Button showShop; ListView showItems; SimpleCursorAdapter cursorAdapter; Long itemId; TextView totalPrice; String itemDescription; int itemAmount; int itemPrice; EditText itemNameEdit; DBHandlerShop getCons; Dialog e1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.shoppinglistlayout); AddItem = (Button) findViewById(R.id.btnAddItem); showShop = (Button) findViewById(R.id.btnSearchShops); showItems = (ListView) findViewById(android.R.id.list); totalPrice = (TextView) findViewById(R.id.totalListPrice); AddItem.setOnClickListener(this); showShop.setOnClickListener(this); setList(); int setPrice = updateTotal(); totalPrice.setText(Integer.toString(setPrice)); itemNameEdit = (EditText) findViewById(R.id.inputItemName); showItems.setTextFilterEnabled(true); itemNameEdit.addTextChangedListener(new TextWatcher() { @Override public void afterTextChanged(Editable s) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { cursorAdapter.getFilter().filter(s.toString()); showItems.refreshDrawableState(); } }); getCons = new DBHandlerShop(this, null, null); getCons.open(); cursorAdapter.setFilterQueryProvider(new FilterQueryProvider() { public Cursor runQuery(CharSequence constraint) { return getCons.getChanges((constraint.toString())); } }); showItems.setAdapter(cursorAdapter); } @Override public void onClick(View clickedAdd) { switch (clickedAdd.getId()) { case (R.id.btnAddItem): show(); break; case (R.id.btnSearchShops): Intent checkGPS = new Intent("com.example.flybaseapp.CheckGPS"); startActivity(checkGPS); break; } } @Override protected void onListItemClick(ListView l, View v, int position, long idd) { super.onListItemClick(l, v, position, idd); itemId = idd; final CharSequence[] items = { "Edit Item", "Delete Item" }; Builder alertDialogBuilder = new AlertDialog.Builder(ShoppingList.this); alertDialogBuilder.setTitle("Item Options:"); alertDialogBuilder.setItems(items, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int item) { if (items[item].equals("Edit Item")) { AlertDialog.Builder builder = new AlertDialog.Builder( ShoppingList.this); builder.setTitle("Edit Item"); DBHandlerShop setEdit = new DBHandlerShop( ShoppingList.this, null, null); setEdit.open(); String itemName = setEdit.getItem(itemId); int itemAmount = setEdit.getItemQuan(itemId); int itemPrice = setEdit.getItemCost(itemId); setEdit.close(); LinearLayout layout = new LinearLayout( ShoppingList.this); layout.setOrientation(LinearLayout.VERTICAL); final EditText titleBox = new EditText( ShoppingList.this); titleBox.setText(itemName); titleBox.setHint("Item Name:"); layout.addView(titleBox); final EditText quantityBox = new EditText( ShoppingList.this); quantityBox.setText(Integer.toString(itemAmount)); quantityBox.setHint("Item Quantity"); layout.addView(quantityBox); final EditText priceBox = new EditText( ShoppingList.this); priceBox.setText(Integer.toString(itemPrice)); priceBox.setHint("Item Price."); layout.addView(priceBox); builder.setView(layout); builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() { public void onClick( DialogInterface dialog, int whichButton) { Editable valueItem = titleBox .getText(); Editable valueAmount = quantityBox .getText(); Editable valuePrice = priceBox .getText(); String itemDescription = valueItem .toString(); String s = valueAmount.toString(); int itemAmount = Integer .parseInt(s); String a = valuePrice.toString(); int itemPrice = Integer.parseInt(a); try { DBHandlerShop update = new DBHandlerShop( ShoppingList.this, null, null); int totalCombined = itemAmount * itemPrice; update.open(); update.updateItem(itemId, itemDescription, itemAmount, itemPrice); update.close(); int setPrice = updateTotal(); totalPrice.setText(Integer .toString(setPrice)); } catch (Exception e) { Toast.makeText( getApplicationContext(), "Items not updated.", Toast.LENGTH_SHORT) .show(); } finally { Toast.makeText( getApplicationContext(), "Items updated.", Toast.LENGTH_SHORT) .show(); setList(); } } }); builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { public void onClick( DialogInterface dialog, int whichButton) { } }); builder.show(); } else if (items[item].equals("Delete Item")) { try { DBHandlerShop delete = new DBHandlerShop( ShoppingList.this, null, null); delete.open(); delete.deleteItem(itemId); delete.close(); DBHandlerShop findPrice = new DBHandlerShop( ShoppingList.this, null, null); findPrice.open(); int returnedCost = findPrice .getItemCost(itemId); findPrice.close(); int cost = updateTotal(); int newTotal = cost - returnedCost; totalPrice.setText(Integer.toString(newTotal)); } catch (Exception e) { Toast.makeText(getApplicationContext(), "Item failed to be deleted.", Toast.LENGTH_SHORT).show(); } finally { Toast.makeText(getApplicationContext(), "Item deleted from the list.", Toast.LENGTH_SHORT).show(); setList(); } } } }); alertDialogBuilder.show(); } @SuppressWarnings("deprecation") private void setList() { DBHandlerShop DBShop = new DBHandlerShop(this, null, null); DBHandlerShop searchItems = new DBHandlerShop(this, null, null); searchItems.open(); Cursor cursor = searchItems.getItems(); startManagingCursor(cursor); searchItems.close(); String[] from = new String[] { DBShop.KEY_ITEMSHOP, DBShop.KEY_ITEMNUM, DBShop.KEY_ITEMPRICE }; int[] to = new int[] { R.id.txtSetItem, R.id.txtSetAmount, R.id.txtSetPrice }; cursorAdapter = new SimpleCursorAdapter(this, R.layout.setshoppinglist, cursor, from, to); showItems.setAdapter(cursorAdapter); } private int updateTotal() { DBHandlerShop total = new DBHandlerShop(this, null, null); int totalPrice = 0; total.open(); Cursor totalPrices = total.getTotals(); total.close(); if (totalPrices != null) { startManagingCursor(totalPrices); if (totalPrices.moveToFirst()) { do { int cost = totalPrices.getInt(3); int amount = totalPrices.getInt(2); int totalCost = cost * amount; totalPrice += totalCost; } while (totalPrices.moveToNext()); return totalPrice; } } else { return totalPrice; } return 0; } private void show() { AlertDialog.Builder builder = new AlertDialog.Builder(ShoppingList.this); builder.setTitle("Enter Item Details:"); LinearLayout layout = new LinearLayout(this); layout.setOrientation(LinearLayout.VERTICAL); final EditText titleBox = new EditText(this); titleBox.setHint("Item Name:"); layout.addView(titleBox); final EditText quantityBox = new EditText(this); quantityBox.setHint("Item Quantity"); layout.addView(quantityBox); final EditText priceBox = new EditText(this); priceBox.setHint("Item Price."); layout.addView(priceBox); builder.setView(layout); builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { try { Editable valueItem = titleBox.getText(); Editable valueAmount = quantityBox.getText(); Editable valuePrice = priceBox.getText(); itemDescription = valueItem.toString(); String s = valueAmount.toString(); itemAmount = Integer.parseInt(s); String a = valuePrice.toString(); itemPrice = Integer.parseInt(a); DBHandlerShop addItem = new DBHandlerShop( ShoppingList.this, null, null); addItem.open(); addItem.insertItems(itemDescription, itemAmount, itemPrice); addItem.close(); } catch (Exception e) { Toast.makeText(getApplicationContext(), "Item failed to be added", Toast.LENGTH_SHORT) .show(); } finally { Toast.makeText(getApplicationContext(), "Item added to your list", Toast.LENGTH_SHORT) .show(); int cost = updateTotal(); totalPrice.setText(Integer.toString(cost)); setList(); } } }); builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { } }); builder.show(); } @Override protected void onResume() { super.onResume(); setList(); showItems.setTextFilterEnabled(true); itemNameEdit.addTextChangedListener(new TextWatcher() { @Override public void afterTextChanged(Editable s) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { cursorAdapter.getFilter().filter(s.toString()); showItems.refreshDrawableState(); } }); getCons = new DBHandlerShop(this, null, null); getCons.open(); cursorAdapter.setFilterQueryProvider(new FilterQueryProvider() { public Cursor runQuery(CharSequence constraint) { return getCons.getChanges((constraint.toString())); } }); showItems.setAdapter(cursorAdapter); } } 

GetChanges () из класса обработчика базы данных:

 public Cursor getChanges(String constraintPassed) { String [] columns = new String[]{KEY_ROWSHOPID, KEY_ITEMSHOP, KEY_ITEMNUM, KEY_ITEMPRICE}; Cursor c = null; if(constraintPassed.equals("")) { c = ourDatabase.query(DATABASE_TABLESHOP, columns, null, null, null, null, null); } else { c = ourDatabase.query(DATABASE_TABLESHOP, columns, KEY_ITEMSHOP + " LIKE'" + constraintPassed + "%'", null, null, null, KEY_ITEMSHOP + " ASC", null); } if( c != null) { c.moveToFirst(); } return c; } 

Нужно ли мне внедрять метод жизненного цикла после внесения изменений? Если бы это было так, кто-то мог бы подтолкнуть меня в правильном направлении, в котором это необходимо, поскольку я пробовал функцииResume () и onRestart () безрезультатно.

Попробуйте позвонить notifyDataSetChanged() в свой адаптер после обновления фильтра. Это должно уведомить ListView о необходимости обновления своих данных.

Насколько я вижу, вы запускаете getCons.open(); Несколько раз, не закрывая их между собой. Я не знаю, игнорирует ли этот метод open() несколько вызовов или вызывает его несколько раз, вызывает ошибку, но вы можете попробовать, исправить ли это, переместив getCons.open(); Непосредственно ниже getCons = new DBHandlerShop(this, null, null); ,

Простым способом решения этой проблемы я хотел бы просто вызвать класс, инициировав новый объект намерения после завершения его редактирования. Это по-прежнему делает работу в целом гладкой и быстрой, и, конечно же, позволяет фильтровать после редактирования. Так что пока ребята, это то, как я собираюсь пойти с ним.

Я вижу, что происходит в вашем случае. Каждый раз, когда пользователь успешно редактирует элемент, вы устанавливаете новый адаптер в свой список! И в вашем случае TextWatcher, добавленный в ваш EditText в методе onCreate, использует самый первый адаптер (в методе onTextChanged ), также созданный в методе onCreate , в первый раз, когда создается действие!

Существует несколько способов решения этой проблемы. Одним из способов было бы изменить весь способ осуществления вашей деятельности (я лично не сделал бы этого так).

Другим способом было бы просто изменить метод setList , который называется самым первым в методе onCreate , и каждый раз, когда пользователь успешно редактирует элемент. Это решение, о котором я расскажу подробнее, потому что это быстро и легко и не требует много времени для вас:

  • Если в списке нет адаптера, создайте его.
  • Если в списке уже есть адаптер, просто измените курсор адаптера и обновите список.

Поэтому ваш метод setList должен выглядеть так:

 @SuppressWarnings("deprecation") private void setList() { DBHandlerShop DBShop = new DBHandlerShop(this, null, null); DBHandlerShop searchItems = new DBHandlerShop(this, null, null); searchItems.open(); Cursor cursor = searchItems.getItems(); startManagingCursor(cursor); searchItems.close(); String[] from = new String [] { DBShop.KEY_ITEMSHOP , DBShop.KEY_ITEMNUM, DBShop.KEY_ITEMPRICE }; int[] to = new int[] { R.id.txtSetItem, R.id.txtSetAmount, R.id.txtSetPrice }; // Check the cursor adapter is previously created if ( cursorAdapter == null ) { // There is no previous cursors, create a new one cursorAdapter = new SimpleCursorAdapter(this, R.layout.setshoppinglist, cursor, from, to); showItems.setAdapter(cursorAdapter); } else { // There is a previous adapter // Stop managing its cursor stopManagingCursor ( cursorAdapter.getCursor() ); // Assign the new cursor to the current adapter // The old cursor will be closed cursorAdapter.changeCursor ( cursor ); // No need to refresh the list, it will be automatically refreshed after the adapter's cursor is changed } } 

Таким образом, адаптер списка является тем же, который используется TextWatcher для фильтрации списка. Он должен работать, дать ему попробовать и сообщить мне, что происходит.

Я думаю, вы должны использовать

 android:hapticFeedbackEnabled="true" android:imeOptions="actionNext" android:nextFocusUp="@id/editeText1" android:nextFocusLeft="@id/edittextText" android:includeFontPadding="true" 

Вы можете попробовать следующие изменения ..

После показа ваших тостов, обновленные / удаленные сообщения вызывают это

 cursorAdapter.notifyDataSetChanged(); 

В вашем методе setList () добавьте следующее ..

 cursorAdapter.registerDataSetObserver(new DataSetObserver() { @Override public void onChanged() { super.onChanged(); setList(); }}); 

И переместитесь ниже кода в setList ()

 itemNameEdit.addTextChangedListener(new TextWatcher() { @Override public void afterTextChanged(Editable s) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { cursorAdapter.getFilter().filter(s.toString()); showItems.refreshDrawableState(); } }); getCons = new DBHandlerShop(this, null, null); getCons.open(); cursorAdapter.setFilterQueryProvider(new FilterQueryProvider() { public Cursor runQuery(CharSequence constraint) { return getCons.getChanges((constraint.toString())); } });