how to resolve Null Pointer Exception in android? [duplicate] - android

This question already has answers here:
Avoiding NullPointerException in Java
(66 answers)
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 months ago.
i'm working with fragments. I have created a List fragment and a Detail fragment.
when i click on an item in the list the app crashes and it gives the following null pointer exception.
Attempt to invoke virtual method 'void
android.widget.TextView.setText(java.lang.CharSequence)' on a null
object reference
I tried solutions of similar question but nothing works for me.
here is my Main Activity:
public class MainActivity extends AppCompatActivity implements ListFrag.ItemSelected {
TextView tvDescription;
ArrayList<String> descriptions;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvDescription = (TextView) findViewById(R.id.tvDescription);
descriptions = new ArrayList<>();
descriptions.add("Description for item 1");
descriptions.add("Description for item 2");
descriptions.add("Description for item 3");
}
#Override
public void onItemSelected(int index) {
tvDescription.setText(descriptions.get(index));
}
}
List Fragment:
public class ListFrag extends ListFragment {
ItemSelected activity;
public interface ItemSelected
{
void onItemSelected(int index);
}
public ListFrag() {
// Required empty public constructor
}
#Override
public void onAttach(#NonNull Context context) {
super.onAttach(context);
activity = (ItemSelected) context;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ArrayList<String> data = new ArrayList<>();
data.add("1.This is item 1");
data.add("2.This is item 2");
data.add("3.This is item 3");
setListAdapter(new ArrayAdapter<>( getActivity() , android.R.layout.simple_list_item_1,data));
}
#Override
public void onListItemClick(#NonNull ListView l, #NonNull View v, int position, long id) {
activity.onItemSelected(position);
} }
Detail Fragment:
public class DetailFrag extends Fragment {
public DetailFrag() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_detail, container, false);
}
}
activity_main layout:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context=".MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="#+id/listFrag"
android:name="com.example.fragmentspart1.ListFrag"
android:layout_width="8dp"
android:layout_height="match_parent"
android:layout_weight="1"
tools:layout="#layout/fragment_list" />
<androidx.fragment.app.FragmentContainerView
android:id="#+id/detailFrag"
android:name="com.example.fragmentspart1.DetailFrag"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="2"
tools:layout="#layout/fragment_detail" />
</LinearLayout>
fragment_list layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#FFFFFF"
tools:context=".ListFrag">
<ListView
android:id="#+id/lvList"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
fragment_detail layout :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#color/design_default_color_secondary"
tools:context=".DetailFrag">
<TextView
android:id="#+id/tvDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:layout_marginRight="20dp"
android:text="#string/textview"
android:textColor="#FFFFFF"
android:textSize="20sp"
android:textStyle="bold" />
</LinearLayout>

(TextView) findViewById(R.id.tvDescription);
returns null in MainActivity because your TextView tvDescription is in fragment_detail layout.
You must move this line to onViewCreated() of your DetailFragment and in onItemSelected() you must create a new instance of DetailFragmet and pass data as arguments to the DetailFragment instance.
After you start the DetailFragment you can do following in DetailFragment:
override onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
tvDescription = (TextView) findViewById(R.id.tvDescription);
// get your list item data from arguments
tvDescription.setText(descriptions.get(index));
}

Related

Custom ArrayAdapter in Fragment not calling getView()

