Update fragment data after newInstance() - android

Basically I have my fragment
public class FragmentDashboard extends Fragment {
public static FragmentDashboard newInstance() {
FragmentDashboard frag = new FragmentDashboard();
return frag;
}
public void updateData(Object object){
myTextView.setText(object.getField);
//update views with object values
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_dashboard, container, false);
myTextView = (TextView) view.findViewById(R.id.myTextView );
}
}
Then in my activity I need to update data I do:
FragmentDashboard fragmentDashboard = (FragmentDashboard) getSupportFragmentManager().findFragmentById(R.id.layFragment);
fragmentDashboard.updateData(myObject)
This works good if I am making the call on my activity after the Fragment has been displayed (like from an asynctask on completed).
The problem I am running into is having to run the updateData right after I add the fragment on my activity's onCreate().
final FragmentTransaction ft = fragmentManager.beginTransaction();
FragmentDashboard fragmentDashboard = FragmentDashboard.newInstance();
ft.replace(R.id.layFragment, fragmentDashboard);
ft.commit();
fragmentDashboard.updateData(myObject)
Running this I get a NPE because the fragment's onCreateView hasn't been run yet and the myTextView is not initialized
I don't want to add parameters on newInstance as I'd like to avoid making the object as parcelable. Any ideas ?

You can use a local field to contains your data and use it in your onCreateView method :
public class FragmentDashboard extends Fragment {
private Object myData=null;
private TextView myTextView = null;
public static FragmentDashboard newInstance() {
FragmentDashboard frag = new FragmentDashboard();
return frag;
}
public void updateData(Object object){
myData = object;
if(myTextView != null)
myTextView.setText(myData);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_dashboard, container, false);
myTextView = (TextView) view.findViewById(R.id.myTextView );
if(myData != null && myTextView != null)
myTextView.setText(myData);
}
}

It isn't a good practice to set Data like updateData(Object ) . Make your model class parcelable or serializable and pass it in putExtra and get it in onViewCreated.
public static FragmentDashboard newInstance(Object object) {
Bundle args = new Bundle();
args.putParcelable("yourModelClass",object);
FragmentDashboard frag = new FragmentDashboard();
frag.setArguments(args);
return frag;
}
And in onViewCreated
if(getArguments != null)
yourModelClassObject = getArguments().getParcelable("yourModelClass");
if(yourModelClassObject != null)
textView.setText(yourModelClassObject.getField());
I have written code orally . May contain mistakes.

Related

Android pass View as an object to fragment

I'm more googling to find how can i pass simple view as an object to fragment, but i can't.
for example in MainActivity i have simple view as :
TextView text = (TextView) findviewById(R.id.tv_text);
now i want to pass that to fragment. this below code is my attach Fragment on MainActivity
MainActivity :
public void attachFragment() {
fts = getActivity().getFragmentManager().beginTransaction();
mFragment = new FragmentMarketDetail();
fts.replace(R.id.cardsLine, mFragment, "FragmentMarketDetail");
fts.commit();
}
and this is my Fragment:
public class FragmentMarketDetail extends Fragment implements ObservableScrollViewCallbacks {
public static final String SCROLLVIEW_STATE = "scrollviewState";
private ObservableScrollView scrollViewTest;
private Context context;
private int scrollY;
public static FragmentMarketDetail newInstance() {
FragmentMarketDetail fragmentFirst = new FragmentMarketDetail();
return fragmentFirst;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_online_categories, container, false);
scrollViewTest = (ObservableScrollView) view.findViewById(R.id.scrollViewTest);
scrollViewTest.setScrollViewCallbacks(this);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = getActivity().getBaseContext();
}
}
It wouldn't be good practise to pass a view that way. If you want to access the view in your activity from within your fragment class, use getActivity() to access the activity to which your fragment is attached, and from there you find your TextView.
TextView text = (TextView) getActivity().findViewById(R.id.tv_text);
How about adding a set function in your custom fragment
e.g.
public void setTextView(TextView tv){
this.tv = tv
}
and then calling it after
mFragment = new FragmentMarketDetail();
mFragment.setTextView(textView)
Find fragment by tag and invoke a function on it:
mFragment = (FragmentMarketDetail ) getActivity().getFragmentManager().findFragmentByTag(FragmentMarketDetail .class.getSimpleName());
mFragment.passTextView(textView);
Of course fragment must be added to backstack.

Getting NullPointerException while passing string between two Fragments [duplicate]

