Search in a ListView doesn't work properly - android

I have a listView with about 30 items in it and have added a search function to it via an editText. When I type 'a' in the textfield everything that starts with an 'a' shows up on the list but when I type another letter the list disappears even tho the list contains an item with 'a' + the other letter i typed.
Another thing that confuses me is that there is an item in the list called IWU Trading and thats the only item I can search for, means that if I type 'I' + 'W' the item shows up in the listView. But if I type 'a' + 'r' an item that is named 'art' dosent show up.
My question(s).
How can I do to make this search function work?
Why does it act like it does?
My XML
<EditText
android:id="#+id/searchEditText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/selectCustomerTextView"
android:layout_marginTop="20dp"
android:hint="#string/typeToSearch"
android:ems="10"
android:imeOptions="actionDone"
android:inputType="textNoSuggestions"/>
<ListView
android:id="#+id/list_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/nextButton"
android:layout_alignParentLeft="true"
android:layout_below="#+id/searchEditText"
android:choiceMode="singleChoice"
android:dividerHeight="5dp" >
</ListView>
My code:
private ArrayAdapter<Customer> _oldAdapter = null;
public void onCreate(Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
setContentView(R.layout.activity_customer_pick);
EditText searchText = (EditText) findViewById(R.id.searchEditText);
ListView listView = (ListView) findViewById(R.id.list_view);
listView.setClickable(true);
searchText.addTextChangedListener(filterTextWatcher);
_oldAdapter = _phoneDAL.BindValues(this);
listView.setAdapter(_oldAdapter);
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
String s = _oldAdapter.getItem(arg2).toString();
_listViewPostion = arg2;
Toast.makeText(CustomerPick.this, "Du valde: " + s, arg2).show();
}
});
}
The search method:
private TextWatcher filterTextWatcher = new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
public void onTextChanged(CharSequence s, int start, int before,
int count) {
ArrayAdapter<Customer> _adapter = new ArrayAdapter<Customer>(CustomerPick.this, android.R.layout.simple_list_item_single_choice, new ArrayList<Customer>());
ListView listView = (ListView) findViewById(R.id.list_view);
int textLength = s.length();
if(textLength == 0){
listView.setAdapter(_oldAdapter);
return;
}
for (int i = 0; i < listView.getAdapter().getCount(); i++)
{
String word = _oldAdapter.getItem(i).getCustName().toLowerCase();
if (textLength <= word.length())
{
if(s.toString().equalsIgnoreCase(word.substring(0, textLength)))
{
_adapter.add(_oldAdapter.getItem(i));
}
}
}
listView.setAdapter(_adapter);
}
};
}
My CustomerClass (private ArrayAdapter _oldAdapter = null;)
public class Customer {
private final int _custNumber;
private final String _custName;
public Customer(int custNumber, String custName){
_custNumber = custNumber;
_custName = custName;
}
public int getCustNumber() {
return _custNumber;
}
public String getCustName() {
return _custName;
}
#Override
public String toString(){
return _custName;
}
}

Solved the problem by adding:
ListView listView = (ListView) findViewById(R.id.list_view);
((Filterable) listView.getAdapter()).getFilter().filter(s);
into the afterTextChanged method of the TextWatcher(after reading Luksprog's comment).

Related

Search in listview does not show corresponding item

I'm trying to learn java in android studio, but I find myself in a problem.
In the listview when I search for an item it shows the right match name, but when I click to play it plays another item instead of the searched item.
If they have any solutions using searchview it would be better.
Thank you
MainActivity
public class MainActivity extends AppCompatActivity {
private EditText et;
private ArrayList<String> lstEstados_Encontrados = new ArrayList<String>();
// variable declaration
private ListView mainList;
private MediaPlayer mp;
private final String[] listContent = {
"NHA", "iisso",
"Rolezeira",
};
private final int[] resID = {
R.raw.ne, R.raw.eso,
R.raw.rolezeira,
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(activity_main);
et = (EditText) findViewById(R.id.etProcurar);
mp = new MediaPlayer();
mainList = (ListView) findViewById(listView1);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, listContent);
mainList.setAdapter(adapter);
mainList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
playSong(position);
}
});
//Carrega o listview com todos os itens
mainList.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, listContent));
CarregarEncontrados();
et.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
// Abstract Method of TextWatcher Interface.
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// Abstract Method of TextWatcher Interface.
}
//Evento acionado quando o usuário teclar algo
//na caixa de texto "Procurar"
public void onTextChanged(CharSequence s, int start, int before, int count) {
CarregarEncontrados();
//Carrega o listview com os itens encontrados
mainList.setAdapter(new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, lstEstados_Encontrados));
}
});
}
public void CarregarEncontrados() {
int textlength = et.getText().length();
//Limpa o array com os estados encontrados
//para poder efetuar nova busca
lstEstados_Encontrados.clear();
for (int i = 0; i < listContent.length; i++) {
if (textlength <= listContent[i].length()) {
//Verifica se existe algum item no array original
//caso encontre é adicionado no array de encontrados
if (et.getText().toString().equalsIgnoreCase((String)listContent[i].subSequence(0, textlength))) {
lstEstados_Encontrados.add(listContent[i]);
}
}
}
}
public void playSong(int songIndex) {
mp.reset();
mp = MediaPlayer.create(getApplicationContext(), resID[songIndex]);// create's
mp.start();
}
#Override
public void onDestroy() {
super.onDestroy();
mp.release();
}
}
don't use position for the selected item, when you search and filter item. this makes you select the wrong item. because, position related to items that show on the current screen.
my solution :
set textView in layout for store you object ID in it. then in setOnItemClickListener method get ID from your selected item. then select corresponding correct data with selected ID, not position.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/txt_id"
android:testSize="0dp"
android:layout_width="wrap_content"
android:layout_height="0dp" />
...
...
... other element
</LinearLayout >
in java code :
mainList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view,
int position, long id) {
String id=((TextView)view.findViewById(R.id.txt_id)).getText().toString();
// playSong(id);
}
});

