Null pointer exception in imageview when using callback between two fragments? - android

i have two fragments, i want use callback using interface to change imageview
in first fragment from the second fragment but when callback is fired its get imageview null and i get the below error
java.lang.NullPointerException: Attempt to invoke virtual method 'void
android.widget.ImageView.setImageResource(int)' on a null object
reference
first fragment:
public class firstfragment extends Fragment implements MyProfileCallback
{
Imageview myprofile_image;
public firstfragment()
{
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View rootview = inflater.inflate(R.layout.fisrt, container, false);
myprofile_image=(ImageView) rootview.(find.id.myprofile_image);
/
...
/
}
#Override
public void callbackCall()
{
myprofile_image.setImageResource(R.drawable.profile_friends);
}
}
second fragment:
public class secondfragment extends Fragment
{
MyProfileCallback mcallback;
public secondfragment()
{
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View rootview = inflater.inflate(R.layout.second, container, false);
mcallback.callbackCall();
return rootview;
}
interface
public interface MyProfileCallback
{
void callbackCall();
}

Your question is kind of hard to understand so is your code, BUT, I think you should load the resource file in this case R.drawable.profile_friends
when the fragment view has being created
You can:
EDIT:
You are calling your callback from the onCreateView method meaning your mypfile_image view does not have a reference to your element yet
and you get a null pointer exception
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mcallback.callbackCall();
}

Related

ClickListener in cardview return null exception

I have some problem when I try to click a cardview, I want it to make toast with its ID. But whenever I click the cardview, it always crashed and get null exception on its listener. already declare the listener but still crashed. Thank You
Listener class
public interface ResetPasswordListener {
void onClickCardview(String userid);
}
Adapter Class
public class ResetPasswordAdapter extends RecyclerView.Adapter<ResetPasswordAdapter.ViewHolder> implements ResetPasswordListener {
private List<ResetPasswordRespModel> resetList = new ArrayList<>();
private ResetPasswordListener resetPasswordListener;
public void setOnClick(ResetPasswordListener listener) {
this.resetPasswordListener = listener;
}
#Override
public void onClickCardview(String userid) {
Log.d("ID VALUE", userid);
resetPasswordListener.onClickCardview(userid);
}
}
This is how I set the listener in fragment class
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
listResetPasswordBinding = DataBindingUtil.inflate(inflater, R.layout.list_reset_password, container, false);
return inflater.inflate(R.layout.fragment_reset_password, container, false);
}
#Override
public void onViewCreated(#NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
listResetPasswordBinding.setOnClick(new ResetPasswordListener() {
#Override
public void onClickCardview(String userid) {
Toast.makeText(getActivity(), userid, Toast.LENGTH_SHORT).show();
}
});
}
Error Logs
java.lang.NullPointerException: Attempt to invoke interface method 'void example.com.absensiapp.view.listener.ResetPasswordListener.onClickCardview(java.lang.String)' on a null object reference
at example.com.absensiapp.view.adapter.ResetPasswordAdapter.onClickCardview(ResetPasswordAdapter.java:35)
at example.com.absensiapp.databinding.ListResetPasswordBindingImpl._internalCallbackOnClick(ListResetPasswordBindingImpl.java:227)
at example.com.absensiapp.generated.callback.OnClickListener.onClick(OnClickListener.java:11)
The problem seems to be onCreateView you are inflating the layout twice one with DataBindingUtil.inflate adn once with inflater.inflate. Modify it
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
listResetPasswordBinding = DataBindingUtil.inflate(inflater, R.layout.list_reset_password, container, false);
return listResetPasswordBinding.getroot();
}
Also call setOnClick of ResetPasswordAdapter to set listener. Until you set the listener you will keep getting a null pointer.

Fragment Interactions

I am trying to add a fragment to an existing layout from within the onClick method of a button in another Fragment class..
In my MainActivity I add two fragments to the layout..
public class MainActivity extends AppCompatActivity {
private Collapsebutton_Fragment cbut_frag;
private ColourView_Fragment cvw_frag;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cbut_frag = new Collapsebutton_Fragment();
cvw_frag = new ColourView_Fragment();
//ColourView Fragment ready
//CollapseButton Fragment ready
getSupportFragmentManager().beginTransaction()
.add(R.id.container_mainactivity, cbut_frag)
.add(R.id.container_mainactivity, cvw_frag)
.commit();
}
}
One of the added fragments contains a button. When clicking that button - accessing the onClick method of the button - I want to add another fragment..
My code is the following:
public class ColourView_Fragment extends Fragment {
FragmentManager fragmentManager;
ThreeButton_Fragment tbt_fragment;
public ColourView_Fragment(){}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.colourview_fragment, container, false);
FrameLayout frameLayout = (FrameLayout)rootView.findViewById(R.id.ColourView);
frameLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getFragmentManager().beginTransaction()
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.add(R.id.container_mainactivity, tbt_fragment)
.commit();
}
});
return rootView;
}
I get the following error:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference
There is an error in line
.add(R.id.container_mainactivity, tbt_fragment)
How can I correct?
You haven't initialized tbt_fragment in ColourView_Fragment