This question already has answers here:
How to pass values between Fragments
(18 answers)
Closed 6 years ago.
I have Two Dynamic Fragments associated with one activity, I am trying to pass one Text from First Fragment to Second Fragment using Bundle, but I am getting Null Pointer Exception. Is it the right way to pass String between two fragments? Below is my code :
First Fragment
public class FirstFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.content_main, container, false);
String text = "GetThisStringInSecondFragment";
TextView txtView = null;
txtView = (TextView) view.findViewById(R.id.firstfragmenttext);
txtView.setText(text);
Bundle bundle = new Bundle();
bundle.putString("HI", text);
return view;
}
}
Second Fragment
public class SecondFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.content_secondmain,
container, false);
TextView txtView = null;
txtView = (TextView) view.findViewById(R.id.secondfragmenttext);
Bundle bundle = this.getArguments();
String myInt = bundle.getString("HI");
txtView.setText(myInt);
return view;
}
}
Activity
public class MainActivity extends AppCompatActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnLoad = (Button) findViewById(R.id.btn_load);
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
FirstFragment hello = new FirstFragment();
fragmentTransaction.add(R.id.fragment_container, hello, "HELLO");
fragmentTransaction.commit();
FragmentManager fragmentManager2 = getFragmentManager();
FragmentTransaction fragmentTransaction2 = fragmentManager2.beginTransaction();
SecondFragment hello2 = new SecondFragment();
fragmentTransaction2.add(R.id.fragment_container, hello2, "HELLO");
fragmentTransaction2.commit();
}
};
btnLoad.setOnClickListener(listener);
}
}
You are doing getArguments in second fragment but where are you sending those arguments from first fragment. You can use Interface here and define it in activity. From activity, you can use setArgument() method for second fragment.
check the following link for more detailed information and steps to do that.
https://developer.android.com/training/basics/fragments/communicating.html

Pass String Array from one fragment to another

I am Using one String [] to display in ListView of fragmentone and pass String[] to fragmentTwo which has listView. my tried Codes below,
MainActivity:
public class MainActivity extends FragmentActivity implements ListInterface {
private FragmentOne fragmentOne;
private FragmentTwo fragmentTwo;
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
setContentView (R.layout.activity_main);
fragmentOne = new FragmentOne ();
fragmentTwo = new FragmentTwo ();
FragmentManager fragmentManager = getSupportFragmentManager ();
android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction ();
fragmentTransaction.add (R.id.frame_one,fragmentOne);
fragmentTransaction.add (R.id.frame_two , fragmentTwo);
fragmentTransaction.commit ();
}
#Override
public void getValue (String[] s) {
fragmentTwo.setValue (s);
}}
FragmentOne:
public class FragmentOne extends Fragment {
private ListView listView;
private ListInterface listInterface;
String [] listData = {"Dhana","Rahul","Strobs","Uday","Selvi"};
#Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate (R.layout.fragment_one,container,false);
listView = (ListView)view.findViewById (R.id.lst_view);
ArrayAdapter adapter = new ArrayAdapter (getActivity (),R.layout.fragment_one,listData);
listView.setAdapter (adapter);
return view;
}
#Override
public void onAttach (Context context) {
super.onAttach (context);
if(context instanceof ListInterface){
listInterface =(ListInterface)context;
listInterface.getValue (listData);
}else{
throw new ClassCastException (context.toString ()+"mess ");
}
}}
FragmentTwo:
public class FragmentTwo extends Fragment {
private ListView listView;
#Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate (R.layout.fragment_two,container,false);
listView = (ListView)view.findViewById (R.id.lst_view_two);
return view;
}
public void setValue (String [] value){
ArrayAdapter adapter = new ArrayAdapter (getActivity (),R.layout.fragment_two,value);
listView.setAdapter (adapter);
}}
ListInterface:
public interface ListInterface {
public void getValue (String [] s);}
i tried my codes it show
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference
FragmentTwo.setValue(FragmentTwo.java:27)
MainActivity.getValue(MainActivity.java:31)
FragmentOne.onAttach(FragmentOne.java:37)
You can set the data in this way.
public static BuyerToyFragment newInstance(String yourText) {
FragmentOne fragment = new FragmentOne ();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, yourText);
fragment.setArguments(args);
return fragment;
}
NOw in fragmentOne you need to get data like this.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
String myStringData = getArguments().getString(ARG_PARAM1);
}
}
and in your MainActivity you can set data like this.
// you can add string array as well. i dont remember the tag exactely. i its
//like putStingArray() but you need to check it yourself
fragmentOne = new FragmentOne ().newInstance("Your data goes here");
you need to do the same for fragment 2
I don't really understand the role of your list interface.
I don't really understand neither why you make your setValue and getValue call statically...
1/The easiest way is to store your list in your activity and then access it from the fragment, for exemple in onViewCreated.
Activity:
public String[] getMyList() {
return mMyList;
}
You will also need to do the setter to set the list from another fragment.
Access your list from the fragment:
String[] listFromActivity = ((MainActivity) getActivity()).getMyList();
2/A cleaner way could be to pass your list as an argument to your fragment.
In activity :
FragmentOne frO = new FragmentOne();
Bundle bundle = new Bundle();
bundle.putStringArray(mMyList, "my_list_key");
frO.setArguments(bundle);
In fragment :
String[] listFromActivity = getArguments().getStringArray("my_list_key");
The solution 1 is more easy if you want to update your list, if your list won't change the solution 2 is cleaner.