I'm trying to load a list of objects inside a ListView, that is contained inside a Fragment. But I can't get it to work no matter what.
I've tried to load the same data and the same list directly inside the main activity and it works. But not in the fragment.
Here is my code:
MainActivity - The fragment loads correctly, data from the server is retrieved, everything is ok here.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
setContentView(R.layout.side_menu);
if (SharedPreferencesManager.isAuthenticated(getApplicationContext())) {
ServerComm.getInstance(getApplicationContext()).requestMenuItems(new BaseVolleyCallback() {
#Override
public void onMenuRequest(Menu result) {
leftSideMenu = (SideMenuFragment) getSupportFragmentManager().findFragmentById(R.id.left_side_menu);
leftSideMenu.menuItemList = result.top;
leftSideMenu.test();
}
});
}
}
Fragment: Again, everything looks to be fine
public class SideMenuFragment extends Fragment {
ArrayList<MenuItem> menuItemList;
View mView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.side_menu, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mView = view;
}
public void test(){
MenuItemAdapter adapter = new MenuItemAdapter(getContext(), menuItemList);
ListView listView = (ListView) mView.findViewById(R.id.listView);
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final MenuItem item = (MenuItem) parent.getItemAtPosition(position);
MainActivity activity = (MainActivity)getActivity();
activity.loadContent(item);
}
});
}
}
Adapter: - Constructor called with the list of items, getCount() is called with the correct number of items. getView - NOT CALLED.
class MenuItemAdapter extends ArrayAdapter<MenuItem> {
private Context mContext;
private List<MenuItem> menuList = new ArrayList<>();
public MenuItemAdapter(#NonNull Context context, ArrayList<MenuItem> list) {
super(context, 0 , list);
mContext = context;
menuList = list;
}
#Override
public int getCount () {
return menuList.size();
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(R.layout.menu_cell, parent, false);
}
MenuItem item = menuList.get(position);
TextView tvName = (TextView) convertView.findViewById(R.id.itemName);
tvName.setText(item.name);
return convertView;
}
}
main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<fragment android:name="com.example.dbl.SideMenuFragment"
android:id="#+id/left_side_menu"
android:layout_width="0dp"
android:layout_height="match_parent"
android:elevation="100dp"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent=".7"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
side_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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="match_parent"
android:background="#android:color/transparent">
<ListView
android:id="#+id/listView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#color/colorAccent"
android:cacheColorHint="#android:color/transparent"
android:divider="#CCCCCC"
android:dividerHeight="1dp"
android:paddingLeft="2dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
menu_cell.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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="match_parent">
<TextView
android:id="#+id/itemName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:text="Test"
android:textAlignment="center"
android:textColor="#666"
android:textSize="24sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
Honestly, I don't know what I could try next.

Android: RecyclerView content messed up when i open the app and comes back to normal after scrolling down

I'm learning about fragments and i made this app to display a list of recipes, Each row of this list have an image of the recipe and the name of the recipe and i put the recyclerView inside a fragment but the problem is when i open the application the content of the recyclerView gets messed up and returns to normal after scrolling down as shown in the two screenshots below.
before scrolling
after scrolling down
MainActivity class
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListFragment listFragment = new ListFragment();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.placeHolder, listFragment);
fragmentTransaction.commit();
}}
ListAdapter class
public class ListAdapter extends RecyclerView.Adapter{
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,parent,
false);
return new ListViewHolder(view);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((ListViewHolder) holder).bindView(position);
}
#Override
public int getItemCount() {
return Recipes.names.length;
}
private class ListViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView mRecipeText;
private ImageView mRecipeImage;
public ListViewHolder(View itemView) {
super(itemView);
mRecipeImage = itemView.findViewById(R.id.itemImage);
mRecipeText = itemView.findViewById(R.id.itemText);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
}
public void bindView(int position) {
mRecipeText.setText(Recipes.names[position]);
mRecipeImage.setImageResource(Recipes.resourceIds[position]);
}
}}
listFragment class
public class ListFragment extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_list, container , false);
RecyclerView recyclerView = view.findViewById(R.id.listRecyclerView);
ListAdapter listAdapter = new ListAdapter();
recyclerView.setAdapter(listAdapter);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
return view;
}}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
android:id="#+id/placeHolder"
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="match_parent"
android:layout_height="match_parent"
tools:context="com.example.elswefi.smellslikebakin.MainActivity">
</FrameLayout>
fragment_list.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/listRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</android.support.constraint.ConstraintLayout>
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:orientation="horizontal"
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="wrap_content">
<ImageView
android:id="#+id/itemImage"
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="1"
android:layout_margin="8dp"
android:scaleType="fitCenter"
app:srcCompat="#drawable/bagels"
/>
<TextView
android:id="#+id/itemText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:layout_margin="12dp"
android:text="TextView"
android:textSize="24sp"
/>
</LinearLayout>
I hope anyone could help me because i'm still learning and i don't have any idea where this bug came from.
Problem solved
I solved the problem by adding this line of code
android:adjustViewBounds="true"
to the imageView in the list_item.xml file
thank you guys for your comments i really appreciate it.

Why is onActivityCreated() not called in second fragment?

