首页 > 解决方案 > 为什么 RecycleView 让我的应用程序在 Fragments 中崩溃?

问题描述

我对 RecyclerView 不太熟悉,所以请多多包涵,因为我不是 Android 专家。这里的问题是,当我从 NavDrawer 中单击菜单时,我的应用程序将崩溃。

我已经搜索过,但找不到一些运气。我已经在另一个项目中使用了相同的代码,该项目只显示了回收器视图,并且除了这个之外它都可以工作。

有人可以检查出了什么问题吗?

日志猫

2019-07-07 11:21:00.464 7321-7321/com.example.devcash E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.devcash, PID: 7321
    android.view.InflateException: Binary XML file line #10: Binary XML file line #10: Error inflating class fragment
    Caused by: android.view.InflateException: Binary XML file line #10: Error inflating class fragment
    Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference
        at com.example.devcash.Fragments.InventoryListFragment.initRecyclerView(InventoryListFragment.java:96)
        at com.example.devcash.Fragments.InventoryListFragment.initImageBitmaps(InventoryListFragment.java:90)
        at com.example.devcash.Fragments.InventoryListFragment.onCreateView(InventoryListFragment.java:64)
        at android.support.v4.app.Fragment.performCreateView(Fragment.java:2439)
        at android.support.v4.app.FragmentManagerImpl.ensureInflatedFragmentView(FragmentManager.java:1689)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1431)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1684)
        at android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1930)
        at android.support.v4.app.FragmentManagerImpl.onCreateView(FragmentManager.java:3745)
        at android.view.LayoutInflater$FactoryMerger.onCreateView(LayoutInflater.java:190)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:776)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:734)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:865)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:828)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:525)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:427)
        at com.example.devcash.Fragments.InventoryFragment.onCreateView(InventoryFragment.java:31)
        at android.support.v4.app.Fragment.performCreateView(Fragment.java:2439)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1460)
        at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
        at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:802)
        at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2625)
        at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2411)
        at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2366)
        at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273)
        at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:733)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:154)
        at android.app.ActivityThread.main(ActivityThread.java:6823)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1563)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1451)

InventoryListFragment.java

public class InventoryListFragment extends Fragment implements InventoryRecyclerViewAdapter.onInventoryListener{

    private static final String TAG = "InventoryListFragment";
    //variables
    private ArrayList<Integer> mIcon = new ArrayList<>();
    private ArrayList<String> mLabel = new ArrayList<>();

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


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_inventory_list, container, false);
        RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.inventorylist_recycleview);
        recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(getActivity())
                .build()); //adding a divider into the recyclerview list


        Log.d(TAG, "onCreateView: started");
        initImageBitmaps();

        return view;
    }

    private void initImageBitmaps(){
        Log.d(TAG, "initImageBitmaps: preparing bitmaps");

        mIcon.add(R.drawable.ic_product);
        mLabel.add("Products");

        mIcon.add(R.drawable.ic_customer);
        mLabel.add("Services");

        mIcon.add(R.drawable.ic_category);
        mLabel.add("Categories");

        mIcon.add(R.drawable.ic_tag);
        mLabel.add("Discounts");

        initRecyclerView();

    }

    private void initRecyclerView(){
//        Log.d(TAG, "initRecyclerView: init recyclerview");
        RecyclerView recyclerView = getView().findViewById(R.id.inventorylist_recycleview);
        InventoryRecyclerViewAdapter adapter = new InventoryRecyclerViewAdapter(getActivity(), mIcon, mLabel);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
    }

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


    }

    //method created from OnInventoryListener from InventoryListFragment.java
    //handles the onclick for the recycleview items
    @Override
    public void onInventoryClick(int position) {
        mLabel.get(position); //get the position of the clicked item

        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        switch (position){
            case 0:
                ProductsFragment productsFragment = new ProductsFragment();
                fragmentTransaction.replace(R.id.inventorylist_fragmentcontainer, productsFragment);
                fragmentTransaction.addToBackStack(null);
                fragmentTransaction.commit();
                break;
            case 1:
                ServicesFragment servicesFragment = new ServicesFragment();
                fragmentTransaction.replace(R.id.inventorylist_fragmentcontainer, servicesFragment);
                fragmentTransaction.addToBackStack(null);
                fragmentTransaction.commit();
                break;
            case  2:
                CategoriesFragment categoriesFragment = new CategoriesFragment();
                fragmentTransaction.replace(R.id.inventorylist_fragmentcontainer, categoriesFragment);
                fragmentTransaction.addToBackStack(null);
                fragmentTransaction.commit();
                break;
            case 3:
                DiscountsFragment discountsFragment = new DiscountsFragment();
                fragmentTransaction.replace(R.id.inventorylist_fragmentcontainer, discountsFragment);
                fragmentTransaction.addToBackStack(null);
                fragmentTransaction.commit();
                break;
        }

    }