How can I pass Data from one fragment to another one? [duplicate]

This question already has answers here:
Passing data from one fragment to another
(4 answers)
Closed 6 years ago.
Hello i am working with fragment to pass data from one fragment to another with My Model object like Student with (id,name),but i cant able to pass and view data in second fragment from pass first fragment.
use static variable
if you use view pager then update fragment when a fragment is change
In Fragment transaction send data in constructor when when a fragment is replace
You can pass data from one fragment to other using constructor or using setArgument
Using Constructor
ModelStudent student = new ModelStudent(1, "ABCD");
FragmentTwo fragmentTwo = new FragmentTwo(student);
Using setArgument
FragmentTwo fragmentTwo = new FragmentTwo();
Bundle bundle = new Bundle();
bundle.putSerializable("STUDENT", student);
fragmentTwo.setArguments(bundle);
Fragment 1
public class FragmentOne extends Fragment {
private View rootView;
private Button btnPassData;
public FragmentOne() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.frgament_one, container, false);
btnPassData = (Button) rootView.findViewById(R.id.btnPassData);
btnPassData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ModelStudent student = new ModelStudent(1, "ABCD");
// first way
//FragmentTwo fragmentTwo = new FragmentTwo(student);
// or second way
FragmentTwo fragmentTwo = new FragmentTwo();
Bundle bundle = new Bundle();
bundle.putSerializable("STUDENT", student);
fragmentTwo.setArguments(bundle);
FragmentManager fm = getActivity().getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.content, fragmentTwo).commit();
}
});
return rootView;
}
}
Fragment 2
public class FragmentTwo extends Fragment {
private View rootView;
private ModelStudent modelStudent;
private TextView txtStudent;
public FragmentTwo() {
}
public FragmentTwo(ModelStudent modelStudent) {
this.modelStudent = modelStudent;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.frgament_two, container, false);
txtStudent = (TextView) rootView.findViewById(R.id.txtStudent);
Bundle bundle = getArguments();
ModelStudent student = (ModelStudent) bundle.getSerializable("STUDENT");
txtStudent.setText("RollNo: " + student.getRollNo() + " Name: " + student.getName());
return rootView;
}

Pass value to fragment

I am creating a app in which i wanna slide images,so for that i will be using view pager.For the image i have created a fragment which will display the images.
Code
public class ImageSwitcher extends BaseFragment {
private ImageView imageView;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.image_switcher_fragment, container, false);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initialize();
}
private void initialize() {
imageView = (ImageView) view.findViewById(R.id.image_switcher);
imageView.setBackgroundResource("");
}
Now at this line
imageView.setBackgroundResource("");
the image will come from the int array which i will pass.
My doubt is
How will i pass int values to fragments
Is there any better way to use image switcher
Pass your Integer value from your fragment using Bundle as below:
Fragment fragment = new Fragment();
Bundle bundle = new Bundle();
bundle.putInt("id", id);
fragment.setArguments(bundle);
Access the value in Fragment onCreateView method:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
int m_id=getArguments().getInt("id");
return inflater.inflate(R.layout.fragment, container, false);
}
class MyFragment extends Fragment {
private static final String ARG_BG_RES="ARG_BG_RES";
public Fragment() {}
static public newInstance(String backgroundRes) {
Bundle args = new Bundle();
args.putExtra(ARG_BG_RES, backgroundRes);
Fragment fragment = new Fragment();
fragment.setArguments(args);
return f;
void whereYouNeedIt() {
String backgroundRes = getArguments().getStringExtra(ARG_BG_RES);
...
}
}
From outside:
MyFragment f = MyFragment.newInstance("black");
Don't omit public Fragment() {} it's required by the OS.
You can use bundle to pass values to the fragment or during initializing pass values via a custom constructor
For background resource if you are not changing images based on some logic in code, apply it via XML background and a drawable :-/

Categories

Resources