Java 当使用自定义适配器筛选自定义ListView时,会出现崩溃和空指针

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

我有一个自定义的listView,其中包含100多个条目/对象,这就是我想要实现搜索/过滤功能的原因。我已经做了很多,但是当我在editText中键入某些内容时,由于此处的空指针,应用程序崩溃:

@覆盖
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 );