Problem
- Create a ListView
- Enable filtering for the text view
- Make sure that the first item is disabled
- Filter the view so that the first item is not shown
If you do this you can see that the new first item is disabled.
See the attached screenshots:


The problem is that when the ListView filters actually changes the position of the items so the item that use to have position 10 now has position 0 which is what causes the problem.
So how do I best work around this?
Below is the smallest possible sample code that demonstrates the problem, just filter for something other than the first three items.
CustomListActivity.java
package com.example.bug;
import android.app.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
public class CustomListActivity extends ListActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String items[] = new String[100];
for(int i = 0; i < items.length; ++i)
items[i] = "Item " + (i+1);
setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, items) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
view.setEnabled(isEnabled(position));
return view;
}
@Override
public boolean areAllItemsEnabled() {
return false;
}
@Override
public boolean isEnabled(int position) {
return position >= 3;
}
});
getListView().setTextFilterEnabled(true);
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0" package="com.example.bug">
<uses-sdk android:minSdkVersion="7" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name="CustomListActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
res/color/list_item_colors.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="#777" />
<item android:color="#fff" />
</selector>
res/layout/list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="10sp"
android:textSize="16sp"
android:textColor="@color/list_item_colors" />
If you know that no other part of your program will be using the tag associated with the Views that represent the items in the list, you could initialize this the first time getView() is called (when presumably the filter will be empty) and then use the value of the tag on later calls to determine whether or not the items are enabled. For example :
EDIT: Based on the replies below, if it’s possible to use something other than Strings as the array elements, I would recommend the following. Create a new class used to represent the elements –
then change the array from Strings to Elements :
Finally, change the ArrayAdapter declaration and getView method to the following :