首页 > 解决方案 > 尝试在空对象引用上调用虚拟方法“android.widget.Filter com.app.app.adapter.TextTypingCustomAdapter.getFilter()”

问题描述

我为我的 searchview 添加了一个过滤器,以显示与查询匹配的 recyclerview 项目。搜索似乎有效,但如果 recyclerview 中没有项目,应用程序会崩溃,所以有人可以帮我一下吗?

我的片段:

public class TextTypingTabFragment extends Fragment implements TabLayoutFragmentPagerAdapter.ITabLayoutIconFragmentPagerAdapter {
    private static final String TAG = TextTypingTabFragment.class.getSimpleName();

    private final TextTypingLoaderCallbacks mLoaderCallbacks = new TextTypingLoaderCallbacks();
    private TextTypingCustomAdapter mTextTypingCustomAdapter;

    private View mView;
    private ProgressBar mProgressBar;
    private ScrollView mScrollView;
    private RecyclerView mRecyclerView;

    public TextTypingTabFragment() {
        // Required empty public constructor
    }

    // ----

    private Context getContextNonNull() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            return Objects.requireNonNull(getContext());
        } else {
            return getContext();
        }
    }

    // ----

    private int mItemCount = -1;
    private int mFirstVisibleItemPosition = -1, mFirstCompletelyVisibleItemPosition = -1;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LogUtil.d(TAG, "Fragment create");

        Bundle bundle = new Bundle();
        bundle.putString(AppEnvr.EXTRA_PACKAGE_NAME_KEY, MainActivity.sSelectedPackageName);

        getLoaderManager().initLoader(1, bundle, mLoaderCallbacks); // Init with 1

        setHasOptionsMenu(true);
        // ----

        LocalBroadcastManager.getInstance(getContextNonNull()).registerReceiver(mSelectedPackageNameChangedCustomReceiver, new IntentFilter(AppEnvr.ACTION_SELECTED_PACKAGE_NAME_CHANGED));
    }

    @Override
    public void onResume() {
        super.onResume();
        LogUtil.d(TAG, "Fragment resume");

        Bundle bundle = new Bundle();
        bundle.putString(AppEnvr.EXTRA_PACKAGE_NAME_KEY, MainActivity.sSelectedPackageName);

        getLoaderManager().restartLoader(1, bundle, mLoaderCallbacks); // Restart with 1
    }

    @Override
    public void onPause() {
        super.onPause();
        LogUtil.d(TAG, "Fragment pause");

        if (mTextTypingCustomAdapter != null) {
            mItemCount = mTextTypingCustomAdapter.getItemCount();
        }

        if (mRecyclerView != null) {
            LinearLayoutManager linearLayoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();

            if (linearLayoutManager != null) {
                mFirstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition();
                mFirstCompletelyVisibleItemPosition = linearLayoutManager.findFirstCompletelyVisibleItemPosition();
            }
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        LogUtil.d(TAG, "Fragment destroy");

        LocalBroadcastManager.getInstance(getContextNonNull()).unregisterReceiver(mSelectedPackageNameChangedCustomReceiver);
    }

    // ----

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);

        return inflater.inflate(R.layout.fragment_text_typing_tab, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        mView = view;
        mProgressBar = view.findViewById(R.id.fragment_text_typing_tab_progress_bar);
        mScrollView = view.findViewById(R.id.fragment_text_typing_tab_scroll_view);
        mRecyclerView = view.findViewById(R.id.fragment_text_typing_tab_recycler_view);
    }

    // ----

    @Override
    public Fragment getItem() {
        return this;
    }

    @Override
    public CharSequence getPageTitle() {
        return "History";
    }

    @Override
    public int getIcon() {
        return R.drawable.ic_typesave;
    }

    @Override
    public void onCreateOptionsMenu(@NonNull Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.typed_text_fragment_menu, menu);

        final SearchView searchView = new SearchView(getActivity());
        searchView.setQuery(null, true);
        searchView.setQueryHint("Search");
        EditText searchEditText = searchView.findViewById(androidx.appcompat.R.id.search_src_text);
        searchEditText.setTextColor(getResources().getColor(R.color.white));
        searchEditText.setHintTextColor(getResources().getColor(R.color.tabTextColor));

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String s) {
                Filter filter = mTextTypingCustomAdapter.getFilter();

                if (filter != null) {
                    filter.filter(s);

                    return true;
                }

                return false;
            }

            @Override
            public boolean onQueryTextChange(String s) {
                Filter filter = mTextTypingCustomAdapter.getFilter();

                if (filter != null) {
                    filter.filter(s);

                    return true;
                }

                return false;
            }
        });

        menu.findItem(R.id.action_search).setActionView(searchView);

    }

    // ----

    private final BroadcastReceiver mSelectedPackageNameChangedCustomReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            LogUtil.d(TAG, "Receiver receive");

            // ----

            if (context == null || intent == null) {
                if (context == null) {
                    LogUtil.w(TAG, "Receiver receive: Context lack");
                }

                if (intent == null) {
                    LogUtil.w(TAG, "Receiver receive: Intent lack");
                }

                return;
            }

            // ----

            String intentAction = null;
            try {
                intentAction = intent.getAction();
            } catch (Exception e) {
                LogUtil.e(TAG, e.getMessage());
                LogUtil.e(TAG, e.toString());

                e.printStackTrace();
            }

            if (intentAction == null || !intentAction.equals(AppEnvr.ACTION_SELECTED_PACKAGE_NAME_CHANGED)) {
                if (intentAction == null) {
                    LogUtil.w(TAG, "Receiver receive: Intent action lack");
                } else if (!intentAction.equals(AppEnvr.ACTION_SELECTED_PACKAGE_NAME_CHANGED)) {
                    LogUtil.w(TAG, "Receiver receive: Intent action mismatch");
                }

                return;
            }

            // ----

            LogUtil.d(TAG, "Receiver receive: OK");

            // ----

            Bundle extras = null;
            try {
                extras = intent.getExtras();
            } catch (Exception e) {
                LogUtil.e(TAG, e.getMessage());
                LogUtil.e(TAG, e.toString());

                e.printStackTrace();
            }

            if (extras != null) {
                if (extras.containsKey(AppEnvr.EXTRA_PACKAGE_NAME_KEY)) {
                    String packageName = extras.getString(AppEnvr.EXTRA_PACKAGE_NAME_KEY, null);

                    // ----

                    Bundle bundle = new Bundle();
                    bundle.putString(AppEnvr.EXTRA_PACKAGE_NAME_KEY, packageName);

                    getLoaderManager().restartLoader(1, bundle, mLoaderCallbacks); // Restart with 1
                }
            }
        }
    };

    // ----

    private final class TextTypingLoaderCallbacks implements LoaderManager.LoaderCallbacks<ArrayList<TextTypingObject>> {
        private String mPackageName = null;

        @NonNull
        @Override
        public Loader<ArrayList<TextTypingObject>> onCreateLoader(int i, @Nullable Bundle bundle) {
            if (mScrollView != null) {
                mScrollView.setVisibility(View.GONE);
            }

            if (mRecyclerView != null) {
                mRecyclerView.setVisibility(View.GONE);
            }

            if (mProgressBar != null) {
                mProgressBar.setVisibility(View.VISIBLE);
            }

            // ----

            if (bundle != null) {
                mPackageName = bundle.getString(AppEnvr.EXTRA_PACKAGE_NAME_KEY, null);
            }

            // ----

            return new TextTypingLoader(getContextNonNull(), mPackageName);
        }

        @Override
        public void onLoadFinished(@NonNull Loader<ArrayList<TextTypingObject>> loader, @Nullable ArrayList<TextTypingObject> textTypingObjectArrayList) {
            if (textTypingObjectArrayList != null && !textTypingObjectArrayList.isEmpty()) {
                mTextTypingCustomAdapter = new TextTypingCustomAdapter(getContextNonNull(), textTypingObjectArrayList);
            } else {
                if (mTextTypingCustomAdapter != null) {
                    mTextTypingCustomAdapter = null;
                }

                // ----

                if (mPackageName != null && MainActivity.sSelectedPackageName != null) {
                    mPackageName = null;
                    MainActivity.sSelectedPackageName = null;

                    getLoaderManager().restartLoader(1, null, mLoaderCallbacks); // Restart with 1

                    return;
                }
            }

            // ----

            if (mProgressBar != null) {
                mProgressBar.setVisibility(View.GONE);
            }

            if (mTextTypingCustomAdapter != null) {
                if (mRecyclerView != null) {
                    int scrollToPosition = -1;

                    // ----

                    if (mItemCount != -1 && mFirstVisibleItemPosition != -1) {
                        int newItemCount = mTextTypingCustomAdapter.getItemCount();

                        // ----

                        if (newItemCount == mItemCount) { // No added/removed events
                            scrollToPosition = mFirstVisibleItemPosition;
                        } else if (newItemCount > mItemCount) { // Added events found
                            if (mFirstVisibleItemPosition != 0) {
                                int addedEventsCount = newItemCount - mItemCount;

                                scrollToPosition = mFirstVisibleItemPosition + addedEventsCount;

                                // ----

                                if (addedEventsCount >= 1 && mFirstVisibleItemPosition >= 1) {
                                    Snackbar snackbar = Snackbar.make(mView, getContextNonNull().getString(R.string.new_events_found, addedEventsCount) + " (text typing)", Snackbar.LENGTH_SHORT);
                                    snackbar.setAction(getContextNonNull().getString(R.string.scroll), v -> mRecyclerView.smoothScrollToPosition(0));
                                    snackbar.show();
                                }
                            }
                        } else /*if (newItemCount < mItemCount)*/ { // Removed events found
                            scrollToPosition = mFirstVisibleItemPosition;
                        }

                        // ----

                        mFirstVisibleItemPosition = -1;
                        mItemCount = -1;
                    }

                    // ----

                    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(mRecyclerView.getContext());
                    linearLayoutManager.setOrientation(RecyclerView.VERTICAL);
                    if (scrollToPosition != -1) {
                        linearLayoutManager.scrollToPosition(scrollToPosition);
                    }

                    mRecyclerView.setLayoutManager(linearLayoutManager);
                    mRecyclerView.setItemAnimator(new DefaultItemAnimator());
                    mRecyclerView.setAdapter(mTextTypingCustomAdapter);

                    // ----

                    mRecyclerView.setVisibility(View.VISIBLE);

                    // ----
                }
            } else {
                if (mScrollView != null) {
                    mScrollView.setVisibility(View.VISIBLE);
                }
            }

            // ----

            if (mPackageName != null) {
                mPackageName = null;
            }
        }

        @Override
        public void onLoaderReset(@NonNull Loader loader) {
        }
    }
}

