Sorry for my english. I have one activity and in this activity in FragmentPagerAdapter exist 5 fragments. All fragments use one object model for inforation(product name, product image ...).
My activity get data from data base. And then it data send to all fragments. My example Activity:
#BindView(R.id.tabs_sep_prod) TabLayout tabs_sep_prod;
#BindView(R.id.viewpager_sep_prod) ViewPager viewpager_sep_prod;
PrepBaseProdFragment prepBaseProdFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sep_product);
ButterKnife.bind(this);
prepBaseProdFragment = new PrepBaseProdFragment();
// there i have another fragments
// ...
setupViewPager(viewpager_sep_prod);
tabs_sep_prod.setupWithViewPager(viewpager_sep_prod);
}
private void setupViewPager(ViewPager viewPager) {
SepProductActivity.ViewPagerAdapter adapter = new SepProductActivity.ViewPagerAdapter(
adapter.addFrag(prepBaseProdFragment, getString(R.string.sep_prep_base));
// there i have another addFrag
// ...
viewPager.setOffscreenPageLimit(5);
viewPager.setAdapter(adapter);
}
#Override
public void onResume() {
super.onResume();
// this i call method from presenter, it return data in method setData
if(idCat != null && idProd != null)
sepProductPresenter.getSepProd(idCat, idProd);
}
#Override
public void setData(SepProductModel sepProductModel) {
// there i send data to fragment
prepBaseProdFragment.setDataInf(sepProductModel);
// ...
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFrag(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
my fragment
public class PrepBaseProdFragment extends BaseFragment {
#BindView(R.id.text) TextView text;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_about_prod_prepare_base, parent, false);
ButterKnife.bind(this, view);
Log.e("PrepBaseProdFragment", "PrepBaseProdFragment");
return view;
}
public void setDataInf(SepProductModel sepProductModel) {
text.setText(sepProductModel.getPROPERTY_PR_SUBSTRPREP_UA_VALUE().getTEXT());
}
}
My question: when i send data from activity to fragment, my view do not have time to initialize. In fragment line text.setText(sepProductModel.getPROPERTY_PR_SUBSTRPREP_UA_VALUE().getTEXT()); error
java.lang.NullPointerException: Attempt to invoke virtual method 'void
android.widget.TextView.setText(java.lang.CharSequence)' on a null
object reference
Please, help me solve my problem. I spend many times for this
You can check if the text view is null save the data in a variable inside the fragment and in onCreateView use the data variable if it is filled and set the textview text.
Something like this:
// Inside the Fragment body
private SepProductModel sepProductModel;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_about_prod_prepare_base, parent, false);
ButterKnife.bind(this, view);
Log.e("PrepBaseProdFragment", "PrepBaseProdFragment");
if(this.sepProductModel != null)
text.setText(this.sepProductModel.getPROPERTY_PR_SUBSTRPREP_UA_VALUE().getTEXT());
return view;
}
public void setDataInf(SepProductModel sepProductModel) {
if(text != null){
// use text
}
else this.sepProductModel=sepProductModel;
}
I can advise you to wait for your data and then show fragments to adapter, moreover all of them use the same model. While you dont have data, you can show progress bar.
When you have needed model, you can create instances of your fragments and set bundle arguments for them. You can use method like this:
public static MyFragment newInstance(MyModel model){
MyFragment fragment = new MyFragment();
Bundle args = new Bundle();
args.putSerializable(KEY, model);//or args.putParcelable(KEY, model);
fragment.setArguments(args);
return fragment;
}
Notice: your model need to implement Serializable or Parcelable to be putted in bundle. You may read about difference here.
Then in your set data method, when you already have your model you can setup your adapter and set it to view pager, but with this approach:
adapter.addFrag(MyFragment.newInstance(model), getString(R.string.sep_prep_base));
It have to help you, ask me if you have some questions.
Related
I, know this question is already asked on community but still I am not able to resolve my issue. That's why posting this again. How to pass data from recyclerview adapter to fragment. I have successfully pass data from adapter to the activity. But not able to get how to pass data from adapter to the fragment. I have two Parameters in my database (1) mSliderImage and (2) mTitle. The mSliderImage is shown on home fragment. but now I want when user click on particular image of slider a new fragment get opens and there mTitle will be shown. I successfully able to open new fragment on click of image-slider base on image position. But not getting how to pass mTitle in that fragment. Please someone help me the whole code because I have to submit this college level project by 17th of January. I am only posting the important code not my whole code. I just want coding solution of how to pass mSliderTitle from adapter to the fragment. when I click on some image of Image Slider.
Below is my code:
In Model I have passed 2 Getters ans Setters already mentioned above. (1) mSliderImage and (2) mTitle.
Slider Adapter:
public class SliderImageAdapter extends SliderViewAdapter<SliderImageAdapter.SliderAdapterVH>{
public List<Banner> bannerList;
public Context context;
private OnItemClicked onClick;
public interface OnItemClicked {
void onItemClick(int position);
}
public SliderImageAdapter(Context context, List<Banner> bannerList, OnItemClicked onClick) {
this.bannerList = bannerList;
this.context = context;
this.onClick = onClick;
}
#Override
public SliderAdapterVH onCreateViewHolder(ViewGroup parent) {
View inflate = LayoutInflater.from(parent.getContext()).inflate(R.layout.image_slider_myshop, parent, false);
return new SliderAdapterVH(inflate);
}
#Override
public void onBindViewHolder(final SliderAdapterVH viewHolder, final int position) {
Glide.with(viewHolder.itemView)
.load(bannerList.get(position).getmSliderImage())
.into(viewHolder.imageViewBackground);
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onClick.onItemClick(position);
}
});
}
#Override
public int getCount() {
return bannerList.size();
}
public int getItemPosition (Object object) {
return POSITION_NONE;
}
public void setOnClick(OnItemClicked onClick) {
this.onClick = onClick;
}
class SliderAdapterVH extends SliderViewAdapter.ViewHolder {
View itemView;
ImageView imageViewBackground;
public SliderAdapterVH(View itemView) {
super(itemView);
imageViewBackground = itemView.findViewById(R.id.iv_auto_image_slider);
this.itemView = itemView;
}
}
Home Fragment: (Here Image Slider is Shown. and I want when user click a new fragment get open and show mTitle).
public class HomeFragment extends Fragment implements SliderImageAdapter.OnItemClicked {
private SliderImageAdapter sliderImageAdapter;
private List<Banner> bannerList;
bannerList = new ArrayList<>();
sliderImageAdapter = new SliderImageAdapter(getActivity(), bannerList, this);
#Override
public void onItemClick(int position) {
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.fragment_container_dashboard, SliderClickFragment.newInstance());
ft.addToBackStack(null);
ft.commit();
}
Slider Click Fragment XML:
<androidx.coordinatorlayout.widget.CoordinatorLayout
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/mSliderTitle"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Slider Click Fragment Java: (Here I want to show mTitle when user click on image)
public class SliderClickFragment extends Fragment {
public static SliderClickFragment newInstance() {
Bundle args = new Bundle();
SliderClickFragment fragment = new SliderClickFragment();
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.slider_click_listner,container,false);
return view;
}
}
Try this. I haven't tested but this flow should get what you are trying to achieve.
HomeFragment.java
public class HomeFragment extends Fragment implements SliderImageAdapter.OnItemClicked {
private SliderImageAdapter sliderImageAdapter;
private List<Banner> bannerList;
bannerList = new ArrayList<>();
sliderImageAdapter = new SliderImageAdapter(getActivity(), bannerList, this);
#Override
public void onItemClick(int position) {
//GET THE TITLE STRING HERE
String title = bannerList.get(position).getmSliderTitle();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
//PASS THIS TITLE TO THE FRAGMENT INSTANCE LIKE THIS
ft.add(R.id.fragment_container_dashboard, SliderClickFragment.newInstance(title));
ft.addToBackStack(null);
ft.commit();
}
SliderClickFragment.java
public class SliderClickFragment extends Fragment {
//EDIT the newInstance Method definition to include title like this:
public static SliderClickFragment newInstance(String title) {
Bundle args = new Bundle();
//PASS THE STRING IN THE BUNDLE WHICH WILL THEN BE FETCHED IN ONCREATEVIEW LATER LIKE THIS
args.putString("title", title);
SliderClickFragment fragment = new SliderClickFragment();
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.slider_click_listner,container,false);
//GET THE STRING HERE AND THEN USE IT HOWEVER YOU LIKE
String title = getArguments().getString("title");
return view;
}
}
I have an Weather adapter to show the weather, the activity is split into two screens, one half a listview (different adapter), the other is tablayout with another tablayout inside to scroll through all the different pages of weather that are available
After turning off the wifi to make sure i don't receive anything and then turning on the wifi to receive the weather i get the update method called for the adapter and the list is updated, new fragments created, onViewCreated is called but the fragments display as blank and as only 1 (can't cycle through them if there are multiple).
Here is the Weather ViewPagerAdapter
public class WeatherViewPagerAdapter extends FragmentStatePagerAdapter {
private List<Fragment> fragments;
public WeatherViewPagerAdapter(FragmentManager fm) {
super(fm);
fragments = new LinkedList<>();
if (Storage.getInstance().getWeatherModels().size() == 0){
// Displays page but with "no weather available" message
fragments.add(WeatherFragment.newInstance(null));
}else{
for (CurrentWeatherModel model : Storage.getInstance().getWeatherModels()){
fragments.add(WeatherFragment.newInstance(model));
}
}
}
public void rediscoverWeather(){
fragments.clear();
if (Storage.getInstance().getWeatherModels().size() == 0){
fragments.add(WeatherFragment.newInstance(null));
}else{
for (CurrentWeatherModel model : Storage.getInstance().getWeatherModels()){
fragments.add(WeatherFragment.newInstance(model));
}
}
}
#Override
public int getItemPosition(#NonNull Object object) {
return POSITION_NONE;
}
#Override
public int getCount() {
return fragments.size();
}
#Override
public Fragment getItem(int position) {
return fragments.get(position);
}
#Override
public Parcelable saveState() {
return null;
}
}
And this is the fragment that is in the Tablayout on the side that displays the weather
public class WeatherViewPagerFragment extends Fragment {
private WeatherViewPagerAdapter adapter;
private ViewPager viewpager;
private TabLayout tabLayout;
public static WeatherViewPagerFragment newInstance(){
return new WeatherViewPagerFragment();
}
#Override
public UniqueInfo getUniqueInfo() {
return null;
}
#Override
public void update() {
adapter.rediscoverWeather();
setPage(0);
adapter.notifyDataSetChanged();
}
public void setPage(int pageNumber){
if (pageNumber >=0 && pageNumber < adapter.getCount()){
viewpager.setCurrentItem(pageNumber, true);
}
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.weather_view_pager, container, false);
}
private void createAdapter(){
adapter = new WeatherViewPagerAdapter(getChildFragmentManager());
viewpager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewpager);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
viewpager = view.findViewById(R.id.viewpager);
tabLayout = view.findViewById(R.id.sliding_tabs);
createAdapter();
}
}
The update() for WeatherViewPagerFragment gets called when its meant to, which updates the Adapter, re-doing the fragments and calling onCreateView and onViewCreated, but what i see is just a blank fragment, any suggestions why this would be happening? i figured it could be a focus issue but i haven't had any luck as of yet with fixing it
I have googled everything during a day about the subject and nothing seems to work around for my project. I have added a viewpager to my main activity. There is two fragments attached to it thanks to a page adapter. I initialized everything on the OnCreate method from my main activity. The view pager work well. The problem is when I want to access from my MainActivity the textviews included in my fragments. I created a Set method in each fragment which modify the textviews accordingly to the arguments. So in order to call this method from my MainActivity I have to instantiate the fragments on my MainActivity and the problem is that this line of code return null and the fragments can not be instantiated. Here is the code used for testing this purpose.
Main Activity
public class MainActivity extends AppCompatActivity{
private SecondActivitySwipeAdapter adapterViewPager;
private FirstFragmentSwipe fragment1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v(TAG, "onCreate");
setContentView(R.layout.main_activity_test);
ViewPager vpPager = (ViewPager) findViewById(R.id.viewpager);
adapterViewPager = new SecondActivitySwipeAdapter(getSupportFragmentManager());
vpPager.setAdapter(adapterViewPager);
fragment1 = (FirstFragmentSwipe) adapterViewPager.getRegisteredFragment(vpPager.getCurrentItem());
fragment1.setTextViews(1,2,3,4,5);
}
...
}
SecondActivitySwipeAdapter
public class SecondActivitySwipeAdapter extends FragmentStatePagerAdapter {
SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
private static int NUM_ITEMS = 2;
private FragmentManager mFragmentManager;
public SecondActivitySwipeAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
mFragmentManager = fragmentManager;
}
// Returns total number of pages
#Override
public int getCount() {
return NUM_ITEMS;
}
// Returns the fragment to display for that page
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return FirstFragmentSwipe.newInstance();
case 1:
return SecondFragmentSwipe.newInstance();
default:
return null;
}
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
}
FirstFragmentSwipe
public class FirstFragmentSwipe extends Fragment {
private TextView avg1;
private TextView avg2;
private TextView avg3;
private TextView avg4;
private TextView avg5;
public static FirstFragmentSwipe newInstance(){
return new FirstFragmentSwipe();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.swipelayout1, container, false);
avg1 = view.findViewById(R.id.pwrAvgNmbview1);
avg2 = view.findViewById(R.id.pwrAvgNmbview2);
avg3 = view.findViewById(R.id.pwrAvgNmbview3);
avg4 = view.findViewById(R.id.pwrAvgNmbview4);
avg5 = view.findViewById(R.id.pwrAvgNmbview5);
return view;
}
public void setTextViews(int avg1, int avg2, int avg3, int avg4, int avg5){
this.avg1.setText(Integer.toString(avg1));
this.avg2.setText(Integer.toString(avg2));
this.avg3.setText(Integer.toString(avg3));
this.avg4.setText(Integer.toString(avg4));
this.avg5.setText(Integer.toString(avg5));
}
}
The second fragment is basically the same as fragment for the moment. I am using some ideas found by googling. The last line of the onCreate method make the app crash. Thanks for you precious help.
So the problem here is that registeredFragments doesn't have the fragments instantiated yet.
First you can check if fragment1 is null to prevent crashes.
Furthermore you'd rather put initialization methods in getItem() of adapter or in onViewCreated() of the fragment and do some updates in later lifecycle methods if needed.
I'm pretty new at Android, so I've already seen similar questions like mine, but I still can't send a Text to another fragment. I get this following error:
java.lang.NullPointerException: Attempt to invoke virtual method '
Here's the code, for better understanding...
FragOne
public class FragOne extends Fragment {
SendDados enviar;
String NumPessoas;
public interface SendDados{
void setdados(String numPessoas);
}
#Override
public void onAttach(Activity activity){
super.onAttach(activity);
try{ enviar=(SendDados)activity;
}catch (ClassCastException e){
throw new ClassCastException("erro");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.reserva_layout, container, false);
final TextView numero=(TextView)rootView.findViewById(R.id.qtdPessoas);
reservar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
NumPessoas= numero.getText().toString();
enviar.setdados("1");
}
});
FragTwo
public class FragTwo extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.confirm_reserva_layout, container, false);
numeroPessoas=(TextView)rootView.findViewById(R.id.numPessoas);
return rootView;
}
public void UpdateDados(String numPessoas)
{
numeroPessoas.setText(numPessoas);
}
Activity
public class MenuActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener,ReservaFragment.SendDados {
#Override
public void setdados(String numPessoas) {
ConfirmaReservaFragment cf= (ConfirmaReservaFragment)getSupportFragmentManager().findFragmentById(R.id.confirmaReserva);
cf.UpdateDados(numPessoas);
}
What I need to do is this, when I click the button, the textView from FragOne, must be copied to FragTwo, what am I doing wrong here? I always get this error:
java.lang.NullPointerException: Attempt to invoke virtual method '
I appreciate any help.
Since we are talking about simple TextViews, copying the whole TextView to send it to another fragment seems too complicated for a simple job. Just send a String and display the text inside a new TextView inside FragTwo.
I recommend reading this link for passing parameters to fragments before their construction.
If you insist on passing TextViews as parameters to fragments then you are going to have to find a way to serialize TextViews (I don't think they implement Parcelable) and that won't be a simple job.
Regarding your code:
Names of objects start with small caps (first snippet).
Names of methods start with small caps (last snippet).
Use instanceof in onAttach (first snippet).
I don't see what ConfirmaReservaFragment is?
Also I really really recommend you type your code in English.
Fragments should comunicate through an activity so i will post you a short example of how to correctly send data from one fragment to another using a host activity:
First we will use this layout named host activity layout with a framelayout as a parent called host_fragment_container :
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/host_fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
now we are going to load our host activity and set this layout as a content view and create a basic method to change fragments on this frame layout :
public class HostActivity extends AppCompatActivity
implements TextViewContainerFragment.textViewClickListener{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.host_activity_layout);
}
private void switchFragment(Fragment fragment) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.host_fragment_container, fragment)
.commit();
}
}
Now lets create our first fragment (the one who will send the text) :
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:id="#+id/text_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
we will use this same xml file for both sender and receiver fragments
public class TextViewContainerFragment extends Fragment {
public interface textViewClickListener {
void onTextViewClicked(String value);
}
private textViewClickListener mActivityCallback;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.text_view_container_fragment, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
final TextView textView = (TextView) view.findViewById(R.id.text_view);
//search the view by id and cast it into a text view the set it on click lsitener
textView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// now if the cast was successful the activity callback will be valid and ready to use
// but we are going to check if its valid anyways
if (mActivityCallback != null) {
mActivityCallback.onTextViewClicked(textView.getText().toString());
}
}
});
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
// if context is extracted from an activity
// that means its safe to cast
if (context instanceof Activity) {
mActivityCallback =
(textViewClickListener) context;
}
}
// factory method
public static TextViewContainerFragment newInstance() {
return new TextViewContainerFragment();
}
}
now that we have our interface on the fragment we will implement it on the host activity to listen for callbacks & its going to call a sencond fragment ot display the sent text :
public class HostActivity extends AppCompatActivity
implements TextViewContainerFragment.textViewClickListener{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.host_activity_layout);
if (savedInstanceState == null) {
switchFragment(TextViewContainerFragment.newInstance());
}
}
private void switchFragment(Fragment fragment) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.host_fragment_container, fragment)
.commit();
}
#Override
public void onTextViewClicked(String value) {
switchFragment(TextReceiverFragment.newInstance(value));
}
}
Here is the code for the receiver fragment (older fragment will be replaced for this one) :
public class TextReceiverFragment extends Fragment {
public static final String ARG_TEXT_RECEIVED_FROM_ANOTHER_FRAGMENT = "text";
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.text_view_container_fragment, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
((TextView) view.findViewById(R.id.text_view)).setText(getArguments() != null ?
getArguments().getString(ARG_TEXT_RECEIVED_FROM_ANOTHER_FRAGMENT)
: "No text was sent from another fragment");
}
public static TextReceiverFragment newInstance(String text) {
TextReceiverFragment fragment = new TextReceiverFragment();
Bundle argument = new Bundle();
argument.putString(ARG_TEXT_RECEIVED_FROM_ANOTHER_FRAGMENT,
text);
fragment.setArguments(argument);
return fragment;
}
}
If you really want to copy the textview from Fragment 1 to Fragment 2. I suggested you to send the config data (e.g. the text, clicked, color) of the textview instead of the whole object. As the response from Spidey ,sending the widget to other fragment will be a trouble.
To facilitate your work, A textview config model should be used to send the config data of the textview.
public class TextViewConfig implements Parcelable {
private String text;
private boolean selected;
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.text);
dest.writeByte(this.selected ? (byte) 1 : (byte) 0);
}
public TextViewConfig() {
}
protected TextViewConfig(Parcel in) {
this.text = in.readString();
this.selected = in.readByte() != 0;
}
public static final Parcelable.Creator<TextViewConfig> CREATOR = new Parcelable.Creator<TextViewConfig>() {
#Override
public TextViewConfig createFromParcel(Parcel source) {
return new TextViewConfig(source);
}
#Override
public TextViewConfig[] newArray(int size) {
return new TextViewConfig[size];
}
};
public String getText() {
return text;
}
public void setText(String pText) {
text = pText;
}
public boolean isSelected() {
return selected;
}
public void setSelected(boolean pSelected) {
selected = pSelected;
}
}
Since the model class can be implemented as Parcelable easily, you can use it to send the data of the textview. And then you can use the answer from Juan Hurtado to practice the communication between the fragments by sending the config data.
let's supose u wants to got to the fragment two from fragment one with text "hello" by a click event on fragment one,
your code look like this,
class FragOne extends Fragment{
onCreateView(){
.
.
<your view>.setOnClickListener(new OnClickListener(){
#cverride
onClick(){
Bundle bundle=new Bundle();
bundle.putString("msg","<ur text will gose here which u wants to send to fragment two>");
.
.
.
//now move to the fragment two here
FragTwo fragTwo=new FragTwo();
fragTwo.setArgument(bundle);
FragmentManager fragmentManager=getSupportFragmentManager();
fragmentManager.beginTransaction().add(<ur root layout is>,fragmentTwo).commit();
}
});
}
}
Now in ur Fragmnet Two,
class FragTwo extends Fragment{
onCreateView(){
.
.
//get text which is send by fragment one
Bundle bundle=new Bundle();
String text=bundle.getString("msg");//this is ur text which is send by fragment one
}
}
Hope this will help u,
My EditText is in my fragment named : EquationsCalculFragment.java
I want to recover the value in my fragment named : EquationsResultat.java
I have two NullPointerException with no apparent reasons (see the comments directly in the code).
NB : For the error in the EquationsResultsFragment, I tried to cast with String.valueOf(), with Float.parseFloat(), with the two combined... but no one worked.
EquationsCalculFragment.java
public class EquationsCalculFragment extends Fragment {
private ViewPager viewPager;
private EditText champ_a;
private EditText champ_b;
private String a;
private String b;
public float getA_equa_2nd() {
return Float.parseFloat(a);
}
public float getB_equa_2nd() {
return Float.parseFloat(b);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_equations_calcul, container, false);
viewPager = (ViewPager) getActivity().findViewById(R.id.viewpager);
champ_a = (EditText) view.findViewById(R.id.equa_2nd_a);
champ_b = (EditText) view.findViewById(R.id.equa_2nd_b);
Button button = (Button) view.findViewById(R.id.btn_equations_resultats);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
b = champ_b.getText().toString();
a = champ_a.getText().toString();
EquationsResultatFragment eqResFr = new EquationsResultatFragment();
eqResFr.getResultat(getA_equa_2nd(), getB_equa_2nd()); //NullPointerException happens here
//at com.example.slabre.applitest.EquationsCalculFragment$1.onClick(EquationsCalculFragment.java:60)
viewPager.setCurrentItem(1, true);
}
});
return view;
}
}
EquationsResultat.java
public class EquationsResultatFragment extends Fragment {
private TextView results;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_equations_resultat, container, false);
results = (TextView) view.findViewById(R.id.equa_2nd_resultat);
return view;
}
public void getResultat(float a, float b) {
results.setText(String.valueOf((a*a)+(2*a*b)+(b*b))); // NullPointerException happens here
// at com.example.slabre.applitest.EquationsResultatFragment.getResultat(EquationsResultatFragment.java:29)
}
}
Hope you can help me, I think this is not a big problem.
Parent Activity : TabFragment.java (yes my app si working with a TabLayout and ViewPager)
public class TabFragment extends Fragment {
public static TabLayout tabLayout;
public static ViewPager viewPager;
public static int int_items = 3 ;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
/**
*Inflate tab_layout and setup Views.
*/
View x = inflater.inflate(R.layout.tab_layout,null);
tabLayout = (TabLayout) x.findViewById(R.id.tabs);
viewPager = (ViewPager) x.findViewById(R.id.viewpager);
/**
*Set an Apater for the View Pager
*/
viewPager.setAdapter(new MyAdapter(getChildFragmentManager()));
tabLayout.post(new Runnable() {
#Override
public void run() {
tabLayout.setupWithViewPager(viewPager);
}
});
return x;
}
class MyAdapter extends FragmentPagerAdapter{
public MyAdapter(FragmentManager fm) {
super(fm);
}
/**
* Return fragment with respect to Position .
*/
#Override
public Fragment getItem(int position)
{
switch (position){
case 0 : return new EquationsCalculFragment();
case 1 : return new EquationsResultatFragment();
case 2 : return new EquationsInfosFragment();
}
return null;
}
#Override
public int getCount() {
return int_items;
}
/**
* This method returns the title of the tab according to the position.
*/
#Override
public CharSequence getPageTitle(int position) {
switch (position){
case 0 :
return "Calcul";
case 1 :
return "Résultats";
case 2 :
return "Infos";
}
return null;
}
}
}
First of all, you cannot directly communicate between different fragments. You need to go through your container activity for it.
Declare a listener interface through which your fragment will communicate with your container activity. Attach that listener to your EquationsCalculFragment. Your container activity should implement that listener.
Now when you EquationsCalculFragment wants to communicate with EquationsResultatFragment you notify your container activity using that listener. In the container activity, when you get the listener callback, grab your EquationsResultatFragment fragment instance using findFragmentById(int id) or findFragmentByTag(String tag) and check if it is already added to your container activity. If it is, then call any public method of EquationsResultatFragment fragment, using that grabbed EquationsResultatFragment fragment instance.
Check out this link for more details and sample code.
EquationsResultat's getResultat is called when you click on the EquationsCalculFragment's button, and should set EquationsResultat's TextView (results) text. Problem is, results is set on EquationsResultat's onCreateView, and it seems this method has no been called yet, and therefore results is still null.
Post your activitie's code, it will be easier to help you knowing when you are attaching the fragments, etc.
Try this!!
public void getResultat(float a, float b) {
results.setText(((a * a) + (2 * a * b) + (b * b))+"");
}