自定义 listView 数组,搜索,在 NotifyDataSetChanged 上崩溃,加上 listView 没有得到更新

Posted

技术标签:

【中文标题】自定义 listView 数组,搜索,在 NotifyDataSetChanged 上崩溃,加上 listView 没有得到更新【英文标题】:Custom listView Array, Search, crash on NotifyDataSetChanged, plus the listView is not getting updated 【发布时间】:2021-06-08 18:32:30 【问题描述】:

我正在调试问题,我可以得到它已被过滤,但刷新应用程序会崩溃,

我正在从数据库中获取列表,显示没有问题,

过滤列表时,应用在 notifyDataSetChanged() 时崩溃

请帮忙


public class ViewListContents extends AppCompatActivity implements Filterable  
    DatabaseHelper myDB;
    ArrayList<User> userList;
    ArrayList<User> userListFiltered;
    ListView listView;
    User user;
    TextView firstName;
    TextView lastName;
    TextView favFood;
    MediaPlayer player;
    private int featureCustomTitle;
    ThreeColumn_ListAdapter adapter;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);

        setContentView(R.layout.viewcontents_layout);
        myDB = new DatabaseHelper(this);
        userList = new ArrayList<>();
        Cursor data = myDB.getListContents();
        ListView listView = (ListView) findViewById(R.id.listView);
        TextView firstName = (TextView) findViewById(R.id.textFirstName);
        TextView lastName = (TextView) findViewById(R.id.textLastName);
        TextView favFood = (TextView) findViewById(R.id.textFavFood);
        ThreeColumn_ListAdapter adapter = new ThreeColumn_ListAdapter(this, R.layout.list_adapter_view, userList);
        listView.setAdapter(adapter);

        MenuItem menuItem = findViewById(R.id.search_view);
        this.userList = userList;
        this.userListFiltered = userList;

        player = MediaPlayer.create(this, Settings.System.DEFAULT_ALARM_ALERT_URI);
        int numRows = data.getCount();
        if (numRows == 0) 
            Toast.makeText(ViewListContents.this, "The Database is empty  :(.", Toast.LENGTH_SHORT).show();
         else 
            int i = 0;
            while (data.moveToNext()) 
                user = new User(data.getString(1), data.getString(2), data.getString(3));
                userList.add(i, user);
                System.out.println(data.getString(1) + " " + data.getString(2) + " " + data.getString(3));
                System.out.println(userList.get(i).getFirstName());
                i++;
            

        

        menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() 
            @Override
            public boolean onMenuItemClick(MenuItem item) 
                if (item.getGroupId() == R.id.search_view) 
                    Log.e("main activity","item clicked");
                    //startActivity(new Intent(getContext(),ThreeColumn_ListAdapter.class).putExtra("itemss",userListFiltered.get(position)));

                    Intent intent = new Intent(getApplicationContext(), ThreeColumn_ListAdapter.class);
                    intent.putExtra("nvp", userListFiltered);
                    startActivity(intent);
                    return true;
                 else 
                    // edit shape menu
                    return false;

                
            
        );

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() 
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) 
                TextView v;
                player.setLooping(true);
                player.start();
                v =  view.findViewById(R.id.textFirstName);
                Toast.makeText(getApplicationContext(), "selected Item Name is " + v.getText().toString(), Toast.LENGTH_SHORT).show();
            
        );
    

    @Override
    public boolean onCreateOptionsMenu(Menu menu)  
        getMenuInflater().inflate(R.menu.menu, menu);

        MenuItem menuItem = menu.findItem(R.id.search_view);

        SearchView searchView = (SearchView) menuItem.getActionView();

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() 
                                              @Override
                                              public boolean onQueryTextSubmit(String query) 
                                                  return false;
                                              

                                              @Override
                                              public boolean onQueryTextChange(String newText) 
                                                  //ThreeColumn_ListAdapter adapter = new ThreeColumn_ListAdapter(getApplicationContext(), R.layout.list_adapter_view, userList);
                                                  //  Toast.makeText(getApplicationContext(),newText,Toast.LENGTH_SHORT).show();
                                                  getFilter().filter(newText);



                                                  return true;
                                              
                                          
        );
        return true;
    

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) 
        int id = item.getItemId();

        if(id == R.id.search_view)
            return true;
        


        return super.onOptionsItemSelected(item);
    


    @Override
    public Filter getFilter() 
        Filter filter = new Filter() 
            @Override
            protected FilterResults performFiltering(CharSequence constraint) 

                FilterResults filterResults = new FilterResults();

                if (constraint == null || constraint.length() == 0 )

                    filterResults.count = userList.size();
                    filterResults.values = userList;
                else
                    ArrayList<User> resultData = new ArrayList<>();
                    String searchStr = constraint.toString().toLowerCase();
                    Toast.makeText(getApplicationContext(),constraint,Toast.LENGTH_SHORT).show();
                    for (User user: userList)
                        if(user.getFirstName().contains(searchStr))

                            resultData.add(user);
                        
                        filterResults.count = resultData.size();
                        filterResults.values = resultData;
                    
                


                return filterResults;
            

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) 
                userListFiltered = (ArrayList<User>) results.values;
                adapter.notifyDataSetChanged();
            
        ;
        return filter;
    


