如何修复调用 getParent() 方法时“尝试在空对象引用上调用虚拟方法”

How to fix 'Attempt to invoke virtual method on a null object reference' when calling getParent() method

提问人:Grygol 提问时间:9/6/2019 更新时间:9/6/2019 访问量:1559

问:

我在LinearLayout中有按钮,它是RecyclerView中单元格的一部分。我想将其更改为另一个按钮,因此我通过调用 button.getParent() 方法使用一些需要按钮父视图的方法。不幸的是,它以“尝试在空对象引用上调用虚拟方法'android.view.ViewParent android.view.View.getParent()'错误结尾。我觉得我想念看什么,但我无法抓住它可能是什么。我将不胜感激您的帮助。

在下面的代码示例中,我包含了在我看来对解决我的问题至关重要的代码。当然,如果需要,我可以提供更多。

layout_cell.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/relativeLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/white"
    android:padding="2dp">

    <RelativeLayout
        android:id="@+id/subItem"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/descript"
        android:layout_marginTop="16dp"
        android:orientation="vertical">

        <LinearLayout
            android:id="@+id/buttonsLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/fileNameTextViewInCell"
            android:layout_marginHorizontal="8dp"
            >

            <Button
                android:id="@+id/downloadButtonInCell"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginLeft="8dp"
                android:layout_weight="1"
                app:icon="@drawable/ic_download"
                app:iconPadding="8dp" />

        </LinearLayout>


    </RelativeLayout>




</RelativeLayout>

CellAdapter.java:

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

      @Override
        public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
            View view = LayoutInflater
                    .from(viewGroup.getContext())
                    .inflate(R.layout.layout_cell, viewGroup, false);
            mViewHolder = new ViewHolder(view);
            return mViewHolder;
        }

    viewHolder.mDownloadButton.setOnClickListener(new View.OnClickListener() {
               @Override
               public void onClick(View view) {

                        ViewGroupUtils.replaceView(view, mViewHolder.mLoadingButton);

                        view.setEnabled(false);

               }
           });

public class ViewHolder extends RecyclerView.ViewHolder {

            RelativeLayout mRelativeLayout;
            Button mDownloadButton;
            Button mLoadingButton;
            LinearLayout mButtonsLayout;

        public ViewHolder(View itemView) {
            super(itemView);

            mRelativeLayout = itemView.findViewById(R.id.relativeLayout);
            mDownloadButton = (Button) itemView.findViewById(R.id.downloadButtonInCell);
            mLoadingButton = itemView.findViewById(R.id.loadingView);
            mButtonsLayout = itemView.findViewById(R.id.buttonsLayout);

        }
    }



}

ViewGroupUtils.java:

 public class ViewGroupUtils {

    public static ViewGroup getParent(View view) {
            return (ViewGroup) view.getParent();
    }

    public static void removeView(View view) {
        ViewGroup parent = getParent(view);
        if(parent != null) {
            parent.removeView(view);
        }
    }

    public static void replaceView(View currentView, View newView) {
        ViewGroup parent = getParent(currentView);
        if(parent == null) {
            return;
        }
        final int index = parent.indexOfChild(currentView);
        removeView(currentView);
        removeView(newView);
        parent.addView(newView, index);
    }
    }
java android xml android 布局 nullpointerexception

评论


答:

0赞 Saravinfotech 9/6/2019 #1

我知道您正在动态尝试从 recyclerview 行中删除现有按钮并将其替换为新视图,只是一个建议,您可以尝试此选项吗?

现有视图是否处于可见状态,新视图处于隐藏/消失状态,并且基于逻辑只是翻转现有视图和新视图的可见性?

所以首先默认 --> 现有视图 -- >状态 VISIBLE
新视图 -- 根据您的要求>状态 HIDDEN/GONE

所以根据你的条件

现有视图 -->状态 HIDDEN/GONE 新视图 -->状态 VISIBLE

这可能更容易,您可能不必为回收器视图而苦苦挣扎,因为下一个挑战是获取特定行的动态 ID。