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
Related
I want to create tags using RecyclerView that can be selected to produce results.
What I want to achieve is when I tap on Books TextView on the top-right must change to Books immediately. In my case when I tap on Books it just stays in Art and it replaces Art with Books only when I replace my fragments. I also highlight buttons when clicked (changing border from grey to black) but after changing fragments highlights return back to Art again. Shortly I want to highlight button when clicked and change TextView content based on clicked button text. I partly achieved it by using interfacews but didn't get what I wanted. I provided codes below:
TrendCategoryTagsAdapter.java:
public class TrendCategoryTagsAdapter extends FirestoreRecyclerAdapter<CategorySelection, TrendCategoryTagsAdapter.TrendCategoryTagsHolder> {
Context context;
onCategoryTagClicked onCategoryTagClicked;
int row_index;
public TrendCategoryTagsAdapter(#NonNull FirestoreRecyclerOptions<CategorySelection> options, Context context, com.rajabmammadli.paragrafredesign.Interface.onCategoryTagClicked onCategoryTagClicked) {
super(options);
this.context = context;
this.onCategoryTagClicked = onCategoryTagClicked;
}
#Override
protected void onBindViewHolder(#NonNull final TrendCategoryTagsHolder holder, final int position, #NonNull CategorySelection model) {
holder.categoryNameText.setText(model.getCategoryName());
holder.categoryNameContainer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
row_index = position;
notifyDataSetChanged();
}
});
if (row_index == position) {
holder.categoryNameContainer.setBackground(ContextCompat.getDrawable(context, R.drawable.black_rounded_bg));
onCategoryTagClicked.onTagClick(holder.categoryNameText.getText().toString());
} else {
holder.categoryNameContainer.setBackground(ContextCompat.getDrawable(context, R.drawable.grey_rounded_bg));
}
}
#NonNull
#Override
public TrendCategoryTagsHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(context).inflate(R.layout.trendcategory_cell, parent, false);
return new TrendCategoryTagsAdapter.TrendCategoryTagsHolder(v);
}
public static class TrendCategoryTagsHolder extends RecyclerView.ViewHolder {
RelativeLayout categoryNameContainer;
TextView categoryNameText;
public TrendCategoryTagsHolder(#NonNull View itemView) {
super(itemView);
categoryNameContainer = itemView.findViewById(R.id.categoryNameContainer);
categoryNameText = itemView.findViewById(R.id.categoryNameText);
}
}
}
trendcategory_cell.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp">
<RelativeLayout
android:id="#+id/categoryNameContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/grey_rounded_bg">
<TextView
android:id="#+id/categoryNameText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="#font/gilroyregular"
android:padding="15dp"
android:text="categoryname"
android:textColor="#android:color/black" />
</RelativeLayout>
</RelativeLayout>
TrendingFragment.java:
public class TrendingFragment extends Fragment implements onCategoryTagClicked {
RecyclerView trendingCategoryRV;
TextView noPostTV, selectedCategoryText;
FirebaseFirestore db = FirebaseFirestore.getInstance();
CollectionReference categoryRef;
String selectedCategory = "Art";
TrendCategoryTagsAdapter trendCategoryTagsAdapter;
public TrendingFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_trending, container, false);
trendPostRV = view.findViewById(R.id.trendPostRV);
trendingCategoryRV = view.findViewById(R.id.trendingCategoryRV);
noPostTV = view.findViewById(R.id.noPostTV);
selectedCategoryText = view.findViewById(R.id.selectedCategoryText);
selectedCategoryText.setText(selectedCategory);
setUpTrendCategoryTagsRV();
setUpTrendingPostRV();
// Inflate the layout for this fragment
return view;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
trendCategoryTagsAdapter.startListening();
}
#Override
public void onDestroyView() {
super.onDestroyView();
trendCategoryTagsAdapter.stopListening();
}
private void setUpTrendCategoryTagsRV() {
categoryRef = db.collection("Categories");
Query query = categoryRef.orderBy("categoryName", Query.Direction.ASCENDING);
FirestoreRecyclerOptions<CategorySelection> options = new FirestoreRecyclerOptions.Builder<CategorySelection>()
.setQuery(query, CategorySelection.class)
.build();
trendCategoryTagsAdapter = new TrendCategoryTagsAdapter(options, getContext(), this);
trendingCategoryRV.setNestedScrollingEnabled(false);
final LinearLayoutManager trendingTagsLM = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false);
trendingCategoryRV.setLayoutManager(trendingTagsLM);
trendingCategoryRV.setAdapter(trendCategoryTagsAdapter);
trendCategoryTagsAdapter.notifyDataSetChanged();
}
#Override
public void onTagClick(String categoryName) {
selectedCategory = categoryName;
}
}
Any help will be appreciated. Thanks in advance
While trying to inflate a FragmentDialog containing a RecyclerView, I'm having this "The specified child already has a parent. You must call removeView() on the child's parent first." error.
Here's the code from my DialogFragment:
public class MyDialogFragment extends AppCompatDialogFragment {
private static final String DATA = "data";
private MyDialogFragment.MyDialogFragmentListener listener;
private ArrayList<MyArrayList> mArrayListData;
public static MyDialogFragment newInstance(ArrayList<MyArrayList> ArrayListData) {
Bundle args = new Bundle();
MyDialogFragment fragment = new MyDialogFragment();
args.putParcelableArrayList(DATA, ArrayListData);
fragment.setArguments(args);
return fragment;
}
#NonNull
#Override
public Dialog onCreateDialog(#Nullable Bundle savedInstanceState) {
if (getArguments() != null) {
mArrayListData = getArguments().getParcelableArrayList(DATA);
}
AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity());
builder.setView(createRecyclerView(mArrayListData))
.setTitle(requireContext().getString(R.string.title))
.setPositiveButton(requireContext().getString(R.string.ok_button), null);
Dialog dialog = builder.create();
/* Option set cause key board doesn't appear */
dialog.show();
Objects.requireNonNull(dialog.getWindow()).clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
dialog.setCanceledOnTouchOutside(false);
return dialog;
}
#Override
public void onResume() {
super.onResume();
final AlertDialog MyAlertDialog = (AlertDialog) getDialog();
if (MyAlertDialog != null) {
Button positiveButton = MyAlertDialog.getButton(Dialog.BUTTON_POSITIVE);
positiveButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
...
dismiss();
}
});
}
}
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
try {
listener = (MyDialogFragment.MyDialogFragmentListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString() +
"must implement ExampleDialogListener");
}
}
public interface MyDialogFragmentListener {
void MyDialogFragmentListenerReturn(ArrayList<MyArrayList> ArrayListData);
}
private RecyclerView createRecyclerView(final ArrayList<MyArrayList> ArrayListData){
LayoutInflater inflater = requireActivity().getLayoutInflater();
View view = inflater.inflate(R.layout.fragmentLayout, null, false);
RecyclerView MyRecyclerView = view.findViewById(R.id.recyclerViewId);
MyRecyclerAdapter myAdapter = new MyRecyclerAdapter (getActivity(), ArrayListData);
MyRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
MyRecyclerView.setAdapter(myAdapter);
myAdapter.setOnItemClickListener(new MyRecyclerAdapter.OnItemClickListener() {
#Override
public void onReturnValue(int position, int value) {
mArrayListData.get(position).setValue(value);
}
});
return MyRecyclerView;
}
}
My recycler adapter:
public class MyRecyclerAdapter extends RecyclerView.Adapter<MyRecyclerAdapter.InsideRecyclerHolder> {
private final Context mContext;
private ArrayList<MyArrayList> mArrayListData;
private MyRecyclerAdapter.OnItemClickListener mListener;
MyRecyclerAdapter(Context context, ArrayList<MyArrayList> ArrayListData) {
mContext = context;
mArrayListData = RecyclerCarUpdateList;
}
#NonNull
#Override
public MyRecyclerAdapter.InsideRecyclerHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater myInflater = LayoutInflater.from(mContext);
View myOwnView = myInflater.inflate(R.layout.layout_recycler, parent, false);
return new MyRecyclerAdapter.InsideRecyclerHolder(myOwnView, mListener);
}
#Override
public void onBindViewHolder(#NonNull MyRecyclerAdapter.InsideRecyclerHolder holder, int position) {
MyArrayList currentItem = mArrayListData.get(position);
holder.t1.setText(currentItem.getFirstValue());
holder.e1.setHint(currentItem.getSecondValue());
}
#Override
public int getItemCount() {
return mArrayListData.size();
}
public interface OnItemClickListener {
void onReturnValue(int position, int newValue);
}
public void setOnItemClickListener(MyRecyclerAdapter.OnItemClickListener listener) {
mListener = listener;
}
static class InsideRecyclerHolder extends RecyclerView.ViewHolder {
final TextView t1;
final EditText e1;
InsideRecyclerHolder(#NonNull View itemView, final OnItemClickListener mListener) {
super(itemView);
t1 = itemView.findViewById(R.id.textValue);
e1 = itemView.findViewById(R.id.editTextValue);
e1.setImeOptions(EditorInfo.IME_ACTION_DONE);
e1.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (mListener != null) {
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
if (!e1.getText().toString().isEmpty()) {
listener.onReturnValue(position, Integer.parseInt(e1.getText().toString()))
}
}
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
}
}
And here's the stack:
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
at android.view.ViewGroup.addViewInner(ViewGroup.java:4915)
at android.view.ViewGroup.addView(ViewGroup.java:4746)
at android.view.ViewGroup.addView(ViewGroup.java:4718)
at androidx.appcompat.app.AlertController.setupCustomContent(AlertController.java:657)
at androidx.appcompat.app.AlertController.setupView(AlertController.java:475)
at androidx.appcompat.app.AlertController.installContent(AlertController.java:233)
at androidx.appcompat.app.AlertDialog.onCreate(AlertDialog.java:279)
at android.app.Dialog.dispatchOnCreate(Dialog.java:403)
at android.app.Dialog.show(Dialog.java:302)
at com.myself.myapp.MyDialogFragment.onCreateDialog(MyDialogFragment.java:61)
at androidx.fragment.app.DialogFragment.onGetLayoutInflater(DialogFragment.java:419)
at androidx.fragment.app.Fragment.performGetLayoutInflater(Fragment.java:1484)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:320)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1187)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356)
at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1434)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1497)
at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:447)
at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2169)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1992)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1947)
at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1849)
at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:169)
at android.app.ActivityThread.main(ActivityThread.java:6578)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
It points the issue to the "dialog.show();" of my DialogFragment. I have to admit that I'm quite lost whit is. I have another DialogFragment that works the same way with no issue.
I solved my issue, I originaly thought it came from my java code but it was an xml layout issue ...
My DialogFrament layout was like that:
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#FF8200"
android:orientation="vertical"
android:padding="16dp"
tools:context=".MyDialogFragment ">
<TextView
android:id="#+id/textViewId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:textSize="16sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerViewId"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textViewId" />
</androidx.constraintlayout.widget.ConstraintLayout>
and I just needed to use the RecyclerView as a sole element of the layout:
<androidx.recyclerview.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/recyclerViewId"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:backgroundTint="#FF8200"
android:nestedScrollingEnabled="false"
android:padding="16dp"
tools:context=".MyDialogFragment "
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
I want to wrap my recycler view inside a coordinator layout but the problem is whenever i do that the items stop showing up. For items i use autogenerated dummy text from android studio. And if i only use a recylcer view without coordinatorlayout all the items show up perfectly.
Thanks for your help in advance.
p.s im kinda new to asking questions on stackoverflow so i apologize for any formatting issues
fragment.java
public class TodoFragment extends Fragment {
private static final String ARG_COLUMN_COUNT = "column-count";
private OnListFragmentInteractionListener mListener;
public TodoFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_todo_list, container, false);
final FloatingActionButton floatingActionButton = view.findViewById(R.id.fab);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
if (view instanceof RecyclerView) {
Context context = view.getContext();
RecyclerView recyclerView = (RecyclerView) view;
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.addItemDecoration(new DividerItemDecoration(getContext(), LinearLayoutManager.VERTICAL));
recyclerView.setAdapter(new ToDoRecyclerViewAdapter(DummyContent.ITEMS, mListener));
}
return view;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnListFragmentInteractionListener) {
mListener = (OnListFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnListFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnListFragmentInteractionListener {
void onListFragmentInteraction(DummyItem item);
}
}
layout.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
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/coordlayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/list"
android:name="com.example.kayc.projectplanner.aktivnostiFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
app:layoutManager="com.example.kayc.projectplanner.FloatButtonBehavior.RVlayoutmanager"
tools:context=".fragmenti.TodoFragment"
tools:listitem="#layout/fragment_todo" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="#dimen/fab_margin"
app:srcCompat="#android:drawable/ic_menu_add" />
</android.support.design.widget.CoordinatorLayout>
Adapter.java
public class ToDoRecyclerViewAdapter extends RecyclerView.Adapter<ToDoRecyclerViewAdapter.ViewHolder> {
private final List<DummyItem> mValues;
private final OnListFragmentInteractionListener mListener;
public ToDoRecyclerViewAdapter(List<DummyItem> 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_todo, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.mItem = mValues.get(position);
holder.mIdView.setText(mValues.get(position).id);
holder.mContentView.setText(mValues.get(position).content);
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (null != mListener) {
mListener.onListFragmentInteraction(holder.mItem);
}
}
});
}
#Override
public int getItemCount() {
return mValues.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public final View mView;
public final TextView mIdView;
public final TextView mContentView;
public DummyItem mItem;
public ViewHolder(View view) {
super(view);
mView = view;
mIdView = (TextView) view.findViewById(R.id.item_number);
mContentView = (TextView) view.findViewById(R.id.content);
}
#Override
public String toString() {
return super.toString() + " '" + mContentView.getText() + "'";
}
}
}
The problem is in your onCreateView. it should be like this:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_todo_list, container, false);
final FloatingActionButton floatingActionButton = view.findViewById(R.id.fab);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.list);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.addItemDecoration(new DividerItemDecoration(getContext(), LinearLayoutManager.VERTICAL));
recyclerView.setAdapter(new ToDoRecyclerViewAdapter(DummyContent.ITEMS, mListener));
return view;
}
if (view instanceof RecyclerView) will always return false because view is a ConstraintLayout instance.
if (view instanceof RecyclerView) never execute. cause view's root is
CoordinatorLayout not RecyclerView. So just remove the if(view instanceof RecyclerView).
<android.support.design.widget.CoordinatorLayout
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/coordlayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/list"
android:name="com.example.kayc.projectplanner.aktivnostiFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
tools:context=".fragmenti.TodoFragment"
tools:listitem="#layout/fragment_todo" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="#dimen/fab_margin"
app:srcCompat="#android:drawable/ic_menu_add" />
</android.support.design.widget.CoordinatorLayout>
And onCreateView().
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_todo_list, container, false);
final FloatingActionButton floatingActionButton = view.findViewById(R.id.fab);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
RecyclerView recyclerView = view.findViewById(R.id.list);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), LinearLayoutManager.VERTICAL));
recyclerView.setAdapter(new ToDoRecyclerViewAdapter(DummyContent.ITEMS, mListener));
return view;
}
Also look for onActivityCreated() cause getActivity() can return null in onCreateView().
In this fragment,
public class BlankFragment extends Fragment {
public BlankFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View rootView = inflater.inflate(R.layout.fragment_blank, container, false);
RecyclerView rv = rootView.findViewById(R.id.rv_recycler_view);
rv.setNestedScrollingEnabled(false);
SimpleDateFormat localDateFormat = new SimpleDateFormat("HH:mm");
SunTimes suntime = SunTimes.compute().at(latlang.Lat,latlang.Lang).today().execute();
String sun_rise = localDateFormat.format(suntime.getRise());
String sun_set = localDateFormat.format(suntime.getSet());
Date sunnoon = suntime.getNoon();
System.out.println("SUNRISE "+ sun_rise);
TextView cityField = rootView.findViewById(R.id.tv_city);
TextView sunrise = rootView.findViewById(R.id.tv_sunrt);
TextView sunset = rootView.findViewById(R.id.tv_sunst);
cityField.setText("Hello World"); //Line 45
sunrise.setText(sun_rise);
sunset.setText(sun_set);
return rootView;
}
I am getting error:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at com.example.phocast.BlankFragment.onCreateView(BlankFragment.java:45)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2354)
The question is while I have a normal string as a text, how it can get null point exception?
What am I doing wrong?
Update
the fragment_blank does not have the id, as its just an inflater:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swiperefresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
That id is in item_blank.xml as:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="120sp" >
<android.support.v7.widget.CardView
android:id="#+id/card_view"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_margin="10dp"
android:layout_height="120sp"
card_view:cardCornerRadius="4dp"
card_view:elevation="14dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/iv_image"
android:layout_width="120sp"
android:layout_height="fill_parent"
android:scaleType="fitStart"
card_view:srcCompat="#drawable/property_image_3">
</ImageView>
<TextView
android:id="#+id/tv_city"
android:layout_width="wrap_content"
android:layout_height="30sp"
android:layout_marginBottom="1sp"
android:layout_toRightOf="#+id/iv_image"
android:gravity="top"
android:paddingLeft="5sp"
android:text="Hello World"
android:textAppearance="#style/TextAppearance.AppCompat.Large">
</TextView>
.....
and which is defined in the Adapter:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private String[] mDataset;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class MyViewHolder extends RecyclerView.ViewHolder {
public CardView mCardView;
public TextView mTextView;
public MyViewHolder(View v) {
super(v);
mCardView = (CardView) v.findViewById(R.id.card_view);
mTextView = (TextView) v.findViewById(R.id.tv_city);
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(String[] myDataset) {
mDataset = myDataset;
}
// Create new views (invoked by the layout manager)
#Override
public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.card_item, parent, false);
// set the view's size, margins, paddings and layout parameters
MyViewHolder vh = new MyViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
holder.mTextView.setText(mDataset[position]);
holder.mCardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String currentValue = mDataset[position];
Log.d("CardView", "CardView Clicked: " + currentValue);
}
});
}
#Override
public int getItemCount() {
return mDataset.length;
}
}
So I am expecting the cardview to be read from the adapter, as it is working for this case:
public class BlankFragment extends Fragment {
public BlankFragment() {
// Required empty public constructor
}
//
// #Override
// public void onCreate(Bundle savedInstanceState) {
// super.onCreate(savedInstanceState);
//
// }
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View rootView = inflater.inflate(R.layout.fragment_blank, container, false);
RecyclerView rv = rootView.findViewById(R.id.rv_recycler_view);
rv.setNestedScrollingEnabled(false);
Weather_OWM.placeIdTask asyncTask = new Weather_OWM.placeIdTask(new Weather_OWM.AsyncResponse() {
public void processFinish(String weather_city, String weather_description, String weather_temperature, String weather_humidity, String weather_pressure, String weather_updatedOn, String weather_iconText, String sun_rise, String sun_set) {
TextView cityField = rootView.findViewById(R.id.tv_city);
TextView sunrise = rootView.findViewById(R.id.tv_sunrt);
TextView sunset = rootView.findViewById(R.id.tv_sunst);
cityField.setText(weather_city);
sunrise.setText(sun_rise);
sunset.setText(sun_set);
}
});
asyncTask.execute(Double.toString(latlang.Lat), Double.toString(latlang.Lang)); // asyncTask.execute("Latitude", "Longitude")
rv.setHasFixedSize(true);
MyAdapter adapter = new MyAdapter(new String[]{"Today", "Golden Hour", "Blue Hour", "Civil Twilight", "Nautical Twilight", "Astronomical Twilight", "Hello", "World"});
rv.setAdapter(adapter);
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
rv.setLayoutManager(llm);
return rootView;
}
}
It's not about the string argument but the cityField TextView you're calling setText() on. You're initialising it with
rootView.findViewById(R.id.tv_city);
which returns null if the view is not found. So your fragment_blank layout does not have a view with id tv_city.
I am building a sudoku in android ,so how do i register all the textviews
for e.g :
button1=(Button)findViewByid(R.id.btn1)
Do i need to write 81 such statements to register every TextView
you can add the views in java code when app running.
you can write your textview's xml statement in an xml file alone, and then inflate it.
In this way, you don't need the view id, because you already have its reference.
grid.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
...
/>
MyActivity.java
ArrayList<TextView> list = new ArrayList<>();
for (int i = 0; i < 81; i++) {
TextView view = (TextView)LayoutInflater.from(ItemDragAndSwipeUseActivity.this).inflate(R.layout.grid, null);
list.add(view);
}
// then attach these views to the layout with addView()
you can use grid view with an adapter instead of text views
grid item
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="13sp"
android:text="#string/country_name"
android:textColor="#color/accent_color"
android:gravity="center"
android:paddingBottom="8dp"
android:paddingTop="8dp"
android:background="#color/color_primary_dark"/>
</RelativeLayout>
Adapter class
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewHolders> {
private List<ItemObject> itemList;
private Context context;
public RecyclerViewAdapter(Context context, List<ItemObject> itemList) {
this.itemList = itemList;
this.context = context;
}
#Override
public RecyclerViewHolders onCreateViewHolder(ViewGroup parent, int viewType) {
View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, null);
RecyclerViewHolders rcv = new RecyclerViewHolders(layoutView);
return rcv;
}
#Override
public void onBindViewHolder(RecyclerViewHolders holder, int position) {
holder.textView.setText(itemList.get(position).getName());
}
#Override
public int getItemCount() {
return this.itemList.size();
}
public class RecyclerViewHolders extends RecyclerView.ViewHolder implements View.OnClickListener{
public TextView textView;
public RecyclerViewHolders(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
textView = (TextView)itemView.findViewById(R.id.textView);
}
#Override
public void onClick(View view) {
Toast.makeText(view.getContext(), "Clicked Position = " + getPosition(), Toast.LENGTH_SHORT).show();
}
}
}
Activity class
public class MainActivity extends ActionBarActivity {
private GridLayoutManager lLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setTitle(null);
Toolbar topToolBar = (Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(topToolBar);
topToolBar.setLogo(R.drawable.logo);
topToolBar.setLogoDescription(getResources().getString(R.string.logo_desc));
List<ItemObject> rowListItem = getAllItemList();
lLayout = new GridLayoutManager(MainActivity.this, 4);
RecyclerView rView = (RecyclerView)findViewById(R.id.recycler_view);
rView.setHasFixedSize(true);
rView.setLayoutManager(lLayout);
RecyclerViewAdapter rcAdapter = new RecyclerViewAdapter(MainActivity.this, rowListItem);
rView.setAdapter(rcAdapter);
}
private List<ItemObject> getAllItemList(){
List<ItemObject> allItems = new ArrayList<ItemObject>();
allItems.add(new ItemObject("1");
allItems.add(new ItemObject("2");
allItems.add(new ItemObject("3");
return allItems;
}
}
You don't have to use IDs for this. You can just create a View (Container) in XML and fill it using a for loop completely without using IDs. You can access them afterwards via their index in the Container.
I hope this helped.