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.
Related
I have a tablayout (with 3 tabs) with viewpager and fragments.
I m trying to send the parsed Json data from MainActivity( When searchview data submitted ) to show in the textview of tabs fragments
See this Image link
The data is succesfully parsing but textview with data(in first tab) is not showing unless scrolled to 3rd tab
//Passing data from MainActivity
public String getMyData() {
return meaning;
}
//Setting value to textview from Fragment
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v=inflater.inflate(R.layout.fragment_meaning, container, false);
MainActivity mainActivity= (MainActivity) getActivity();
assert mainActivity != null;
String data= mainActivity.getMyData();
TextView textView=v.findViewById(R.id.textVIew);
textView.setText(data);
return v;
}
Want to able to show data changes instantly as it is parsed, instead of scrolling to 3rd tab to see changes
Here are some steps that might help you.
On the ViewPager adaptor you have created, make the fragment objects. like below
FragmentOne fragOne; // this should be global
On the viewPager adaptor, do some thing like this,
fragOne = new FragmentOne() // whatever your implementation is.
Then after fetching the data from the server,
if ( fragOne != null ) {
fragOne.setValueOnView( " your data to be passed" );
}
and on the FragmentOne, create a function called setValueOnView
void setValueOnView(String yourString) {
v.findViewById(R.id.textVIew).setText(yourString);
}
And one more thing, while initializing the fragment onCreateView, create an object of View
View v; // global variable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
v=inflater.inflate(R.layout.fragment_meaning, container, false);
Use this approach for other fragments as well
Inside getItem() method in ViewPager class use Fragment constructors with String parameter
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
FragmentOne tab1 = new FragmentOne("string parameter");
return tab1;
case 1:
FragmentTwo tab2 = new FragmentTwo("string parameter");
return tab2;
case 2:
FragmentThree tab3 = new FragmentThree("string parameter");
return tab3;
default:
return null;
}
}
Inside your Fragment:
public FragmentOne(String stringParameter) {
yourLocalVariable = stringParameter; // yourLocalVariable is declared inside Fragment class;
//now you can setText() for your TextView inside onViewCreated()
}
Of course you pass your String from MainActivity to ViewPager like you did earlier.
Use Observer
public class FragmentObserver extends Observable {
#Override
public void notifyObservers() {
setChanged(); // Set the changed flag to true, otherwise observers won't be notified.
super.notifyObservers();
}
}
Activity:
public class MyActivity extends Activity {
private MyAdapter mPagerAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.my_activity);
ViewPager pager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new MyAdapter();
pager.setAdapter(mPagerAdapter);
}
private void updateFragments() {
mPagerAdapter.updateFragments();
}
}
Viewpager adapter
public class MyAdapter extends FragmentPagerAdapter {
private Observable mObservers = new FragmentObserver();
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
mObservers.deleteObservers(); // Clear existing observers.
Fragment fragment = new MyFragment();
if(fragment instanceof Observer)
mObservers.addObserver((Observer) fragment);
return fragment;
}
public void updateFragments() {
mObservers.notifyObservers();
}
}
Your Fragment
public class MyFragment extends Fragment implements Observer {
/* Fragment related stuff... */
#Override
public void update(Observable observable, Object data) {
View root = getView();
// Update your views here.
}
}
You will get data to update method even your fragment already loaded
I'm passing value from adapter to fragment class,
Here adapter class,
rbFolder.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
if(selected != null)
{
selected.setChecked(false);
String meee = data.get(position).getTypeId();
System.out.println("*******so*inside********"+meee);
}
rbFolder.setChecked(true);
String so = data.get(position).getTypeId();
System.out.println("*******so*********"+so);
selected = rbFolder;
System.out.println("********selected*******"+selected);
Fragment homepage = new Fragment();
FragmentTransaction fragmentManager =((FragmentActivity)context).getSupportFragmentManager()
.beginTransaction();
Bundle bundle=new Bundle();
bundle.putString("name", so); //key and value
System.out.println("*****venki***meee*******"+so);
homepage.setArguments(bundle);
// fragmentManager.replace(R.id.content_frame, homepage);
fragmentManager.addToBackStack(null);
fragmentManager.commit();
}
});
In this, putstring working well but in my fragemt class i didnt receive values. I'm trouble in this place.
Here Fragmnet class,
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (rootview != null) {
ViewGroup parent = (ViewGroup) rootview.getParent();
if (parent != null)
parent.removeView(rootview);
}
try {
rootview = inflater.inflate(R.layout.homepage, container, false);
} catch (InflateException e) {
/* map is already there, just return view as it is */
}
Here I get values from adapter but this is not working,
Bundle bundle = ((Activity)context).getIntent().getExtras();
if (bundle != null)
{
String strtext=getArguments().getString("name");
System.out.println("*******strtext*********"+strtext);
}
return rootview;
}
First of All you have to call your HomeFragment() instead of fragment like that
Fragment homepage = new HomeFragment();
FragmentTransaction fragmentManager =((FragmentActivity)context).getSupportFragmentManager()
.beginTransaction();
Bundle bundle=new Bundle();
bundle.putString("name", so); //key and value
homepage.setArguments(bundle);
fragmentManager.replace(R.id.content_frame, homepage);
fragmentManager.addToBackStack(null);
fragmentManager.commit();
When you want to get value inside home fragment then
if( getArguments() != null)
String strtext = getArguments().getString("name");
follow steps one by one, copy Context context;
List rowItems;
onItemClickListner onItemClickListner; and pest into your adapter
then copy two constructor methods and then pest on item click method to pass data to fragment.
in your fragment class set adapter item on click listener code in this way...
madapter.setOnClickListener(new MyListAdapterTemp.onItemClickListner() {
#Override
public void onClick(String str) {
}
});
Context context;
List<String> rowItems;
onItemClickListner onItemClickListner;
public MyListAdapterTemp(Context context, List<String> items) {
this.context = context;
this.rowItems = items;
}
public void setOnClickListener(onItemClickListner onItemClickListner) {
this.onItemClickListner = onItemClickListner;
}
holder.txtDesc.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onItemClickListner.onClick(rowItems.get(position).toString().trim().toUpperCase());
}
});
this method works fine on my app and for activity to fragment , fragment to activity we can pass data using interface but not this
way this is best and proper way to perform this type of operations.
Fragment homepage = new Fragment();
this is supposed to be your Fragment class name -
Fragment homepage = new MyFragment();
And Your Fragment be like -
public class MyFragment extends Fragment {
#Override
public void onCreate(...) {
Bundle b = getArguments(); //To get extras from Fragment
}
}
Other than that,
Bundle bundle = ((Activity)context).getIntent().getExtras();
This is used for an Activity. For Fragment you have to use getArguments()
I am trying to send data from Fragment A to Fragment B of NAVIGATION Drawer on Button click.I tried with bundle and intent but both of them are not working.
In Fragment A I have editText and button when I click the data is passed to another fragment.
In Fragment B there is textView where editText data is going to show but I am not getting a way to communicate between fragment in Navigation Drawer
When lauching Fragment from first fragment
Bundle bundle = new Bundle();
bundle.putString("key", YOUR_EDITVIEW_TEXT);
Fragment fragment = new SECONDFragment();
if (arguments != null) {
fragment.setArguments(arguments);
}
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.replace(R.id.container, fragment);
ft.addToBackStack("");
ft.commit();
And in SecondFragment
private String mData;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mData = getArguments().getString("key");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.YourLayout, container, false);
TextView text = (TextView) rootView.findViewById(R.id.yourTextView);
text.setText(mData);
return rootView;
}
Let your Activity to do the communication.
Take a public static variable in your MainActivity from where you're controlling the Fragment replaces of the navigation drawer. When you click the button in FragmentA store the value in the EditText to the public static variable of your MainActivity. Then when FragmentB is loaded check if the public static value is null or not. If not null place the value of that variable to your desired position.
This is not an elegant way for passing values between fragments, but in your case it'll work just fine.
If you're looking for how to pass values from one fragment to another, try something like this.
// To pass some value from FragmentA
FragmentB mFragmentB = new FragmentB();
Bundle args = new Bundle();
args.putString("VALUE", value);
mFragmentB.setArguments(args);
And from your FragmentB use the code to get the values passed.
Bundle args = getArguments();
int value = args.getString("VALUE");
1- create Application Class
public class MyApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
mInstance = this;
}
private static MyApplication mInstance;
public static synchronized MyApplication getInstance() {
return mInstance;
}
String mytext;
public String getMytext() {
return mytext;
}
public void setMytext(String mytext) {
this.mytext = mytext;
}
}
2- app name tag in manifast
<application
android:name=".MyApplication"
.......
3- from first Fragment
MyApplication.getInstance().setMytext("your text here");
4- from other Fragment
String text=MyApplication.getInstance().getMytext();
//Put the value
YourNewFragment ldf = new YourNewFragment ();
Bundle args = new Bundle();
args.putString("KEY", "VALUE");
ldf.setArguments(args);
//Inflate the fragment
getFragmentManager().beginTransaction().add(R.id.container, ldf).commit();
In onCreateView of the new Fragment:
//Retrieve the value
String value = getArguments().getString("KEY");
I'm having trouble refreshing an array adapter. When I'm testing the program on a phone it works well and refreshes perfectly when switching through fragments. The problem comes when I'm using a tablet and both fragments are up at once.
Here's my fragment code:
public class HistoryFragment extends Fragment {
private ArrayList<String> history = new ArrayList<String>();
private ArrayAdapter<String> arrayAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle data = getArguments();
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.history, container, false);
ListView view = (ListView) v.findViewById(R.id.list);
if(data != null){
history = data.getStringArrayList("history");
}
arrayAdapter = new ArrayAdapter<String>(
getActivity(),
android.R.layout.simple_list_item_1, history);
view.setAdapter(arrayAdapter);
return v;
}
public void setHistory(ArrayList<String> history) {
history.addAll(history);
arrayAdapter.notifyDataSetChanged();
}
}
Here's my activity code:
public class MainActivity extends Activity implements historyClickListener{
public static ArrayList<String> history = new ArrayList<String>();
CalcFragment mCalcFragment = new CalcFragment();
HistoryFragment mHistFragment = new HistoryFragment();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (findViewById(R.id.container) != null) {
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.container, mCalcFragment);
fragmentTransaction.commit();
}
}
#Override
public void sendHistory(ArrayList<String> history){
Fragment hf = getFragmentManager().findFragmentById(R.id.historyfrag);
if(hf != null){
mHistFragment.setHistory(history);
}else{
Bundle data = new Bundle();
data.putStringArrayList("history", history);
mHistFragment.setArguments(data);
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.container, mHistFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
}
The sendHistory is an interface method in a calculator that help the calculator send the list of equations that have been done. Then in main activity if I'm using a tablet then all it does is setHistory which is a method in the history fragment. I believe the problem is that I'm not using arrayAdapter.notifyDataSetChanged() in the history fragment correctly. Can someone please help. Thanks!
You are setting the new data to a variable of the fragment not to the adapter who is the one who shows the data.
So you can:
Create a new ArrayAdapter with the new data and set it to the listview.
Extend ArrayAdapter, create a method that pass the new Data to the Adapter and then call notifyDataSetChanged().
this.history.addAll(history)? I see the same variable name for parameter and member variable.
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.