I am creating an app in which in portrait mode I have an activity that has a fragment which contains a listview and on clicking on that listview, Second activity is called to show the data using second fragment but the problem is that when second fragment, i.e. Frag2 is called its onActivityCreated() method is not getting called. Why so?
MainActivity.xml
portrait mode
<LinearLayout 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="match_parent"
android:layout_height="match_parent"
tools:context="com.example.ankit.fragprac2.MainActivity">
<fragment
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/frag1"
android:name="com.example.ankit.fragprac2.Frag1"
/>
</LinearLayout>
landscape mode
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/frag1"
android:name="com.example.ankit.fragprac2.Frag1"
android:layout_weight="1"/>
<fragment
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/frag2"
android:name="com.example.ankit.fragprac2.Frag2"
android:layout_weight="1"/>
</LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity implements Frag1.Comm {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void respond(int i)
{
FragmentManager fm=getFragmentManager();
Frag2 fg2= (Frag2) fm.findFragmentById(R.id.frag2);
if(fg2!=null && fg2.isVisible())
{
fg2.setData(i);
}
else
{
Intent in=new Intent(this,SecondActivity.class);
in.putExtra("position",i);
startActivity(in);
}
}
}
Fragment1.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/list"/>
</RelativeLayout>
Fragment1.java
public class Frag1 extends Fragment {
ListView lv;
Comm c1;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.activity_frag1,container,false);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
String[] s=getResources().getStringArray(R.array.topics);
c1 = (Comm) getActivity();
lv = getActivity().findViewById(R.id.list);
lv.setAdapter(new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1,s));
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
c1.respond(i);
}
});
}
interface Comm
{
void respond(int i);
}
}
Fragment2.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/text1"
android:layout_centerHorizontal="true"
android:textSize="20dp"
android:textStyle="bold"
android:textColor="#000"/>
</RelativeLayout>
Fragment2.java
public class Frag2 extends Fragment {
TextView t;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.activity_frag2,container,false);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Toast.makeText(getActivity(),"OAC",Toast.LENGTH_SHORT).show();
t=getActivity().findViewById(R.id.text1);
// s1=new String[getResources().getStringArray(R.array.data).length];
// Toast.makeText(getActivity(),""+s1.length,Toast.LENGTH_SHORT).show();
if(savedInstanceState!=null)
{
String s=savedInstanceState.getString("data",null);
t.setText(s);
}
}
public void setData(int i)
{ String[] s1 =getResources().getStringArray(R.array.data);
t.setText(s1[i]);
}
#Override
public void onSaveInstanceState(Bundle outState) {
outState.putString("data",t.getText().toString());
}
}
SecondActivity.xml
<RelativeLayout 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="match_parent"
android:layout_height="match_parent"
tools:context="com.example.ankit.fragprac2.SecondActivity">
<fragment
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/frag21"
android:name="com.example.ankit.fragprac2.Frag2"/>
</RelativeLayout>
SecondActivity.java
public class SecondActivity extends AppCompatActivity {
int i;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Bundle b= getIntent().getExtras();
if(b!=null)
{
i= b.getInt("position",0);
}
FragmentManager fm=getFragmentManager();
Frag2 fga2= (Frag2) fm.findFragmentById(R.id.frag21);
fga2.setData(i);
}
}
In the SecondActivity.onCreate(), move this code:
FragmentManager fm=getFragmentManager();
Frag2 fga2= (Frag2) fm.findFragmentById(R.id.frag21);
fga2.setData(i);
To SecondActivit.onStart().
When using fga2.setData(i) in the onCreate, the Activity is not created yet; it is being created. Hence the onActivityCreated() method of the fragment has not been called yet.
Other notes:
Activity should extent FragmentActivity instead of AppCompatActivity.
you can use getSupportFragmentManager().findFragmentById to get the fragment.
Also see the Activity Life Cycle and Fragment LifeCycle.
Hope this helps.

Fragment communicating between fragment using interface failed, nullpointerException

