I am using ViewPager and Fragment to display data from sqlite. Content for all page is same so I used same Fragment class for all pages. In fragment there is a TextView. And there are two Buttons in Activity.
I am trying to update text of TextView when any Button is clicked from Activity. For this I used interface and override methods in fragment.All works fine.
Note: Buttons are in Activity(common for all pages)
Problem
When I press button it will update textview of next page. E.g. when I click button in page1 the textview of page2 will be updated and so on.
I used following code. Any help would be appreciate. Thanks.
Fragment code
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Create a new TextView and set its text to the fragment's section
// number argument value.
View view = inflater.inflate(R.layout.fragmentview, container, false);
txtAmount = (TextView) view.findViewById(R.id.txtAmount);
return view;
}
#Override
public void onPlusClick(String amount) {
// update textview here
}
#Override
public void onMinusClick(String amount) {
// update textview here
}
Adapter code
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a DummySectionFragment (defined as a static inner class
// below) with the page number as its lone argument.
Fragment fragment = new DummyFragment();
onClick = (onButtonClick) fragment;
return fragment;
}
#Override
public int getCount() {
// Show 3 total pages.
return arrModel.size();
}
#Override
public CharSequence getPageTitle(int position) {
return arrModel.get(position).fname;
}
Activity code
#Override
public void onClick(View v) {
if (v == btnMinus) {
onClick.onMinusClick(edtAmount.getText().toString());
} else if (v == btnPlus) {
onClick.onPlusClick(edtAmount.getText().toString());
}
}
Every time getItem is called you are creating a new fragment a assigning it to onClick so onClick is having reference to the latest fragment which in 2nd in your case.
Try creating a list of fragments in constructor of the adapter:
List<Fragment> fragments=new List<Fragment>();
Fragment currentFragment;
public Myadapter(){
fragments.add(new DummyFragment());
fragments.add(new DummyFragment());
}
#Override
public Fragment getItem(int position) {
return fragments.get(position);
}
public Fragment getCurrentFragment(){
return currentFragment;
}
#Override
public void setPrimaryItem(ViewGroup container, int position,
Object object) {
super.setPrimaryItem(container, position, object);
currentFragment=fragments.get(position);
}
Then in Activity-
public void onClick(View v) {
if (v == btnMinus) {
adapter.getCurrentFragment().onMinusClick(edtAmount.getText().toString());
} else if (v == btnPlus) {
adapter.getCurrentFragment().onPlusClick(edtAmount.getText().toString());
}
}
Related
I whan to call a method that adds respective fragment to viewpager whenever user click on item from recyclerview. how can i do it??, below is my code. thanks
SemesterFragmentViewPager.java
public SemesterFragmentViewPager() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_semester, container, false);
viewPager2 = (ViewPager2) view.findViewById(R.id.viewPager2);
tabLayout = view.findViewById(R.id.tabLayout);
adapter = new MyViewPager(getChildFragmentManager(), this.getLifecycle());
viewPager2.setAdapter(adapter);
new TabLayoutMediator(tabLayout, viewPager2,
new TabLayoutMediator.TabConfigurationStrategy() {
#Override
public void onConfigureTab(#NonNull TabLayout.Tab tab, int position) {
tab.setText("Sem" + (position + 1));
}
}).attach();
// addComputerScienceSem();
// cs();
adapter.notifyDataSetChanged();
return view;
}
public void addComputerScienceSem() {
adapter.addFrags(Semesters.newInstance(0, 0));
adapter.addFrags(Semesters.newInstance(0,1));
adapter.addFrags(Semesters.newInstance(0,2));
adapter.addFrags(Semesters.newInstance(0,3));
}
public void cs(){
adapter.addFrags(Semesters.newInstance(0,4));
adapter.addFrags(Semesters.newInstance(0,5));
}
}
what i want to achieve below is that when ever the case is 0 then i should call cs() method from SemesterFragmentViewPager.java, but not working why
DepartmentRVAdapter.java
public MyViewHolder(#NonNull View itemView) {
super(itemView);
imgDepLogo = itemView.findViewById(R.id.imgDeptLogo);
tvDepName = itemView.findViewById(R.id.tvDepName);
tvDepName.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
clickInterface.onItemClickListener(getLayoutPosition());
switch (getAdapterPosition()){
case 0:
Objects.requireNonNull(departmentFragment.getActivity()).getSupportFragmentManager()
.beginTransaction()
.replace(R.id.frameLayout,new SemesterFragmentViewPager().cs())// it couldnt work
.addToBackStack(null).
commit();
break;
and when the case is 1 then i should call addComputerScienceSem() method from SemesterFragmentViewPager.java, but not working
case 1:
Objects.requireNonNull(departmentFragment.getActivity()).getSupportFragmentManager()
.beginTransaction()
// .setCustomAnimations(R.anim.slide_in_left,R.anim.exit_to_left,R.anim.enter_from_right,R.anim.exit_to_left)
.replace(R.id.frameLayout, new SemesterFragmentViewPager().addComputerScienceSem())// it couldnt work too
.addToBackStack(null).
commit();
break;
MyViewPager.java
public class MyViewPager extends FragmentStateAdapter {
List<Fragment> fragmentList = new ArrayList<>();
public MyViewPager(#NonNull FragmentManager fragmentManager, #NonNull Lifecycle lifecycle) {
super(fragmentManager, lifecycle);
}
#NonNull
#Override
public Fragment createFragment(int position) {
return fragmentList.get(position);
}
#Override
public int getItemCount() {
return fragmentList.size();
}
public void addFrags(Fragment fragment){
fragmentList.add(fragment);
}
}
Step 1: You should create Callback (Interface)
interface HandleClickItemsRecycleview{
void onclickItemRecycleView()
}
And set to Adapter Recycleview Constructor
Step 2: Implement Callback with SemesterFragmentViewPager
SemesterFragmentViewPager implement HandleClickItemsRecycleview
Function Overide
void onClickItemRecyleview(){
// Action Add Fragment To ViewPager.
}
Concerning the response to the above recycleview item click event handling
. Hope it is useful to you
Description:
I have an activity (Father activity) which has a fragment (Father fragment) inside. This fragment is tabbed and has two fragments (Fragment A and Fragment B) that are changed with view pager.
Father activity sends data to Father fragment which has to take them to Fragment B
Question:
What can I do with Father fragment to take data to Fragment B (which is inside a view pager)?
Extra:
Someone told me I can use interface and I've tried to study it but I couldn't find any good tutorial / explanation.
Hi #Tomas I have Done like this
private class ViewPagerAdapter extends FragmentPagerAdapter {
private Fragment fragment1 = Fragment1.getInstance();
private Fragment fragment2 = Fragmen2.getInstance();
ViewPagerAdapter(FragmentManager supportFragmentManager) {
super(supportFragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
#Override
public Fragment getItem(int position) {
if (position == 0) {
return fragment1;
} else {
return fragment2;
}
}
#Override
public int getCount() {
return 2 ;
}
#Override
public CharSequence getPageTitle(int position) {
return "";
}
Fragment1 getFragment1() {
return (Fragment1) fragment1;
}
Fragment2 getFragment2() {
return (Fragment2) fragment2;
}
}
this is my Fragemnt2 code:
public class Fragment2 extends Fragment {
private TextView text;
public static Fragment2 getInstance() {
return new Fragment2();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragmant_2, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
text = view.findViewById(R.id.text2);
}
public void reloadView(String data){
text.setText(data);
}
}
and from viewpager adapter I call method of faragment 2 like this
adapter.getFragment1().reloadView("data");
I have FragmentActivity (MainFragmentActivity) that is calling some fragments. I will say the below one is the 3rd Fragment.
BaseFragment fragSensors = SensorsPagerFragment.newInstance(
m_objAppCredentials);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if (bFirst)
ft.add(R.id.flControlContainer, fragSensors, strTag);
else
ft.replace(R.id.flControlContainer, fragSensors, strTag);
And below class holds a viewpaper which calls more fragment upon swipe.
And in that one of the fragment an activity is called.
When the back button is pressed from the activity. The 1st Fragment UI appears and its mixes with UI of one of the fragment in the viewpager.
How to destroy the UI of the fragment inside the viewpaper or to avoid UI mixing?
public class SensorsPagerFragment extends BaseFragment {
ViewPager m_oVP;
public SensorsPagerFragment() {
LogUtils.LOGD("DEBUG", "SensorsPagerFragment::CTOR");
}
public static SensorsPagerFragment newInstance(AppCredentials objAppCredentials) {
SensorsPagerFragment frag = new SensorsPagerFragment();
m_objAppCredentials = objAppCredentials;
return frag;
}
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_sensors_pager, container, false);
m_oVP = (ViewPager) v.findViewById(R.id.vpSensors);
//pager.setOffscreenPageLimit(0);
// Attach the adaptor to the PAGER
m_oVP.setAdapter(buildAdapter());
return v;
}
private PagerAdapter buildAdapter() {
return (new SensorFragmentPA(getChildFragmentManager()));
}
#Override
public void onStop() {
super.onStop();
CustomToast.Warning(getActivity().getApplicationContext(),
"SensorsPagerFragment::onStop()", 1);
}
////////////////////////////////////////////////////////////////////////////////////////////////
// class SensorFragmentPA
class SensorFragmentPA extends FragmentPagerAdapter {
public SensorFragmentPA(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return Constants.cTOTAL_PAGES;
}
#Override
public Fragment getItem(int nPageNum) {
SensorsFragment f = SensorsFragment.newInstance(m_objAppCredentials, nPageNum);
return f;
}
#Override
public String getPageTitle(int nPageNum) {
return Integer.toString(nPageNum + 1);
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
}
}
}
I have resolved the issue.
I have implemented the callbacks in each fragment. And in the MainFragmentActivity replace the fragments.
I have a FRAGMENT with a viewpager with 7 other fragments. These fragments are used to enter user details. In the final fragment, there is a "submit" button where I need to get all the user details entered in the other fragments. How can I do this
I saw this question which didnt help. So please dont mark this question duplicate.
The base fragment:
public class Register_Layout extends Fragment implements ViewPager.OnPageChangeListener{
public Register_Layout(){}
static ViewPager viewPager1;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_register_layout, container, false);
viewPager1 = (ViewPager) view.findViewById(R.id.view_pager1);
viewPager1.setOffscreenPageLimit(7);
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
viewPager1.setAdapter(new MyAdapter(fragmentManager));
return view;
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
}
class MyAdapter extends FragmentPagerAdapter{
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
if(position==0)
{
fragment = new Register();
}
if(position==1)
{
fragment = new Register_Page2();
}
if(position==2)
{
fragment = new Register_Page3();
}
if(position==3)
{
fragment = new Register_Page4();
}
if(position==4)
{
fragment = new Register_Page5();
}
if(position==5)
{
fragment = new Register_Page6();
}
if(position==6)
{
fragment = new Register_Page7();
}
return fragment;
}
#Override
public int getCount() {
return 7;
}
}
The final fragment where I should get data of all other fragments:
public class Register_Page7 extends Fragment {
public Register_Page7(){
}
EditText editText;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_register_page7, container, false);
Button Previous = (Button) view.findViewById(R.id.Previous7);
Button Regiter = (Button) view.findViewById(R.id.Submit);
Regiter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity());
alertDialogBuilder.setMessage("Are you sure you want to submit?");
alertDialogBuilder.setPositiveButton("Yes",new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1) {
}
});
alertDialogBuilder.setNegativeButton("No,Let me check the details again", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
});
Previous.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new Register_Layout().viewPager1.setCurrentItem(5);
}
});
return view;
}
}
You will probably want to use the fragment manager to get all of the instantiated fragments, and loop through them to get their relevant data.
You could create a subclass of Fragment that all of the fragments would inherit from. This subclass would have a getText method(or some other type of public method), that gets the text from the EditText view.
For other types of data(like switches), you would have similar functions to get the data from the fragment.
Edited
So you could create a new fragment that is derived from Fragment.
public class BaseEntryFragment extends Fragment {
public BaseEntryFragment() {}
public String getEntryText() {}
}
Then you take your existing fragments and extend your new fragment..
public class Register_Page7 extends BaseEntryFragment {
private EditText _editText;
public Register_Page7() {}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
//other create view code
_editText = (EditText)FindViewById(R.id.edit_text);
}
#Override
public String getEntryText() {
return _editText.getText();
}
}
Then with your submit..
List<Fragment> fragments = getActivity().getSupportFragmentManager().getFragments();
for(Fragment frag : fragments) {
// do type checks here
BaseEntryFragment f = (BaseEntryFragment)frag;
String someValue = f.getEntryText();
}
Please note, my Java is really really rusty, so it may not be the perfect syntax. This is just some code to get you started and not intended to be copied and pasted.
i think it is easier in each fragment, you store the user data on a SharedPreference (the data structure can be a json string or whatever you like), at the end (last fragment) read the shared pref data, and perform the register
hope that helps
I recommend you to use an Activity to hold your ViewPager and declare there the variables or objects you want to save from Fragments.
In each Fragment you want to save data you have to use interface to pass the data to the Activity. Here is the way to do it: Passing data between a fragment and its container activity
Then in your last Fragment you can call (with generated getters for the variables I mentioned before) to your container Activity like this:
YourActivity yourActivity = ((YourActivity) getActivity());
int foo = yourActivity.getFooInt();
You can find fragments in your Activity and get data from each fragment by public method. Variable position is position of fragment in your viewpager
public Fragment getFragment(ViewPager container, int position) {
String name = makeFragmentName(container.getId(), position);
return mFragmentManager.findFragmentByTag(name);
}
private static String makeFragmentName(int viewId, int index) {
return "android:switcher:" + viewId + ":" + index;
}
I have a Fragment for a ViewPager. The ViewPager is updated based on an action fired by the user. Well when the Fragment is recreated so to speak, the page of a ViewPager is not updated as should be, or even shown for that matter! When I swipe over to other pages and then back to that one, it loads?
Here is the Fragment:
public static class CardFrontFragment extends Fragment {
public CardFrontFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = null;
rootView = inflater.inflate(R.layout.activity_dashboard, container, false);
TextView textviewLocation = (TextView)rootView.findViewById(R.id.textview_location);
TextView textviewConditions = (TextView)rootView.findViewById(R.id.textview_points);
ViewPager viewPagerDashboard = (ViewPager)rootView.findViewById(R.id.viewPager_Dashboard);
if(overviewData != null) {
textviewLocation.setText(overviewData.getLocation());
textviewPoints.setText(overviewData.getPoints());
viewPagerDashboard.setAdapter(adapterSectionsPager);
adapterSectionsPager.notifyDataSetChanged();
viewPagerDashboard.destroyDrawingCache();
textviewLocation.setText(overviewData.getWeathersLocation());
textviewPoints.setText(overviewData.getWeathersConditions());
}
return rootView;
}
}
Here is the adapter:
public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public android.support.v4.app.Fragment getItem(int position) {
return DashboardSectionFragment.create
(uiContext, position, overviewData, forecastData, hourlyData, radarData);
}
#Override
public int getCount() {
// Show 4 total pages:
return 4;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.title_section_1).toUpperCase(l);
case 1:
return getString(R.string.title_section_2).toUpperCase(l);
case 2:
return getString(R.string.title_section_3).toUpperCase(l);
case 3:
// Radar Page:
return getString(R.string.title_section_4).toUpperCase(l);
}
return null;
}
}
I heard I am extending the correct one FragmentStatePagerAdapter over FragmentPagerAdapter. Yet nothing is working. I have called many methods of the ViewPager and adapter in the Fragment when the ViewPager is recreated but it still does not load initially till it appears off screen then back on...
Thanks!
try overriding the following like this and update the viewpager and pageradapater instance
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
viewPager.invalidate();
pagerAdapter.notifyDataSetChanged();
}
or else depending upon the specific location of the Fragment you can do the following
#Override
public void onPageSelected(int arg0) {
if(int == 2)// In which specifi fragment you want to update the view
{
viewPager.invalidate();
pagerAdapter.notifyDataSetChanged();
}
}
I hope this would help you
Try to update view when fragment get visible to user as follows:
public class MyFragment extends Fragment
#Override
public void setMenuVisibility(final boolean visible) {
super.setMenuVisibility(visible);
if (visible) {
**//Update views here**
}
}