搜索查看代码:

    @Override
    public void onCreateOptionsMenu(@NonNull Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.typed_text_fragment_menu, menu);

        final SearchView searchView = new SearchView(getActivity());
        searchView.setQuery(null, true);
        searchView.setQueryHint("Search");
        EditText searchEditText = searchView.findViewById(androidx.appcompat.R.id.search_src_text);
        searchEditText.setTextColor(getResources().getColor(R.color.white));
        searchEditText.setHintTextColor(getResources().getColor(R.color.tabTextColor));

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String s) {
                Filter filter = mTextTypingCustomAdapter.getFilter();

                if (filter != null) {
                    filter.filter(s);

                    return true;
                }

                return false;
            }

            @Override
            public boolean onQueryTextChange(String s) {
                Filter filter = mTextTypingCustomAdapter.getFilter();

                if (filter != null) {
                    filter.filter(s);

                    return true;
                }

                return false;
            }
        });

        menu.findItem(R.id.action_search).setActionView(searchView);

    }

错误日志:尝试在空对象引用上调用虚拟方法“android.widget.Filter com.app.app.adapter.TextTypingCustomAdapter.getFilter()”

标签: javaandroidnullpointerexception

解决方案


当你要像这样过滤时

Filter filter = mTextTypingCustomAdapter.getFilter();

如果不匹配任何项目。那么您的变量mTextTypingCustomAdapter为空。您应该在过滤两种方法之前检查空安全性(onQueryTextSubmit() && onQueryTextChange()

if(mTextTypingCustomAdapter != null){
Filter filter = mTextTypingCustomAdapter.getFilter();}

推荐阅读