Fragment的按钮正在崩溃应用程序

时间:2017-11-13 16:38:07

标签: java android android-fragments button nullpointerexception

我将一个Button放在片段中,并带有相应的监听器。每次我调用此活动时,应用程序都会崩溃。 Logcat显示空指针异常。下面的代码是Fragment类的片段。

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_carprofile_list, container, false);

    // Set the adapter
    if (view instanceof RecyclerView) {
        Context context = view.getContext();
        RecyclerView recyclerView = (RecyclerView) view;
        if (mColumnCount <= 1) {
            recyclerView.setLayoutManager(new LinearLayoutManager(context));
        } else {
            recyclerView.setLayoutManager(new GridLayoutManager(context, mColumnCount));
        }
        recyclerView.setAdapter(new MyCarProfileRecyclerViewAdapter(carProfileContent.ITEMS, mListener));
    }

    Button imgbtn = (Button) view.findViewById(R.id.editCarProfileButton);
    imgbtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            startActivity(new Intent(getActivity(),ReserveActivity.class));
        }
    });

    return view;
}

Logcat显示:

FATAL EXCEPTION: main
Process: com.example.app, PID: 13571
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.app/com.example.app.CarProfileListActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2377)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2429)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1342)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5333)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:828)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:644)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.mikepuno.parkeazy.CarProfileFragment.onCreateView(CarProfileFragment.java:78)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2354)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1419)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1740)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1809)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:799)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2580)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2367)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2322)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2229)
at android.support.v4.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3221)
at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3171)
at android.support.v4.app.FragmentController.dispatchActivityCreated(FragmentController.java:192)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:560)
at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:177)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1174)
at android.app.Activity.performStart(Activity.java:5353)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2340)

我一直在看这里的多个类似问题,但它似乎对我不起作用。我是否错过了添加Button和听众的方式?

fragment_carprofile_list.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/list"
    android:name="com.mikepuno.parkeazy.CarProfileFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginLeft="16dp"
    android:layout_marginRight="16dp"
    app:layoutManager="LinearLayoutManager"
    tools:context="com.mikepuno.parkeazy.CarProfileFragment"
    tools:listitem="@layout/fragment_carprofile" />

fragment_carprofile.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/plateNumberTextView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:textAppearance="?attr/textAppearanceListItem" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/brandTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:textAppearance="?attr/textAppearanceListItem" />

        <TextView
            android:id="@+id/modelTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:textAppearance="?attr/textAppearanceListItem" />

        <TextView
            android:id="@+id/colorTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:textAppearance="?attr/textAppearanceListItem" />

        <Button
            android:id="@+id/editCarProfileButton"
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:text="Edit" />

    </LinearLayout>
</LinearLayout>

适配器类

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

    private final List<CarProfile> mValues;
    private final OnListFragmentInteractionListener mListener;

    public MyCarProfileRecyclerViewAdapter(List<CarProfile> items, OnListFragmentInteractionListener listener) {
        mValues = items;
        mListener = listener;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.fragment_carprofile, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
        holder.mItem = mValues.get(position);
        holder.mPlateNumberTextView.setText(mValues.get(position).getPlateNumber());
        holder.mBrandTextView.setText(mValues.get(position).getBrand());
        holder.mModelTextView.setText(mValues.get(position).getModel());
        holder.mColorTextView.setText(mValues.get(position).getColor());

        holder.mView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (null != mListener) {
                    // Notify the active callbacks interface (the activity, if the
                    // fragment is attached to one) that an item has been selected.
                    mListener.onListFragmentInteraction(holder.mItem);
                }
            }
        });
    }

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

    public class ViewHolder extends RecyclerView.ViewHolder {
        public final View mView;
        public final TextView mPlateNumberTextView;
        public final TextView mBrandTextView;
        public final TextView mModelTextView;
        public final TextView mColorTextView;
        public CarProfile mItem;

        public ViewHolder(View view) {
            super(view);
            mView = view;
            mPlateNumberTextView = (TextView) view.findViewById(R.id.plateNumberTextView);
            mBrandTextView = (TextView) view.findViewById(R.id.brandTextView);
            mModelTextView = (TextView) view.findViewById(R.id.modelTextView);
            mColorTextView = (TextView) view.findViewById(R.id.colorTextView);
        }

        @Override
        public String toString() {
            return super.toString() + " '" + mPlateNumberTextView.getText() + "'";
        }
    }
}

2 个答案:

答案 0 :(得分:1)

夸大视图后

View view = inflater.inflate(R.layout.fragment_carprofile_list, container, false);

您认为该视图是RecyclerView。这意味着根元素是recyclerview。

然后尝试通过

在该回收者视图中找到一个按钮
Button imgbtn = (Button) view.findViewById(R.id.editCarProfileButton);

返回null ofcourse。然后尝试在null对象上设置单击侦听器。

看起来你的xml文件有误。如果您的每一行都有您要查找的按钮,则需要在适配器类中捕获它,然后通知片段执行您的过程。

解决方案(编辑):

从Fragment中的onCreateView中删除这些行。

Button imgbtn = (Button) view.findViewById(R.id.editCarProfileButton);
    imgbtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            startActivity(new Intent(getActivity(),ReserveActivity.class));
        }
    });

您已经有一个通知片段的接口。 因此我们将使用它进行编辑。

所以最终的适配器类应该像

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

private final List<CarProfile> mValues;
private final OnListFragmentInteractionListener mListener;

public MyCarProfileRecyclerViewAdapter(List<CarProfile> items, OnListFragmentInteractionListener listener) {
    mValues = items;
    mListener = listener;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.fragment_carprofile, parent, false);
    return new ViewHolder(view);
}

@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
    holder.mItem = mValues.get(position);
    holder.mPlateNumberTextView.setText(mValues.get(position).getPlateNumber());
    holder.mBrandTextView.setText(mValues.get(position).getBrand());
    holder.mModelTextView.setText(mValues.get(position).getModel());
    holder.mColorTextView.setText(mValues.get(position).getColor());
}

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

public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

    public final TextView mPlateNumberTextView;
    public final TextView mBrandTextView;
    public final TextView mModelTextView;
    public final TextView mColorTextView;
    public CarProfile mItem;

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

        view.setClickable(true); // This is important
        view.setOnClickListener(this);

        mPlateNumberTextView = (TextView) view.findViewById(R.id.plateNumberTextView);
        mBrandTextView = (TextView) view.findViewById(R.id.brandTextView);
        mModelTextView = (TextView) view.findViewById(R.id.modelTextView);
        mColorTextView = (TextView) view.findViewById(R.id.colorTextView);
    }

    public void onClick(View view) {
       if (null != mListener) {
            mListener.onListFragmentInteraction(mValues.get(getAdapterPosition()));
       }
    }

    @Override
    public String toString() {
        return super.toString() + " '" + mPlateNumberTextView.getText() + "'";
    }
   }

然后你的片段

    @Override
    public void onListFragmentInteraction(CarProfile profile) {
        // TODO Pass your profile to ReserverActivity by using bundles.
        startActivity(new Intent(getActivity(), ReserveActivity.class));
    }

您可以通过点击按钮上的通知片段来改进代码。所以你的按钮点击监听器和通知代码也必须在这里。

答案 1 :(得分:1)

View view = inflater.inflate(R.layout.fragment_carprofile_list, container, false);

You are inflating fragment_carprofile_list.xml, which contains the RecyclerView. There is no mention of Button in that XML, which is why you are getting a NullPointerException