I have 2 fragments (tabs) that share some data. When one changes the data, I'd like to have that reflected on the other tab. I researched this on stackOverflow and I think the relevant answer has to do with a .notifyDataSetChanged() call, but I can't make it work. Here's the relevant code...
public class EnterCourseData extends FragmentActivity implements ActionBar.TabListener {
private ViewPager viewPager;
private TabsPagerAdapter mAdapter;
private ActionBar actionBar;
// Tab titles
private String[] tabs = { "Pars", "Handicaps" };
private int courseNumber, teeNumber;
private Tee tee;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_enter_tees);
// Initilization
Intent mIntent = getIntent();
courseNumber = mIntent.getIntExtra("courseNumber",0);
Course course = Global.getCourse(courseNumber);
teeNumber = mIntent.getIntExtra("teeNumber",0);
tee = course.getTee(teeNumber);
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager(), courseNumber, teeNumber);
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Adding Tabs
for (String tab_name : tabs) {
actionBar.addTab(actionBar.newTab().setText(tab_name)
.setTabListener(this));
}
/**
* on swiping the viewpager make respective tab selected
* */
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// on changing the page
// make respected tab selected
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
and further down, here is the onClick method that necessitates the refresh...
public void savePars(View view){
tee.setSlope(Integer.parseInt(((EditText) findViewById(R.id.enter_tee_slope)).getText().toString()));
tee.setRating(Double.parseDouble(((EditText) findViewById(R.id.enter_tee_rating)).getText().toString()));
mAdapter.notifyDataSetChanged();
}
Here is the TabsPagerAdapter...
public class TabsPagerAdapter extends FragmentPagerAdapter {
int courseNumber, teeNumber;
public TabsPagerAdapter(FragmentManager fm, int courseNumber, int teeNumber) {
super(fm);
this.courseNumber = courseNumber;
this.teeNumber = teeNumber;
}
#Override
public Fragment getItem(int index) {
switch (index) {
case 0:
// Par Entry activity
Fragment parFragment = new ParFragment();
Bundle args = new Bundle();
args.putInt(ParFragment.ARG_COURSE_NUMBER, courseNumber);
args.putInt(ParFragment.ARG_TEE_NUMBER, teeNumber);
parFragment.setArguments(args);
return parFragment;
case 1:
// Handicap Entry fragment activity
Fragment hcpFragment = new HandicapFragment();
args = new Bundle();
args.putInt(HandicapFragment.ARG_COURSE_NUMBER, courseNumber);
args.putInt(HandicapFragment.ARG_TEE_NUMBER, teeNumber);
hcpFragment.setArguments(args);
return hcpFragment;
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 2;
}
}
Here is one Fragment...
public class ParFragment extends Fragment {
public static final String ARG_COURSE_NUMBER = "courseNumber", ARG_TEE_NUMBER = "teeNumber";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_par, container, false);
Bundle args = getArguments();
Course course = Global.getCourse(args.getInt(ARG_COURSE_NUMBER));
((TextView) rootView.findViewById(R.id.display_course_name)).setText(course.getName());
Tee tee = course.getTee(args.getInt(ARG_TEE_NUMBER));
((TextView) rootView.findViewById(R.id.display_tee_name)).setText(tee.getTeeName());
((TextView) rootView.findViewById(R.id.enter_tee_slope)).setText(Integer.toString(tee.getSlope()));
((TextView) rootView.findViewById(R.id.enter_tee_rating)).setText(Double.toString(tee.getRating()));
return rootView;
}
}
And here is the other...
public class HandicapFragment extends Fragment {
public static final String ARG_COURSE_NUMBER = "courseNumber", ARG_TEE_NUMBER = "teeNumber";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_handicap, container, false);
Bundle args = getArguments();
Course course = Global.getCourse(args.getInt(ARG_COURSE_NUMBER));
((TextView) rootView.findViewById(R.id.display_course_name)).setText(course.getName());
Tee tee = course.getTee(args.getInt(ARG_TEE_NUMBER));
((TextView) rootView.findViewById(R.id.display_tee_name)).setText(tee.getTeeName());
((TextView) rootView.findViewById(R.id.enter_tee_slope)).setText(Integer.toString(tee.getSlope()));
((TextView) rootView.findViewById(R.id.enter_tee_rating)).setText(Double.toString(tee.getRating()));
return rootView;
}
}
When the button is clicked, I want to save the values and I want these values to show up on the other fragment.
Help a noob out.
Thanks
You need to communicate between fragments, but a fragment cannot directly communicate with other fragment, all the communication should be done through the activity which holds these fragments.
The steps to follow are :
Define an Interface in the fragment where you have implemented the onClickListener (let it be Fragment A)
Implement the Interface in the activity which holds these fragments
In the method overridden, retrieve the fragment instance from the viewpager adapter and deliver a message to Fragment B by calling it's public methods.
refer this answer to retrieve fragment instance from adapter
For more details about Communicating with Other Fragments, refer here
So there is a trick: just let the fragments have the object reference of one another and call the other's function to load data when you handle the onClickListener of the button.
E.g:
protected void onClickListener(View view) {
if (view == myButton) {
// Do other stuffs here
fragment1.reloadData();
}
}
P/S : I re-post this as answer to have the code formatter.
Related
I'm trying to make an Android app with a tabbed form. One tab for Autonomous, and the other for TeleOp.
The TeleOp tab needs to be able to read data from the Autonomous tab, but I'm having trouble passing data from one to the other, while I'm switching from the first tab to the next.
They're both fragments, with one parent, called the Match Form. I'm not entirely sure what to do, so here is my code:
MatchForm.java
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
public TabLayout tabLayout;
public static String startingPos;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_match_form);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
tabLayout = (TabLayout) findViewById(R.id.tabs);
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_match_form, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
public PlaceholderFragment() {
}
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_match_form, container, false);
TextView textView = (TextView) rootView.findViewById(R.id.section_label);
textView.setText(getString(R.string.section_format, getArguments().getInt(ARG_SECTION_NUMBER)));
return rootView;
}
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch(position){
case 0:
AutonomousFragment autonomousFragment = new AutonomousFragment();
return autonomousFragment;
case 1:
TeleopFragment teleopFragment = new TeleopFragment();
return teleopFragment;
}
return null;
}
#Override
public int getCount() {
return 2;
}
}
public void easyToast(String text){
Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
}
AutonomousFragment.java
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
// Make sure that we are currently visible
if (this.isVisible()) {
// If we are becoming invisible, then...
if (!isVisibleToUser) {
sendData();
}
}
}
public void sendData(){
FragmentTransaction ft = getFragmentManager().beginTransaction();
TeleopFragment teleopFragment = new TeleopFragment();
ft.add(R.id.container, teleopFragment);
final Bundle args = new Bundle();
args.putString("startingPos", startingPos);
args.putString("switchPos", switchPos);
args.putString("scalePos", scalePos);
args.putString("autoRun", autoRun);
args.putString("allianceColor", selectedAllianceColor);
teleopFragment.setArguments(args);
ft.commit();
}
TeleopFragment.java
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.teleop_fragment, container, false);
final Bundle bundle = getArguments();
button = (Button)view.findViewById(R.id.submitButton);
if(bundle != null && bundle.containsKey("startingPos")){
startingPos = bundle.getString("startingPos");
easyToast(startingPos);
}
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
easyToast(startingPos);
}
});
return view;
}
There are many ways to pass the data.One easy and efficient way to implement.create a public class in your package.In that class declare your values as static.
public class MyDataClass {
public static String value1;
public static String value2;
}
Now you can access these values from anywhere either in the fragment or activity.
you can pass the values like this
MyDataClass myobj=new MyDataClass();
myobj.value1="Hello";
To fetch the value in another class use
String val=myobj.value1;
You can pass the data from Autonomous Fragment to the parent activity first and then pass it to the Teleop Fragment.
You can use Intents for this.
How to pass values between Fragments
Or use a custom listener to notify the other fragment once the data is sent.
1. Do you really need ViewPager here?
ViewPager is needed if you want to display multiple fragments at the same time. On my opinion, the fragments in ViewPager must be equal and independent. If you want to keep communication between Fragments in ViewPager you can:
Use EventBus or LocalBroadcastManager, etc.;
Cache Fragment inside ViewPager in this way
2. Maybe you need flow?
If you want implement some fragment flow, for example "PickGoods" -> "GoodsCheckout", it is better to use fragment transactions and pass arguments with Bundle. For example, pass selected goods ids from "PickGoods" to "GoodsCheckout".
Note. You can't pass really big amount of data. But it is enough for large set of ids.
3. One more solution.
If your flow belongs to separate activity, which is going to be killed, after final action in flow (it is important to avoid memory leaks) you can use ViewModel attached to activity and store data in it. You can get ViewModels attached to activity from its fragments:
ViewModelProviders.of(getActivity()).get(DataViewModel.class);
HERE IS THE VIDEO:
https://www.youtube.com/watch?v=eush2bY0XlQ&feature=youtu.be&hd=1
So here is the plot :
1) I have a navigation drawer.
2) By Clicking on one of the list item a tab layout (fragment) is inflated .
3) So I get a tab layout (with 6 tabs) working besides navigation drawer i.e navigation drawer and tab_layout can be used simultaneously.
4) Content of every tab is a Different fragement.
Problem :
When I launch the application and click the list-item with the tab fragment the content of the tab_fragment is inflated normally.
But when i click it again all the content of the first and second tab dissappear.
And reappear only when when i swipe till the third tab and swipe back again .
In simple words ,
On Calling the static new Instance method of Tab_Fragment for the first time is works fine .
On Calling it again the content of the first and second tab disappear and reappear
only when I swipe till the 3rd tab and come back.
I know it sounds weird.
Code:
My Tab_Fragment To Create it I call its New Instance From MainActivity.
public class Tab_Activity extends Fragment {
private final Handler handler = new Handler();
public PagerSlidingTabStrip tabs;
private ViewPager pager;
private MyPagerAdapter adapter;
public final static String TAG = Tab_Activity.class.getSimpleName();
public Tab_Activity() {
// TODO Auto-generated constructor stub
}
public static Tab_Activity newInstance() {
return new Tab_Activity();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.tab_layout, container, false);
}
#Override
public void onViewCreated(View v, Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onViewCreated(v, savedInstanceState);
tabs = (PagerSlidingTabStrip) v.findViewById(R.id.tabs);
pager = (ViewPager) v.findViewById(R.id.pager);
adapter = new MyPagerAdapter(getActivity().getSupportFragmentManager());
pager.setAdapter(adapter);
final int pageMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4, getResources()
.getDisplayMetrics());
pager.setPageMargin(pageMargin);
tabs.setViewPager(pager);
tabs.setIndicatorColorResource(R.color.grey);
tabs.setTextColorResource(R.color.black);
}
public class MyPagerAdapter extends FragmentPagerAdapter {
private final String[] TITLES = { " ELECTRONICS ", " IT ", " COMPUTER "," EXTC ", "INSTRUMENTATION"," MCA " };
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public CharSequence getPageTitle(int position) {
return TITLES[position];
}
#Override
public int getCount() {
return TITLES.length;
}
#Override
public Fragment getItem(int position) {
return Courses.newInstance(position);
}
}
}
The Courses Fragment :
public class Courses extends Fragment {
LinearLayout ll ;
private static final String ARG_POSITION = "position";
public static PagerSlidingTabStrip tab ;
private int position;
public static Courses newInstance(int position) {
Courses f = new Courses();
Bundle b = new Bundle();
b.putInt(ARG_POSITION, position);
f.setArguments(b);
return f;
}
#SuppressLint("NewApi")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
position = getArguments().getInt(ARG_POSITION);
setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.dept_main,container,false);
}
#Override
public void onViewCreated(View v, Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onViewCreated(v, savedInstanceState);
// generate ID's :
TextView h_name = (TextView) v.findViewById(R.id.tv_dept_name);
TextView f_info = (TextView) v.findViewById(R.id.tv_dept_info);
TextView h_vision = (TextView) v.findViewById(R.id.header_vision);
TextView f_vision = (TextView) v.findViewById(R.id.footer_vision);
TextView h_mission = (TextView) v.findViewById(R.id.header_mission);
TextView f_mission = (TextView) v.findViewById(R.id.footer_mission);
TextView h_eoe = (TextView) v.findViewById(R.id.header_EOE);
TextView f_eoe = (TextView) v.findViewById(R.id.footer_EOE);
TextView h_intake = (TextView) v.findViewById(R.id.header_intake);
TextView f_intake = (TextView) v.findViewById(R.id.footer_intake);
h_intake.setText(R.string.h_intake);
h_mission.setText(R.string.h_mission);
h_vision.setText(R.string.h_vision);
h_eoe.setText(R.string.h_eoe);
switch(position){
case 0 :
//Electronics
h_name.setText("Electronics");
f_info.setText(R.string.ug_course);
f_vision.setText(R.string.v_etrx);
f_mission.setText(R.string.m_etrx);
f_eoe.setText("1984");
f_intake.setText(R.string.intake_etrx);
break ;
case 1 :
h_name.setText("Information Technology");
f_info.setText(R.string.ug_course);
f_vision.setText(R.string.v_it);
f_mission.setText(R.string.m_it);
f_eoe.setText("1984");
f_intake.setText(R.string.intake_it);
break ;
case 2 :
h_name.setText("Computer Science");
f_info.setText(R.string.ug_course);
f_vision.setText(R.string.v_coms);
f_mission.setText(R.string.m_coms);
f_eoe.setText("1984");
f_intake.setText(R.string.intake_coms);
break ;
case 3 :
h_name.setText("Electronics And Telecommunication");
f_info.setText(R.string.ug_course);
f_vision.setText(R.string.v_extc);
f_mission.setText(R.string.m_extc);
f_eoe.setText("1984");
f_intake.setText(R.string.intake_extc);
break ;
case 4 :
h_name.setText("Instrumentation");
f_info.setText(R.string.ug_course);
f_vision.setText(R.string.v_it);
f_mission.setText(R.string.m_it);
f_eoe.setText("1984");
f_intake.setText(R.string.intake_it);
break ;
case 5 :
h_name.setText("Master of Computer Applications");
f_info.setText("Post Graduation Course.(PG)");
f_vision.setText(R.string.v_mca);
f_mission.setText(R.string.m_mca);
f_eoe.setText("1984");
f_intake.setText(R.string.intake_mca);
break;
}
}
}
(Comment for any clarifications ! )
Found My Answer ==> https://stackoverflow.com/a/12582529/3475933
Only Changed FragmenPagerAdapter to FragmentStatePagerAdapter and eveything worked fine.
Hope it helps .!
I am using PagerSlidingTab Library for ViewPager. And I want to change Fragment while scrolling of tabs. It is working fine. Check out my code.
I am using AsynTask() on each Fragment.
When the App opens with the MainActivity, First Fragment is attached to the activity, But It shows two AsynTask() dialog message, one from First and another from Second Fragment. And When I scroll to second tab, It shows dialog message of Third Fragment.
So, If I scroll from left to right in tabs, the Fragment right to the current fragment is displayed and if i scroll from right to left, the Fragment left to the current Fragment is displayed.
Please help me to solve the problem.
My Code:
public class PageSlidingTabStripFragment extends Fragment {
public static final String TAG = PageSlidingTabStripFragment.class
.getSimpleName();
public static PageSlidingTabStripFragment newInstance() {
return new PageSlidingTabStripFragment();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.pager, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
PagerSlidingTabStrip tabs = (PagerSlidingTabStrip) view
.findViewById(R.id.tabs);
ViewPager pager = (ViewPager) view.findViewById(R.id.pager);
MyPagerAdapter adapter = new MyPagerAdapter(getChildFragmentManager());
pager.setAdapter(adapter);
tabs.setViewPager(pager);
}
public class MyPagerAdapter extends FragmentPagerAdapter {
public MyPagerAdapter(android.support.v4.app.FragmentManager fm) {
super(fm);
}
private final String[] TITLES = { "Instant Opportunity", "Events",
"Experts" };
#Override
public CharSequence getPageTitle(int position) {
return TITLES[position];
}
#Override
public int getCount() {
return TITLES.length;
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new InstantOpportunity();
case 1:
return new Events();
case 2:
return new Experts();
default:
break;
}
return null;
}
}
}
Explanation:
It turns out there is an easier implementation for scrollable tabs which doesn't involve another library. You can easily implement tabs into your app using normal Android code straight from the default SDK.
The Code
Main Class:
public class PageSlidingTabStripFragment extends Fragment {
//Variables
private ViewPager viewPager;
private PagerTitleStrip pagerTitleStrip;
public PageSlidingTabStripFragment() {
// Required empty public constructor
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//Find your pager declared in XML
viewPager = (ViewPager) getView().findViewById(R.id.pager);
//Set the viewPager to a new adapter (see below)
viewPager.setAdapter(new MyAdapter(getFragmentManager()));
//If your doing scrollable tabs as opposed to fix tabs,
//you need to find a pagerTitleStrip that is declared in XML
//just like the pager
pagerTitleStrip = (PagerTitleStrip)
getView().findViewById(R.id.pager_title_strip);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.[your layout name here], container, false);
}
}
Adapter:
//Note: this can go below all of the previous code. Just make sure it's
//below the last curly bracket in your file!
class MyAdapter extends FragmentStatePagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int arg0) {
Fragment fragment = null;
if (arg0 == 0) {
fragment = new InstantOpportunity();
}
if (arg0 == 1) {
fragment = new Events();
}
if (arg0 == 2) {
fragment = new Experts();
}
return fragment;
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
if (position == 0) {
return "Instant Opportunity";
}
if (position == 1) {
return "Events";
}
if (position == 2) {
return "Experts";
}
return null;
}
}
Conclusion:
I hope this helps you understand another way to make scrollable tabs! I have examples on my Github Page about how to make each type (That being Fixed or Scrollable).
Links:
Fixed Tabs Example - Click Here
Scrollable Tabs Example - Click Here
Hope this helps!
Edit:
When asked what to import, make sure you select the V4 support fragments.
please use this example..its very easy.i already implement that.
reference link
hope its useful to you.its best example of pager-sliding-tabstrip.
Use
framelayout compulsory:
FrameLayout fl = new FrameLayout(getActivity());
fl.addView(urFragementView);
and then set your fragement view in this framelayout.
I've been trying to get an id from a listview-onclicklistener to three tabbed fragments. The user firstly clicks in myTicketsFragmentand then goes to the detail page which contains 3 swipeable tabs. These views are 'hosted' by one individual activity named TicketActivity. So currently I've succesfully passed data from the fragment to TicketActivity but I cannot go further than that. Been searching for 2 hours now and still no results..
Here's my code:
myTicketsFragment: passing the data in setOnItemClickListener to tab activity
public void onItemClick(AdapterView<?> parentView,
View childView, int position, long id) {
Bundle bundle = new Bundle();
bundle.putInt("ticketId", myTickets.get(position).getId());
Intent ticketDetail = new Intent(getActivity(), TicketActivity.class);
ticketDetail.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
ticketDetail.putExtras(bundle);
startActivity(ticketDetail);
}
TicketActivity: receiving data and passing it through to the 3 tabs
private ViewPager viewPager;
private TicketTabsPagerAdapter mAdapter;
private ActionBar actionBar;
// Tab titles
private String[] tabs = { "Info", "Intern", "Extern" };
public TicketInfoFragment ticketInfoFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tabs);
// Receive data
Bundle bundle = getIntent().getExtras();
int ticketId = bundle.getInt("ticketId");
// Pass data to fragments
// ...
// Initilization
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
mAdapter = new TicketTabsPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(true);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Adding Tabs
for (String tab_name : tabs) {
actionBar.addTab(actionBar.newTab().setText(tab_name)
.setTabListener(this));
}
/**
* on swiping the viewpager make respective tab selected
* */
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// on changing the page
// make respected tab selected
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
Example of a tab fragment
public class TicketInfoFragment extends Fragment {
TicketFull ticket = new TicketFull();
private DatabaseHelper db;
int ticketId;
String androidId;
String authCode;
String platform_url;
int uId;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
db = new DatabaseHelper(getActivity());
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_ticket_info, container, false);
return rootView;
}
}
I would be pleased if anyone could help me out
Thanks in advance
2 quick ways:
use an static method in your activity to retrieve current ticket id
Design and implement an interface and register the fragments as listeners from the activity
First option, In your activity:
private static int ticketId;
public static int getCurrentTicketId(){
return ticketId;
}
and in your fragment you can do:
TickerActivity.getCurrentTicketId();
Second option, Use an interface:
public interface TicketListener{
public void onTicketChanged(int newTicket);
}
and in your activity add:
public List<TicketListener> listeners = new ArrayList<TicketListener>();
public void addListener(TicketListener listener){
listeners.add(listener);
}
and register every fragment as a new listener
YourFragment frag = new YourFragment();
addListener(frag);
and finally when you want to notify the key to the listeners iterate over the list:
for(TicketListener listener : listeners){
listener.onTicketChanged(ticket);
}
You can do in two different ways. The more simple is in your Activity container has to provider a getter for the data that you want to access from the Fragments, so in your fragments has to access to this getter via getActivity to get a reference to the father and the invoke the get method, I mean:
In TicketActivity:
private int ticketId;
#Override
protected void onCreate(Bundle savedInstanceState) {
...
// Receive data
Bundle bundle = getIntent().getExtras();
ticketId = bundle.getInt("ticketId");
...
}
public int getTicketId() {
return ticketId;
}
And in your fragments:
((TicketActivity)getActivity()).getTicketId();
Or a more elegant way, is passing the Bundle via arguments when you initialize your fragments. You will have to do this inside your TicketTabsPagerAdapter class. I mean something like that:
TicketInfoFragment f = new TicketInfoFragment();
f.setArguments(bundle);
To do this last method is better use the Singleton pattern. You can follow the next link: http://developer.android.com/reference/android/app/Fragment.html
public static class DetailsFragment extends Fragment {
/**
* Create a new instance of DetailsFragment, initialized to
* show the text at 'index'.
*/
public static DetailsFragment newInstance(int index) {
DetailsFragment f = new DetailsFragment();
// Supply index input as an argument.
Bundle args = new Bundle();
args.putInt("index", index);
f.setArguments(args);
return f;
}
public int getShownIndex() {
return getArguments().getInt("index", 0);
}
it is very simple. When you will pass a bundle from ActivityA to other ActivityB(with bundle). it will be received by the ActivityB class instead of fragment.
It's simple to implement:
in onResume method of ActivityB ==> receive the bundle and passes attach it to your required fragment. check my code to pass from onresume to Framgent class
String tag = Constants.TAG_Search;
Fragment fragment;
fragment = fragmentManager.findFragmentByTag(tag);
fragmentTransaction.remove(fragment);
Search searchFragment = new Search();
searchFragment.setArguments(Globals.bd);
fragmentTransaction.add(R.id.tab2, searchFragment, tag);
Hope it will help
I have created a FragmentActivity of 2 tabs. This is a very basic Tab example from Android Developer tutorial using FragmentActivity and FragmentPagerAdapter Code Here
public class FragmentPagerSupport extends FragmentActivity implements
ActionBar.TabListener {
SectionsPagerAdapter mSectionsPagerAdapter;
static final int NUM_ITEMS = 10;
ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_pager);
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
...........
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
Bundle args = new Bundle();
switch (position) {
case 0:
fragment = new Fragment01();
args.putInt(Fragment01.ARG_SECTION_NUMBER, position + 1);
fragment.setArguments(args);
break;
case 1:
fragment = new Fragment02();
args.putInt(Fragment02.ARG_SECTION_NUMBER, position + 1);
fragment.setArguments(args);
break;
return fragment;
}
}
Then I have created 2 different fragments for 2 tabs:
public static class Fragment01 extends Fragment {
private EditText mName;
private EditText mEmail1;
public static final String ARG_SECTION_NUMBER = "2";
public Fragment01() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_customer_add, container, false);
mName = (EditText) v.findViewById(R.id.customer_add_name);
mEmail = (EditText) v.findViewById(R.id.customer_add_email);
View confirmButton = v.findViewById(R.id.customer_add_button);
confirmButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
......................
}
});
}
}
Now in the 2nd tab I need to show the input value of Name and Email from 1st tab and on confirm from 2nd tab need to save in database. But here I stuck. I am not getting an idea how I can keep data from first tab? Please help.
One approach could be to use Singleton DP. There will be only one object having Name, Email etc. as fields. Set Name and Email fields using setters when you are in first fragment and access them using getters in second fragment.
On confirm, you can insert entire object into database.