InventoryRecyclerViewAdapter.java

public class InventoryRecyclerViewAdapter extends RecyclerView.Adapter<InventoryRecyclerViewAdapter.ViewHolder>{

    private static final String TAG = "RecyclerViewAdapter";
    private ArrayList<Integer> mIcon = new ArrayList<>();
    private ArrayList<String> mLabel = new ArrayList<>();
    private Context context;

    public InventoryRecyclerViewAdapter(Context context, ArrayList<Integer> mIcon, ArrayList<String> mLabel) {
        this.mIcon = mIcon;
        this.mLabel = mLabel;
        this.context = context;
    }

    //responsible for inflating the view
    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.customlayout_inventorylist, viewGroup, false);
        ViewHolder holder = new ViewHolder(view);
        return holder;
    }

        @Override
        public void onBindViewHolder(@NonNull InventoryRecyclerViewAdapter.ViewHolder viewHolder, final int i) {
            Log.d(TAG, "onBindViewHolder: called.");

            Glide.with(context)
                    .asBitmap()
                    .load(mIcon.get(i))
                    .into(viewHolder.icon);

            viewHolder.label.setText(mLabel.get(i));
            viewHolder.customLayout.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Log.d(TAG, "OnClick: clicked on: " + mLabel.get(i));
                    Toast.makeText(context, mLabel.get(i), Toast.LENGTH_SHORT).show();
                }
            });

        }

    @Override
    public int getItemCount() {
        return mLabel.size();
    }


    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
        ImageView icon;
        TextView label;
        LinearLayout customLayout;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            icon = itemView.findViewById(R.id.inventorylist_icon);
            label = itemView.findViewById(R.id.inventorylist_title);
            customLayout = itemView.findViewById(R.id.inventoryoptions_layout);

            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {

        }
    }

    public interface onInventoryListener{
        void onInventoryClick(int position);
    }

标签: androidandroid-recyclerviewfragment

解决方案


传递您膨胀的视图变量并findViewById在其上使用,而不是使用getView() .

getView()如果在返回视图之前调用它,则返回 null onCreateView()。(参考

更新:

initImageBitmaps方法一:调用onViewCreated

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

方法二:函数间传递视图变量

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_inventory_list, container, false);
        RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.inventorylist_recycleview);
        recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(getActivity())
                .build()); //adding a divider into the recyclerview list


        Log.d(TAG, "onCreateView: started");
        initImageBitmaps(view);

        return view;
    }

    private void initImageBitmaps(View view){
        Log.d(TAG, "initImageBitmaps: preparing bitmaps");

        mIcon.add(R.drawable.ic_product);
        mLabel.add("Products");

        mIcon.add(R.drawable.ic_customer);
        mLabel.add("Services");

        mIcon.add(R.drawable.ic_category);
        mLabel.add("Categories");

        mIcon.add(R.drawable.ic_tag);
        mLabel.add("Discounts");

        initRecyclerView(view);

    }

    private void initRecyclerView(View view){
//        Log.d(TAG, "initRecyclerView: init recyclerview");
        RecyclerView recyclerView = view.findViewById(R.id.inventorylist_recycleview);
        InventoryRecyclerViewAdapter adapter = new InventoryRecyclerViewAdapter(getActivity(), mIcon, mLabel);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
    }

推荐阅读