Question

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?

Was it helpful?

Solution

I suspect that your error is another issue entirely (not related to R.id.search_box)

When you use

android:id="@+building_list/search_box"

you need to reference it using

findViewById(R.building_list.search_box)

In your case, using

android:id="@+id/search_box"

(which you have tried) will solve that first issue, as you are referencing it with

findViewById(R.id.search_box)

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

adapter.getFilter().filter(s);

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

setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, terms));

with

adapter= new ArrayAdapter<String>(this, R.layout.list_item, terms));
setListAdapter(adapter); 

OTHER TIPS

You imported android.R.id instead of mjd.listview.test.R (or something similar)

Let see guide about using R : http://developer.android.com/guide/topics/resources/accessing-resources.html

please post the logcat

i think the problem is not the layout,

is the exception in the onTextChanged method. I think the adapter is null and the adapter.getFilter().filter(s) throw the exception.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top