How to Enable/ Disable button from another fragment in android?

i have an activity with 4 fragments from fragment number 1 I want to enable an existing button (that is disable) on fragment 3, when i click in my button in fragment1. this is my attempt:
fragment 1:
public class FragmentEvolucion extends Fragment {
//btnGuardar is in fragment1, the others are in fragment 3 and 4
Button btnGuardar, btnHabilitarMed, btnHabilitarImc;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_evolucion, container, false);
btnGuardar=(Button)rootView.findViewById(R.id.btnGuardarEvolucion);
btnHabilitarMed=(Button)rootView.findViewById(R.id.btnGuardarMedicacion);
btnHabilitarImc=(Button)rootView.findViewById(R.id.btnGuardarDiagnostico);
btnGuardar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
btnHabilitarMed.setEnabled(true);
btnHabilitarImc.setEnabled(true);
}
});
this give me an error:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setEnabled(boolean)' on a null object reference
How can i access the button and change it status enabled correctly?
First of all, create a interface.
UpdateButtonListener.java
public interface UpdateButtonListener {
void onUpdate(boolean status);
}
Now in fragment 3, implement interface to class
public class Fragment3 extends Fragment implements UpdateButtonListener{
public static UpdateButtonListener updateButton;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment3, container, false);
updateButton = this;
return view;
}
#Override
public void onUpdate(boolean status) {
// here set the functionality of button whether to disable or not .
if(status){
btnHabilitarMed.setEnabled(true);
btnHabilitarImc.setEnabled(true);
}
}
}
Now in first fragment.
btnGuardar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Fragment3.updateButton.onUpdate(true);
}
Like-wise do for other's.

Fragment gives null object reference on layout inflater

I have a fragment "data" class which receives an array of string from the main activity class and sets those strings as textview inside itself.
I have a function "set" which receives string array as parameters and sets that as textview. Code for fragment "data" class is -
public class data extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v=inflater.inflate(R.layout.data,container,false);
return v;
}
public void set(String[] a){
LayoutInflater li=(LayoutInflater)getActivity().getLayoutInflater() // Logcat gives error at this line
View v=li.inflate(R.layout.data,null);
TextView t1=(TextView)v.findViewById(R.id.textView3);
TextView t2=(TextView)v.findViewById(R.id.textView4);
t1.setText(a[0]);
t2.setText(a[1]);
}
}
Log cat error is -
java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.LayoutInflater android.app.Activity.getLayoutInflater()' on a null object reference
*****EDIT******
Now I am passing data using bundles instead of String array-
My data class looks like this-
public class data extends Fragment {
TextView t1,t2;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v=inflater.inflate(R.layout.data,container,false);
t1=(TextView)v.findViewById(R.id.textView3);
t2=(TextView)v.findViewById(R.id.textView4);
return v;
}
public void set(){
t1.setText(getArguments().getString("name"));
t2.setText(getArguments().getString("email"));
}
}
I am calling this set like this from my main activity
show.setOnClickListener(new OnClickListener(){ public void onClick(View v){
FragmentTransaction ft=getFragmentManager().beginTransaction();
data frag=new data();
ft.add(R.id.ly2,frag);
ft.commit();
String s[]=data.show();
Bundle b=new Bundle();
b.putString("name",s[0]);
b.putString("email",s[1]);
frag.setArguments(b);
frag.set();
}});<br><br>
My show function is inside another class that uses database-
public String[] show(){
String[] col={"name","email"};
Cursor c=sdb.query("book",col,null,null,null,null,null);
c.moveToFirst();
String d[]=new String[2];
d[0] =c.getString(c.getColumnIndex("name"));
d[1] =c.getString(c.getColumnIndex("email"));
return d;
}
Logcat now says-
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
Kindly help.
You are calling set() before the fragment has been attached to the activity.
UPDATE: In your edited question, you are still calling set() before the fragment has been attached to the activity. commit() on a FragmentTransaction is asynchronous; work on attaching the fragment to the activity will not begin until after you return control of the main application thread back to the framework.
public class data extends Fragment {
TextView t1;
TextView t2;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v=inflater.inflate(R.layout.data,container,false);
t1=(TextView)v.findViewById(R.id.textView3);
t2=(TextView)v.findViewById(R.id.textView4);
return v;
}
public void set(String[] a){
t1.setText(a[0]);
t2.setText(a[1]);
}
}
You do not need to inflate the layout twice in a fragment.