Trying to Communicating FragmentA to FragmentB, doing is taking numeric value from fragmentA adding them and displaying result in fragmentB using interface, but I got nullpointerException, I have look many times in the code but seems everything is fine but getting nullpointerException showing line 34 in FragmentA
listener.setResult(result+" ");
Here's My FragmentA
public class FragmentA extends Fragment{
MyFragmentInterface listener;
Button buton;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view =inflater.inflate(R.layout.fragment_a,container,false);
final EditText editText= (EditText) view.findViewById(R.id.edit_text1);
final EditText editText2= (EditText) view.findViewById(R.id.edit_text2);
buton= (Button) view.findViewById(R.id.button);
buton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int num1=Integer.parseInt(editText.getText().toString());
int num2=Integer.parseInt(editText2.getText().toString());
int result=num1+num2;
listener.setResult(result+" ");
}
});
return view;
}
#Override
public void onAttach(Context context) {
listener= (MyFragmentInterface) context;
super.onAttach(context);
}
}
Here's my fragment_a.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/edit_text1"
android:inputType="number"
android:textSize="30sp"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:id="#+id/edit_text2"
android:textSize="30sp"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Calculate"
android:id="#+id/button"
android:background="#null"
android:textAllCaps="false"/>
</LinearLayout>
FragmentB.java
public class FragmentB extends Fragment {
TextView textView;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
textView= (TextView) getActivity().findViewById(R.id.textview);
return inflater.inflate(R.layout.fragment_b,container,false);
}
public void putresult(String r){
textView.setText(r);
}
}
fragment_b.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30sp"
android:id="#+id/textview"
android:text="Text will appear here"/>
</LinearLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity implements MyFragmentInterface {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentA fragmentA=new FragmentA();
FragmentManager fragmentManager=getFragmentManager();
FragmentTransaction fragmentTransaction=fragmentManager.beginTransaction();
fragmentTransaction.addToBackStack(null);
fragmentTransaction.replace(R.id.linear1,fragmentA);
fragmentTransaction.commit();
FragmentB fragmentB=new FragmentB();
FragmentManager fragmentManager1=getFragmentManager();
FragmentTransaction fragmentTransaction1=fragmentManager1.beginTransaction();
fragmentTransaction1.addToBackStack(null);
fragmentTransaction1.replace(R.id.linear2,fragmentB);
fragmentTransaction1.commit();
}
#Override
public void setResult(String result) {
FragmentB fragmentnew=new FragmentB();
fragmentnew= (FragmentB) getFragmentManager().findFragmentById(R.id.linear2);
fragmentnew.putresult(result);
}
}
MyFragmentInterface.java
public interface MyFragmentInterface {
public void setResult(String result);
}
activity_main.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"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="queendevelopers.com.communicate.MainActivity"
android:weightSum="2"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="#+id/linear1"
android:orientation="vertical" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="#+id/linear2"
android:orientation="vertical" />
</LinearLayout>
error log:
08-16 16:11:42.307 7630-7630/queendevelopers.com.communicate E/AndroidRuntime: FATAL EXCEPTION: main
Process: queendevelopers.com.communicate, PID: 7630
java.lang.NullPointerException: Attempt to invoke interface method 'void queendevelopers.com.communicate.MyFragmentInterface.setResult(java.lang.String)' on a null object reference
at queendevelopers.com.communicate.FragmentA$1.onClick(FragmentA.java:34)
at android.view.View.performClick(View.java:4832)
at android.view.View$PerformClick.run(View.java:19844)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5319)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1016)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:811)
To expand on the comment I made that solved the problem:
The original issue was not to do with your interface callback (this was not the root cause of the NullPointerException).
When the callback method setResult(String result) was invoked this line :
fragmentnew.putresult(result); was causing the null pointer because, in the method putresult in your fragment there is a null reference to your textView (textView.setText(r);).
For every Activity you can have an associated view heirarchy (your XML file), this is set by setContentView() in onCreate(). Now if you try and reference any #+id widgets from the XML layout you can cast relevant object type : TextView, EditText, ListView. Fragments (which are attached to a hosting Activity) can also have their own layouts, this is inflated in onCreateView(). Your final code should look something like this:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_b,container,false);
textView = (TextView) view.findViewById(R.id.textview);
return view;
}
Your view object now contains your view hierarchy for the inflated XML Layout, from which you can access all widgets.
The line of code that was incorrect was:
textView = (TextView) getActivity().findViewById(R.id.textview);
The reason being you are using the convenience method getActivity() this will return the hosting Activity reference - thus you now will have access to the hosting Activity - used a lot for gaining a Context of other purposes, however your view id reference is invalid because it is in the view hierarchy of your inflated layout in your fragment.
Try this method inside your Fragment
#Override
public void onAttach(Context context) {
super.onAttach(context);
listener = (MyFragmentInterface) getActivity();
}
try this
(((MyFragmentInterface)getActivity()).setResult(result+" ");
Change in Fragment A:
from:
buton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int num1=Integer.parseInt(editText.getText().toString());
int num2=Integer.parseInt(editText2.getText().toString());
int result=num1+num2;
listener.setResult(result+" ");
}
});
To
buton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int num1=Integer.parseInt(editText.getText().toString());
int num2=Integer.parseInt(editText2.getText().toString());
int result=num1+num2;
((MainActivity) getActivity()).setResult(result+" ");
}
});
Because I think your listener object is not initialised before being used so try this answer please.

