I am trying to create a simple list view with a search box at the top. Hamy gives an excellent tutorial in this thread. However, I’ve run into one problem at the end of this – there is a line that references a layout XML file:
filterText = (EditText) findViewById(R.id.search_box);
Eclipse throws an error, insofar as ‘id’ cannot be resolved (or is not a field). My layout XML file contains the following:
<!-- Pretty hint text, and maxLines -->
<EditText android:id="@+building_list/search_box"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="type to filter"
android:inputType="text"
android:maxLines="1"/>
<!-- Set height to 0, and let the weight param expand it -->
<!-- Note the use of the default ID! This lets us use a
ListActivity still! -->
<ListView android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"
/>
I’ve tried some obvious fixes, such as replacing the line
<EditText android:id="@+building_list/search_box"
with:
<EditText android:id="@+id/search_box"
…This removes the error, but if I try to put anything into the text box, the app crashes.
Where have I gone wrong? For completeness, here is the content of my java file:
package mjd.listview.test;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.R.id;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.app.Dialog;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import au.com.bytecode.opencsv.CSVReader;
public class ListProjectActivity extends ListActivity {
private EditText filterText = null; // used in filtering the list
ArrayAdapter<String> adapter = null; // used in filtering the list
/** Called when the activity is first created. */
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.filterable_listview); // load the layout file 'filterable_listview.xml'
filterText = (EditText) findViewById(R.id.search_box); // used in filtering the list
filterText.addTextChangedListener(filterTextWatcher); // used in filtering the list
String next[] = {}; // 'next' is used to iterate through dictionaryFile
List<String[]> dictionaryArray = new ArrayList<String[]>();
try {
CSVReader reader = new CSVReader(new InputStreamReader(getAssets().open("dictionaryFile.csv")));
while((next = reader.readNext()) != null) {
dictionaryArray.add(next);
}
} catch (IOException e) {
e.printStackTrace();
}
String[] terms = dictionaryArray.get(0); // load terms from dictionaryArray
setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, terms));
ListView lv = getListView();
lv.setOnItemClickListener(new OnItemClickListener() { // when an item is clicked on...
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
AlertDialog alertDialog = new AlertDialog.Builder(ListProjectActivity.this).create(); // create a dialog box in memory
alertDialog.setTitle(((TextView) view).getText()); // set title of dialog box to term name
alertDialog.setMessage("Put definition here"); // set dialog box message to term definition
alertDialog.show(); // actually display the dialog box
}
});
}
// The whole block below is used in filtering the list
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) {
adapter.getFilter().filter(s);
}
};
@Override
protected void onDestroy() {
super.onDestroy();
filterText.removeTextChangedListener(filterTextWatcher);
}
}
EDIT: I have a suspicion this relates to the fact that I later use a different list layout (see the line below)
setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, terms));
Perhaps that ‘list_item’ needs to be something like ‘android:id/list’? But I can’t get the syntax right to make it reference properly… Any ideas?
I suspect that your error is another issue entirely (not related to R.id.search_box)
When you use
you need to reference it using
In your case, using
(which you have tried) will solve that first issue, as you are referencing it with
That done, your logcat indicates that there is a NullPointerException occuring in the onTextChanged method. In my experience, this is usually an object reference that hasn’t been initialised, or an array related issue. In your case, you’re calling
in the onTextChanged method, but it doesn’t look like you have actually set adapter to anything anywhere in the code. From what I can gather this is supposed to do, try replacing
with