Java 当使用自定义适配器筛选自定义ListView时,会出现崩溃和空指针
我有一个自定义的listView,其中包含100多个条目/对象,这就是我想要实现搜索/过滤功能的原因。我已经做了很多,但是当我在editText中键入某些内容时,由于此处的空指针,应用程序崩溃:Java 当使用自定义适配器筛选自定义ListView时,会出现崩溃和空指针,java,android,listview,filter,Java,Android,Listview,Filter,我有一个自定义的listView,其中包含100多个条目/对象,这就是我想要实现搜索/过滤功能的原因。我已经做了很多,但是当我在editText中键入某些内容时,由于此处的空指针,应用程序崩溃: @覆盖 public void onTextChanged(字符序列、int start、int before、int count){ adapter.getFilter().filter; } 这是我的主要活动: public class MainActivity extends AppCompatA
@覆盖
public void onTextChanged(字符序列、int start、int before、int count){
adapter.getFilter().filter;
}
这是我的主要活动:
public class MainActivity extends AppCompatActivity implements TextWatcher{
MyAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView lw = findViewById(R.id.lw);
EditText suche = findViewById(R.id.suchen);
suche.addTextChangedListener(this);
final ArrayList<Objekt> arrayList = new ArrayList();
arrayList.add(new Objekt("AAA", "AAA1"));
arrayList.add(new Objekt("BBB", "BBB1"));
arrayList.add(new Objekt("CCC", "CCC1"));
arrayList.add(new Objekt("DDD", "DDD1"));
arrayList.add(new Objekt("EEE", "EEE1"));
arrayList.add(new Objekt("FFF", "FFF1"));
final MyAdapter adapter = new MyAdapter(this,arrayList);
lw.setAdapter(adapter);
lw.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String selection = arrayList.get(position).getKuerzel();
if(selection.equals("AAA")){
Intent intent = new Intent(MainActivity.this, AAA.class);
startActivity(intent);
} else if (selection.equals("BBB")){
Intent intent = new Intent(MainActivity.this, BBB.class);
startActivity(intent);
} else if (selection.equals("CCC")){
Intent intent = new Intent(MainActivity.this, CCC.class);
startActivity(intent);
} else if (selection.equals("DDD")){
Intent intent = new Intent(MainActivity.this, DDD.class);
startActivity(intent);
} else if (selection.equals("EEE")){
Intent intent = new Intent(MainActivity.this, EEE.class);
startActivity(intent);
} else if (selection.equals("FFF")){
Intent intent = new Intent(MainActivity.this, FFF.class);
startActivity(intent);
}
}
});
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
adapter.getFilter().filter(s); //<-- nullPointer here
}
@Override
public void afterTextChanged(Editable s) {
}
还有我的Objekt课程:
public class Objekt {
String kuerzel;
String fullAdress;
public Objekt(String kuerzel, String fullAdress) {
this.kuerzel = kuerzel;
this.fullAdress = fullAdress;
}
public String getKuerzel() {
return kuerzel;
}
public void setKuerzel(String kuerzel) {
this.kuerzel = kuerzel;
}
public String getFullAdress() {
return fullAdress;
}
public void setFullAdress(String fullAdress) {
this.fullAdress = fullAdress;
}
}之所以会发生这种情况,是因为当您设置
侦听器时,适配器未初始化
您还在类级别声明了一个变量adapter
,但再次创建了局部变量adapter并将局部值传递给list
因此,将行更改为adapter=newmyadapter(这是arrayList)代码>
如果这不能解决问题,那么在设置适配器后设置侦听器
adapter = new MyAdapter(this,arrayList);
suche.addTextChangedListener(this);
好的,所以我将问题简化为简单的问题:
public class StackOverflow extends AppCompatActivity implements TextWatcher
{
MyAdapter adapter;
@Override
protected void onCreate( Bundle savedInstanceState )
{
/* ..*/
final MyAdapter adapter = new MyAdapter( this, arrayList );
ListView lw = findViewById(R.id.lw);
/*..*/;
lw.setAdapter( adapter );
/* ..*/
}
/* ..*/
@Override
public void onTextChanged( CharSequence s, int start, int before, int count )
{
adapter.getFilter().filter( s ); //<-- nullPointer here
}
/* ..*/
}
class MyAdapter{
/*...*/
}
但是,这与onCreate
方法中的变量不同:
final MyAdapter adapter = new MyAdapter( this, arrayList );
它具有相同的名称,并对字段进行阴影处理,但由于它声明了自身,因此是一个不同的变量。它只能在onCreate
方法中访问(“在范围内”),在onTextChanged
中不存在
删除阴影并初始化字段将解决NullPointerException
:
/*deleted: final Adapter*/ adapter = new MyAdapter( this, arrayList );
这是可行的,但是初始化方法中的字段不是一个好的实践。通常最好在构造函数内初始化字段。但是,由于它需要MainActivity
本身作为其上下文,因此在这里不起作用。我建议进一步重构它,以消除Adapter
构造函数中MainActivity
参数的需要,这超出了本答案的范围
希望这有帮助 非常感谢您详尽的回答!帮了大忙
MyAdapter adapter;
final MyAdapter adapter = new MyAdapter( this, arrayList );
/*deleted: final Adapter*/ adapter = new MyAdapter( this, arrayList );