AutoCompleteTextView adapter issue

I have an AutoCompleteTextView, and depending from the changes in it, it shows the dropdown list with the data from server. Via listener after changing every symbol I make request to the server and take some list.
After that I show that list in AutoCompleteTextView, in code I do it by this way:
List<String> list = new ArrayList<String>();
for (int i = 0; i < jsonArray.length(); i++) {
list.add(jsonArray.getJSONObject(i).getString("title"));
}
String[] cities = list.toArray(new String[list.size()]);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(DistanceCalculation.this, R.layout.support_simple_spinner_dropdown_item, cities);
AutoCompleteTextView my = (AutoCompleteTextView) myView;
my.setAdapter(adapter);
Problem is it oftenly shows only the first element of the list, and after long click it shows the full list. I don understand why its happening.
Sorry for the bad eng, thanks in advance! Also you could check the rest of the code below:
xml part:
<AutoCompleteTextView
android:id="#+id/from"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="15dp"
android:background="#drawable/td_inp"
android:hint="Откуда"
android:paddingBottom="5dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingTop="5dp"
android:textColor="#000"
android:textColorHint="#757575" />
AutoCompleteTextView and its listener in onCreate
tCityFrom = (AutoCompleteTextView) findViewById(R.id.from);
tCityFrom.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
if(s.length() >= 2) load_city(ssid, s.toString(),tCityFrom);
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {}
});
I assume you want to show AutoComplete suggestions according to what user types. You have to load data from server onTextChanged():
tCityFrom = (AutoCompleteTextView) findViewById(R.id.from);
tCityFrom.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) { }
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(s.length() >= 2)
load_city(ssid, s.toString(),tCityFrom);
}
});
Then declare ArrayList and Adapter globally:
List<String> list;
ArrayAdapter<String> adapter;
In onCreate():
list = new ArrayList<String>();
adapter = new ArrayAdapter<String>(DistanceCalculation.this, R.layout.support_simple_spinner_dropdown_item, cities);
AutoCompleteTextView my = (AutoCompleteTextView) myView;
my.setAdapter(adapter);
Replace your first code snippet of load_city() with below code :
list.clear();
for (int i = 0; i < jsonArray.length(); i++) {
list.add(jsonArray.getJSONObject(i).getString("title"));
}
adapter.notifyDataSetChanged();
Hope this helps.

select mutiple contact list by searchview and send to another activity