How to get the exact moment when a fragment is no longer visible to the user?

I'm trying to do a wizard to save a sheet with simple informations.
I spent hours looking for solutions, but all of them didn't work.
I have an activity whose layout has just a ViewPager. This activity has two fragments (A and B).
When the first one is complete, the user clicks on the "Next Button" on action bar and then the second one should appear. At this point, when the user finish the process, he clicks on "Save Button" and the sheet should be saved.
I've tried to do this in several ways, but none of them have worked:
For now, I'm trying to know when the fragment A turns invisible (i.e., when the fragment B is occupating all the screen), then I will be able to send its data using an interface (like explained here). The problem is that I don't know which method to use...
I've already tried all the lifecycle methods but none of them has worked.
Does anybody have any suggestion?
You can use ViewPager.onPageScrolled() to detect when the user scrolls the ViewPager.
Check the ViewPager Ref Docs
I've modified Reference Docs example to demonstrate storing information from the first fragment into a variable in the parent activity when the user scrolls. I've included all the java and xml files, so you should be able to just cut and paste into a new project to get it running.
MainActivity.java
public class MainActivity extends FragmentActivity {
private static final int NUM_ITEMS = 2;
private MyAdapter mAdapter;
private ViewPager mPager;
private boolean mStoredCheckBoxState;
private TextView mStoredCheckBoxStateNotification;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mStoredCheckBoxStateNotification = (TextView)findViewById(R.id.storedCheckState);
mAdapter = new MyAdapter(getSupportFragmentManager());
mPager = (ViewPager)findViewById(R.id.pager);
mPager.setAdapter(mAdapter);
mPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int arg0) {
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
FragmentA frag = (FragmentA)mAdapter.getItem(0);
// Store the checked state value from Fragment A
mStoredCheckBoxState = frag.getCheckBoxState();
// Update the UI with the stored CheckBox state value
if (mStoredCheckBoxState == true) {
mStoredCheckBoxStateNotification.setText("Checked");
} else {
mStoredCheckBoxStateNotification.setText("Not Checked");
}
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
public static class MyAdapter extends FragmentPagerAdapter {
private FragmentA mFragA = new FragmentA();
private FragmentB mFragB = new FragmentB();
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return mFragA;
case 1:
return mFragB;
}
return null;
}
#Override
public int getCount() {
return NUM_ITEMS;
}
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Stored Checkbox State : " />
<TextView
android:id="#+id/storedCheckState"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Not Checked" />
</LinearLayout>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1">
</android.support.v4.view.ViewPager>
</LinearLayout>
FragmentA.java
public class FragmentA extends Fragment {
private CheckBox mCheckBox;
private boolean mCheckBoxState;
// Getters
public boolean getCheckBoxState() {
return mCheckBoxState;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_a, container, false);
mCheckBox = (CheckBox)view.findViewById(R.id.checkBox1);
mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mCheckBoxState = isChecked;
}
});
return view;
}
}
fragment_a.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment A" />
<CheckBox
android:id="#+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="CheckBox" />
</LinearLayout>
FragmentB.java
public class FragmentB extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_b, container, false);
return view;
}
}
fragment_b.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment B" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</LinearLayout>
</LinearLayout>
Ok, I solved this problem overriding the method [setUserVisibleHint(boolean)][1] and checking the parameter! ;)

Categories

Resources