Maintain fragment's view state

I have seen Link1 for this issue but could understand it right. I have a fragment that loads a list. When i click the list item it opens another activity. But i press back button it loads the list again. I want it to be at the same scroll position where it was before. In above mentioned link it specifies to use flag but i haven't got the point.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
android.app.Fragment fragment = new MeFragment();
getFragmentManager().beginTransaction().replace(R.id.layout_FragmentsContainer, fragment).addToBackStack(null).commit();
}
}
public class MeFragment extends Fragment
{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.fragment_me, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
meLV = (ListView) getView().findViewById(R.id.lv_Inbox);
loadingListProgress = (ProgressBar) getView().findViewById(R.id.progress_LoadingList);
meList = new ArrayList<Message>();
meAdapter = new MessagesListAdapter(getActivity(), meList);
//addFooter();
meLV.setAdapter(meAdapter);
meLV.setOnItemClickListener(this);
pageCount = 0;
loadmoreProgressDialog = new ProgressDialog(getActivity());
loadmoreProgressDialog.setTitle("Please wait ...");
loadmoreProgressDialog.setMessage("Loading more ...");
loadmoreProgressDialog.setCancelable(true);
loadUserMessages();
meLV.setOnScrollListener(new EndlessScrollListener() {
#Override
public void onLoadMore(int page, int totalItemsCount) {
// TODO Auto-generated method stub
//addFooter();
loadmoreProgressDialog.show();
loadUserMessages();
}
});
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// TODO Auto-generated method stub
Utils.showToast_msg(getActivity(), "MessageItemClicked");
ReferralDetailFragment fragment = new ReferralDetailFragment();
getFragmentManager().beginTransaction().replace(R.id.layout_FragmentsContainer, fragment).addToBackStack(null).commit();
}
}
public class ReferralDetailFragment extends Fragment implements OnClickListener {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_referraldetail,container, false);
linkToAcknowledge = (TextView) view.findViewById(R.id.lbl_Link_to_Acknowledge);
return view;
}
}
I implemented a simple solution for this in my app, basically when you press back to go to the fragment again, onCreateView() is called. Here in onCreateView() you have done all initialization, so we change
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_me, container, false);
/*
*Whatever you want to do
*
*/
return view;
}
to:
View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
if(view==null){
view = inflater.inflate(R.layout.fragment_me, container, false);
/*
*Whatever you want to do
*
*/
}
else{
((ViewGroup)view.getParent()).removeView(view);
}
return view;
}
Here, we move View view outside and make it a class variable. So if it is the first time the fragment is called, it is null and the initialization occurs, otherwise it goes to else black. Else block is required because onCreateView() adds whatever it returns as a child of the view's parent, so since view is already there, we remove it and onCreateView automatically adds it again.
According to our exchange in the comments, I completely deletde my answer and re-write a new one.
I copy/paste the code from one of my apps and removing the useless things and changing the names. Hope there is not too many typing mistakes, at that it is the minimum required to have it working.
When I pop back to FirstFragment from SecondFragment, the scroll position of FirstFragment is the same as when I clicked an item to load the SecondFragment.
Note that I don't extend FragmentActivity. I have an activity which loads the fragments.
Extend/modify to match your needs.
MainActivity :
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_layout);
}
}
FirstFragment Class :
public class FirstFragment extends Fragment implements OnItemClickListener {
private ListView mListView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.first_fragment_layout, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mListView = (ListView) getView().findViewById(R.id.listview_first_fragment);
mListView.setAdapter(mAdapter); // depends on your adapter
mListView.setOnItemClickListener(this);
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mListView.setItemChecked(position, true);
//in case you need, set the bundle here, for example pass the position
Bundle arguments = new Bundle();
arguments.putInt("position", position);
SecondFragment secondFragment = new SecondFragment();
secondFragment.setArguments(arguments);
getFragmentManager().beginTransaction().replace(R.id.fragment_container, secondFragment).addToBackStack(null).commit();
}
}
SecondFragment Class :
public class SecondFragment extends Fragment {
private Integer mPosition;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.second_fragment_layout, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Bundle arguments = getArguments();
if (arguments == null) {
mPosition= 0;
} else {
mPosition= arguments.getInt("Position");
}
}
}
What you are trying to achieve may be done with help of savedInstanceState. i also had this kind of problem which i resolved by using add() method instead of replace() in transition.
If you can change your method or already not using add() than give it a shot.
and if add() method didn't do the trick then check the implementation of savedInstanceState.
correctly save instance state.
How to save states of fragment views.

Categories

Resources