OK I have a multiple choice ListView that works fine. I check the boxes for the contacts (held in a String[]) and can return the values fine. Because some people have a bunch of contacts I wanted to create a search bar kind of like the stock one for the Android phone book. I created an EditText and aligned it above my list. I found the filtering code here on StackOverflow and it works wonderfully.
My Problem:
When you filter someones name out, and you select the name, when you either backspace from the EditText or continue typing, the correct position of the name you selected is not saved. For example, if I start typing "Adam" and get to "Ada" and select it, if I backspace to type in "Carol", whatever position "Ada" was at is selected. It gathers the place that "Adam" was at from the click (Let's say 2) and when the list is restored checks that position (2) even though Adam is not there anymore. I need a way to gather the name.. then when the list is restored or searched again, the NAME Adam is checked and not the POSITION Adam was previously at. I have absolutely no ideas other than creating tons of Arrays and could really use some help.
public class MainActivity extends Activity {
private static final String[] items={"lorem1", "ipsum1", "dolor1",
"sit1", "amet1","lorem2", "ipsum2", "dolor2",
"sit2", "amet2","lorem3", "ipsum3", "dolor3",
"sit3", "amet3","lorem4", "ipsum4", "dolor4",
"sit4", "amet4","lorem5", "ipsum5", "dolor5",
"sit5", "amet5","lorem6", "ipsum6", "dolor6",
"sit6", "amet6","pigeon","victory"};
ListView list;
Button save;
EditText inputSearch;
SearchView searchview;
ArrayAdapter<String> adapter;
int textlength=0;
// private String my_sel_items;
ArrayList<String> selectedItems1 = new ArrayList<String>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
adapter = (new ArrayAdapter<String>(this, android.R.layout.simple_list_item_multiple_choice, items));
list = (ListView) findViewById(R.id.list);
list.setEmptyView(findViewById(R.id.empty));
list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
list.setAdapter(adapter);
list.setTextFilterEnabled(true);
inputSearch = (EditText) findViewById(R.id.inputSearch);
save = (Button) findViewById(R.id.save);
inputSearch.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
// When user changed the Text
MainActivity.this.adapter.getFilter().filter(cs);
textlength = inputSearch.getText().length();
selectedItems1.clear();
for (int i = 0; i < items.length; i++) {
if (textlength <= items[i].length()) {
if (inputSearch.getText().toString().equalsIgnoreCase(
(String)
items[i].subSequence(0,
textlength))) {
selectedItems1.add(items[i]);
}
}
}
list.setAdapter(new ArrayAdapter<String>
(MainActivity.this,
android.R.layout.simple_list_item_multiple_choice, selectedItems1));
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
}
});
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SparseBooleanArray checked = list.getCheckedItemPositions();
ArrayList<String> selectedItems = new ArrayList<String>();
for (int i = 0; i < checked.size(); i++) {
int position = checked.keyAt(i);
if (checked.valueAt(i))
selectedItems.add(adapter.getItem(position));
}
String[] outputStrArr = new String[selectedItems.size()];
for (int i = 0; i < selectedItems.size(); i++) {
outputStrArr[i] = selectedItems.get(i);
}
if (selectedItems.size() < 1) {
Toast.makeText(getApplicationContext(), "Select atleast one ", Toast.LENGTH_LONG).show();
} else {
Intent intent = new Intent(MainActivity.this, Main2Activity.class);
Bundle b = new Bundle();
b.putStringArray("selectedItems", outputStrArr);
intent.putExtras(b);
startActivity(intent);
}
}
});
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView arg0, View arg1, int arg2, long arg3) {
}
});
}
}
Perhaps you can use unique ID's.
In every list item you can have an invisible TextView that will store the ID.
On click assign to some variable the ID and you can use it later.
Hope that helps.
Lets say your list items XML are as so:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- Contact name -->
<TextView
android:id="#+id/contactName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<!-- Contact Unique ID -->
<TextView
android:id="#+id/contactID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible"/>
In your activity class add the following variables:
static int uid;
int selectedId;
Then before initializing the list add:
uid = 0;
In the adapter or whatever way you add views to list do:
TextView id = (TextView)yourListItem.findViewById(R.id.contactID);
id.setText(String.valueOf(uid));
uid++;
And finally in the onClickListener of the list item add:
TextView id = (TextView)yourListItem.findViewById(R.id.contactID);
selectedId = Integer.parseInt(id.getText().toString());
That way you can fetch the selected list item later - by comparing the selected id.

Filter Data from List<String> in android onTextChange Android