Viewbtn 在 Fragment 中,所以我正在对如何创建列表搜索进行一些测试。

public class ThreeColumn_ListAdapter extends ArrayAdapter<User>  
    ArrayList<User> userList;
    ArrayList<User> userListFiltered;
    LayoutInflater mInflater;
    ArrayList<User> users;
    int mViewResourceId;
    private Context context;

    public ThreeColumn_ListAdapter(Context context, int textViewResourceId, ArrayList<User> users) 
        super(context, textViewResourceId, users);
        this.users = users;
        this.userList = users;
        this.userListFiltered = users;
        this.context = context;


        mInflater = (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
        mViewResourceId = textViewResourceId;
    

    @Override
    public int getCount() 
        return userListFiltered.size();
    

    @Override
    public User getItem(int position) 
        return userListFiltered.get(position);
    

    @Override
    public long getItemId(int position) 
        return position;
    

    public void updateData(ArrayList<User> userList)
        this.userList = userList;
        notifyDataSetChanged();
    

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
        convertView = mInflater.inflate(mViewResourceId, null);

        User user = users.get(position);

        if (user !=null)
            TextView firstName = (TextView) convertView.findViewById(R.id.textFirstName);
            TextView lastName = (TextView) convertView.findViewById(R.id.textLastName);
            TextView favFood = (TextView) convertView.findViewById(R.id.textFavFood);

            if (firstName != null)
                firstName.setText((user.getFirstName()));
            
            if (lastName != null)
                lastName.setText((user.getLastName()));
            
            if (favFood != null)
                favFood.setText((user.getFavFood()));
            

            // Toast.makeText(getContext(), "we are ok!!!", Toast.LENGTH_SHORT ).show();

        



        return convertView;
    


【问题讨论】:

您需要发布堆栈跟踪。有这么多代码,很难通读一遍并想出一个解决方案。 【参考方案1】:
    您的应用程序将因 NPE 崩溃,因为您的适配器未初始化。在 OnCreate 中,您正在初始化适配器,但这是一个本地适配器。您已经在 Global one 中清除了,但尚未初始化。

替换这个

ThreeColumn_ListAdapter adapter = new ThreeColumn_ListAdapter(this, R.layout.list_adapter_view, userList);

adapter = new ThreeColumn_ListAdapter(this, R.layout.list_adapter_view, userList);
    现在在过滤器之后,您只更新userListFiltered,但在适配器类中您已通过userList。所以 listview 不会在过滤器上更新。

更新过滤列表的列表

在适配器中创建 1 个方法

public void updateData(ArrayList<User> userList)
        this.userList = userList;
        notifyDataSetChanged();
    

 @Override
            protected void publishResults(CharSequence constraint, FilterResults results) 
                userListFiltered = (ArrayList<User>) results.values;
                adapter.updateData(userListFiltered);
            

【讨论】:

谢谢,现在它正在工作:),@Kishan 我如何将列表更新为新的 userListFilter? 仍然无法正常工作:(,我将在上面更新适配器当前代码 我调试过,我选的字母不存在,比如“Z”,我可以在更新中看到 iselist 值为零,但视图中的列表仍然没有更新。跨度> 我正在尝试添加这个 menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() @Override public boolean onMenuItemClick(MenuItem item) if (item.getGroupId() == R.id.search_view) Log.e("主要活动","项目点击"); Intent intent = new Intent(getApplicationContext(), ThreeColumn_ListAdapter.class); intent.putExtra("nvp", userListFiltered); startActivity(intent); return true;

以上是关于自定义 listView 数组,搜索,在 NotifyDataSetChanged 上崩溃,加上 listView 没有得到更新的主要内容,如果未能解决你的问题,请参考以下文章

Android自定义ListView:添加搜索功能

如何从自定义 ListView 适配器传递 Intent Extra?

通过自定义listView同时选择和搜索不起作用

如何从 Firebase 检索数据到 ListView(使用自定义数组适配器)

滚动时更新自定义列表视图失败

ListView 和自定义适配器在 Kotlin 中不起作用