I have been trying to use Fragments in Android Studio and have been successful in the implementation of it. But, when I am trying to pass any data (Text/String here) I’m getting a Null Pointer Exception.
The Fragment doesn’t appear to get received by the second Fragment. Here is the code:
MainActivity.java
public class MainActivity extends AppCompatActivity {
TabLayout tb;
ViewPager2 vp;
viewPagerAdapter vpa;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tb=findViewById(R.id.tab_lyt);
vp= findViewById(R.id.pager);
vpa= new viewPagerAdapter(this);
vp.setAdapter(vpa);
tb.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
vp.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
vp.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
tb.getTabAt(position).select();
}
});
}
}
activity_main.xml
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/tab_lyt"
android:layout_marginTop="0dp" />
<com.google.android.material.tabs.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tab_lyt">
<com.google.android.material.tabs.TabItem
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Menu 1"/>
<com.google.android.material.tabs.TabItem
android:id="@+id/frag2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Menu 2"/>
</com.google.android.material.tabs.TabLayout>
</RelativeLayout>
viewPagerAdapter.java
public class viewPagerAdapter extends FragmentStateAdapter {
public viewPagerAdapter(@NonNull FragmentActivity fragmentActivity) {
super(fragmentActivity);
}
@NonNull
@Override
public Fragment createFragment(int position) {
switch (position)
{
case 0: return new frag1();
case 1: return new frag2();
default: return new frag1();
}
}
@Override
public int getItemCount() {
return 2;
}
}
frag1.java
public class frag1 extends Fragment {
private EditText editText;
private Button button;
public frag1(){
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_frag1, container, false);
editText = view.findViewById(R.id.frag1ET);
button = view.findViewById(R.id.frag1btn);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String text = editText.getText().toString();
Bundle bundle = new Bundle();
bundle.putString("tex", text);
Toast.makeText(getContext(), ""+bundle.toString(), Toast.LENGTH_LONG).show();
frag2 f2 = new frag2();
f2.setArguments(bundle);
editText.setText("");
}
});
return view;
}
}
frag1.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".frgmnts.frag1">
<EditText
android:id="@+id/frag1ET"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="116dp"
android:ems="10"
android:hint="Enter text"
android:inputType="textPersonName"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/frag1btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="28dp"
android:text="Button"
app:layout_constraintEnd_toEndOf="@+id/frag1ET"
app:layout_constraintStart_toStartOf="@+id/frag1ET"
app:layout_constraintTop_toBottomOf="@+id/frag1ET" />
<TextView
android:id="@+id/frag1tv"
android:layout_width="260dp"
android:layout_height="56dp"
android:layout_marginTop="56dp"
android:textAlignment="textStart"
android:hint="Text from Frag 2"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="@+id/frag1ET"
app:layout_constraintHorizontal_bias="0.506"
app:layout_constraintStart_toStartOf="@+id/frag1ET"
app:layout_constraintTop_toBottomOf="@+id/frag1btn" />
</androidx.constraintlayout.widget.ConstraintLayout>
frag2.java
public class frag2 extends Fragment {
private TextView tv2;
public frag2(){
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_frag2, container, false);
tv2 = view.findViewById(R.id.frag2tv);
return view;
}
@Override
public void onResume() {
super.onResume();
Bundle bundle = getArguments();
if (bundle != null) {
String text = bundle.getString("tex");
tv2.setText(text);
}
else
tv2.setText("Text not received");
}
}
frag2.xml
<?xml version="1.0" encoding="utf-8"?>
<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="match_parent"
android:layout_height="match_parent"
tools:context=".frgmnts.frag2">
<EditText
android:id="@+id/frag2ET"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="116dp"
android:ems="10"
android:hint="Enter text"
android:inputType="textPersonName"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/frag2btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:text="Button"
app:layout_constraintEnd_toEndOf="@+id/frag2ET"
app:layout_constraintStart_toStartOf="@+id/frag2ET"
app:layout_constraintTop_toBottomOf="@+id/frag2ET" />
<TextView
android:id="@+id/frag2tv"
android:layout_width="260dp"
android:layout_height="56dp"
android:layout_marginTop="44dp"
android:hint="Text from Frag 1"
android:textAlignment="textStart"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="@+id/frag2ET"
app:layout_constraintStart_toStartOf="@+id/frag2ET"
app:layout_constraintTop_toBottomOf="@+id/frag2btn" />
</androidx.constraintlayout.widget.ConstraintLayout>
Any help and inputs in this regard will be helpful. Thank you
2
Answers
You’re creating a new fragment when sending data, which you souldn’t. The
viewPager
has no reference of the new fragment with data. That’s why you’re getting theNullPointerException
.There are several ways to pass data from one activity to another. The most convinient way is to use a common
ViewModel
class. Here is an example:Remember the
requireActivity()
is crucial since we want the sameviewModel
in both fragments.I’m not sure it is the best idea, but it can solve your requirement.
You can create a listener to listen to your button and pass the text to the other fragment.
And then place the listener on the first fragment.
Then finally handle the listener on Adapter.