I have little problem with filter data from List.i want to filter data from List. My Problem is wech i start to write text on edittext than the listview shows thw only first posision of the List.
Here is my Code.
MainClass
public class ItemType extends AppCompatActivity {
ListView item;
Context context=this;
List<String> allItemNames = new ArrayList<String>();
Item_Type_list_adapter adapter;
EditText search;
ArrayAdapter<String> adapter1;
String[] data = {"mehul joisar","amit mishra","amitabh","Aamir khan","jesica","katrina"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_item_type);
search=(EditText)findViewById(R.id.Search);
item=(ListView)findViewById(R.id.item_type_listview);
allItemNames = new ArrayList<String>();
allItemNames.add("Coil");
allItemNames.add("Plate");
allItemNames.add("Sheet");
allItemNames.add("Extra");
adapter=new Item_Type_list_adapter(this,allItemNames);
item.setAdapter(adapter);
item.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String data = (String) adapterView.getItemAtPosition(i);
Log.d("Positions", data);
}
});
search.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence cs, int i, int i1, int i2) {
adapter.getFilter().filter(search.getText().toString());
adapter.notifyDataSetChanged();
}
#Override
public void afterTextChanged(Editable editable) {
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_item_type, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
return super.onOptionsItemSelected(item);
}
}
ArrayAdapter Class
public class Item_Type_list_adapter extends ArrayAdapter<String> implements Filterable {
Activity context;
private final List<String> allNames;
public Item_Type_list_adapter(Activity context,List<String> allNames) {
super(context, R.layout.item_type_layout,allNames);
this.context=context;
this.allNames=allNames;
}
public View getView(int position,View view,ViewGroup parent) {
LayoutInflater inflater=context.getLayoutInflater();
View rowView=inflater.inflate(R.layout.item_type_layout, null, true);
TextView ItemName = (TextView) rowView.findViewById(R.id.ItemName);
ItemName.setText(allNames.get(position));
return rowView;
};
}
I Add the 4 value in List
1.Coil
2.Plate
3.sheet
4.extra
And when i start filter it only showing the Coil.But When i touch on listview its Log perfect Value But just Showing Wrong value.
Help me to solve this issue.
is there any missing in my code?
Thanks in advance
Try out this code for filtering ListView with EditText
activity_main.xml
<EditText
android:id="#+id/etText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10">
<requestFocus />
</EditText>
<ListView
android:id="#+id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:divider="#android:color/transparent"
android:isScrollContainer="false" />
a new TextView layout called item.xml for showing items
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
</TextView>
onCreate() method inside MainActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Array list of items
List<String> itemsList = new ArrayList<String>();
itemsList.add("AAAA");
itemsList.add("AABC");
itemsList.add("ABCD");
itemsList.add("BBCD");
itemsList.add("BCDE");
itemsList.add("CCDE");
itemsList.add("CDEF");
// create an ArrayAdaptar from the String Array
final ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,
R.layout.item, itemsList);
ListView listView = (ListView) findViewById(R.id.list);
// Assign adapter to ListView
listView.setAdapter(dataAdapter);
// enables filtering for the contents of the given ListView
listView.setTextFilterEnabled(true);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// When clicked, show a toast with the TextView text
Toast.makeText(getApplicationContext(),
((TextView) view).getText(), Toast.LENGTH_SHORT).show();
}
});
EditText myFilter = (EditText) findViewById(R.id.etText);
myFilter.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
public void onTextChanged(CharSequence s, int start, int before,
int count) {
dataAdapter.getFilter().filter(s);
}
});
}
hope it helps

How to use elements in autoCompleteTextView?

I want to convert choosen element to Integer. When it's done I want to add a random number between 1-20 to choosen Integer. Than show up that number in Toast.
To convert a value coming from a TextView to an integer, you just need to use the following code:
EditText tViewNum = (EditText) rootView.findViewById(R.id.number);
String strWord = tViewNum.getText().toString();
Random r = new Random();
int i1 = r.nextInt(21 - 1) + 20;
String Randomiser = strWord + " " + il; //the +" "+ is used to add a space between the word and the random number.
Toast.makeText(MainActivity.this, Randomiser + "//any other text you wish to include", Toast.LENGTH_SHORT).show();
Note that the random number given here is between 1 (inclusive) and 20 (inclusive).
use a widget forAutoCompleteTextView.
"CustomAutoCompleteTextView"
public class CustomAutoCompleteTextView extends AutoCompleteTextView {
public CustomAutoCompleteTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void performFiltering(final CharSequence text, final int keyCode) {
// String filterText = "";
super.performFiltering(text, keyCode);
}
/**
* After a selection, capture the new value and append to the existing
* text
*/
#Override
protected void replaceText(final CharSequence text) {
super.replaceText(text);
}
}
Your Xml will be like this:[Depend where you add your widget ]
<com.example.widget.CustomAutoCompleteTextView
android:id="#+id/sent_message_to"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_margin="10dip"
android:layout_weight="1"
android:imeOptions="actionSend"
android:hint="name"
android:gravity="left|center"
android:padding="10dip"
android:textColor="#color/green"
android:textSize="18dp"
android:visibility="visible"
android:selectAllOnFocus="true"
android:inputType="textPersonName"
android:completionThreshold="3"
/>
Main class
you can set adapter for list value or declare array
private AutoCompleteAdapter mAutoCompleteAdapter;
private ArrayList<String> mArray = new ArrayList<String>();
private CustomAutoCompleteTextView mAutoFillTextView;
.....
mAutoFillTextView = mViewUtils.createAutoFillTextView(view.findViewById(R.id.sent_message_to), false);
mAutoCompleteAdapter = new AutoCompleteAdapter(getActivity(), mArray);
mAutoFillTextView.setAdapter(mAutoCompleteAdapter);
and
mAutoFillTextView.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(final CharSequence s, int start, int before, int count) {
try {
mArray.clear();
String string = s.toString().trim();
if (mAutoFillTextView.getThreshold() <= string.length() && mAllowRequest) {
//GET DATA TO LIST
}
} catch (NullPointerException ignored) {
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
});

Categories

Resources