I put a Button in fragment with the corresponding listener. Every time I call on this activity the app crashes. Logcat show a null pointer exception. The code below is a snippet from the Fragment class.
@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 shows:
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)
I've been looking at multiple similar issues here but it just don't seem to work for me. Am I missing anything from the way I added the Button and the listener?
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>
Adapter 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());
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() + "'";
}
}
}
After you inflate your view
View view = inflater.inflate(R.layout.fragment_carprofile_list, container, false);
you assume that view is RecyclerView. That means root element is recyclerview.
Then trying to find a button inside of that recyclerview by doing
Button imgbtn = (Button) view.findViewById(R.id.editCarProfileButton);
which returns null ofcourse. Then trying to set a click listener on null object.
Looks like your xml file is wrong. If your each row has button that you are trying to find, you need to catch it in your adapter class then notify fragment to do your process.
SOLUTION (EDIT):
Remove these lines from onCreateView
in Fragment.
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));
}
});
You have already a interface that notify the fragment. So that we are going to use it for editing.
So the final adapter class should be like
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() + "'";
}
}
Then your fragment
@Override
public void onListFragmentInteraction(CarProfile profile) {
// TODO Pass your profile to ReserverActivity by using bundles.
startActivity(new Intent(getActivity(), ReserveActivity.class));
}
You can improve the code by notify fragment on your button click. So your button click listener and notify code must also be in here.
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.