I am trying to modify the contents of a ListView as the user types into an EditText. It is working mostly but the strange thing is that it does not restore the list when characters are deleted. when going through debugger mode I see two things happening and I don't know why.
jobs
which containes the original list is modified, even though I am not modifying it in my code as far as I know.In the
getNewArray
method,if(newArray.size() == 0) { return jobs; }
is never executed even whennewArray.size()
is 0 (checked in debugger mode)
here is the activity:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Arrays;
public class MainActivity extends AppCompatActivity {
String[] stringArray = {"557K", "559B", "601A", "357K", "459B", "501A", "657K", "759B", "801A"};
private ArrayList<String> jobs;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
jobs = new ArrayList<String>(Arrays.asList(stringArray));
setContentView(R.layout.activity_main);
ListView listView = (ListView)findViewById(R.id.listView);
final ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, jobs);
listView.setAdapter(adapter);
final EditText editText = (EditText) findViewById(R.id.editText);
// set listener for list view. clicked item populates the EditText
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String text = ((TextView) view).getText().toString();
String[] subStrings = text.split(" :", 2);
editText.setText(subStrings[0]);
}
});
// set text watcher to modify content in list as user types into EditText
TextWatcher textWatcher = 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) {
}
@Override
public void afterTextChanged(Editable editable) {
// get modified array
ArrayList<String> newList = StringMatcher.getNewArray(jobs, editable.toString());
// refresh viewList
adapter.clear();
adapter.addAll(newList);
adapter.notifyDataSetChanged();
}
};
editText.addTextChangedListener(textWatcher);
}
@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_main, 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
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/editText" />
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/listView" />
StringMatcher class:
import java.util.ArrayList;
public class StringMatcher {
private StringMatcher(){}
/**
* Taken from András Belicza
* http://stackoverflow.com/questions/86780/is-the-contains-method-in-java-lang-string-case-sensitive
* On 29/10/2015
* @param src
* @param what
* @return
*/
private static boolean containsIgnoreCase(String src, String what) {
final int length = what.length();
if (length == 0)
return true; // Empty string is contained
final char firstLo = Character.toLowerCase(what.charAt(0));
final char firstUp = Character.toUpperCase(what.charAt(0));
for (int i = src.length() - length; i >= 0; i--) {
// Quick check before calling the more expensive regionMatches() method:
final char ch = src.charAt(i);
if (ch != firstLo && ch != firstUp)
continue;
if (src.regionMatches(true, i, what, 0, length))
return true;
}
return false;
}
public static ArrayList<String> getNewArray(ArrayList<String> jobs, String newString) {
ArrayList<String> newArray = new ArrayList<String>();
for(String job: jobs){
if(containsIgnoreCase(job,newString))
newArray.add(job);
}
if(newArray.size() == 0) {
return jobs;
}
else {
return newArray;
}
}
}