#Override
public void onViewDetachedFromWindow(#NonNull FragmentViewHolder holder) {
super.onViewDetachedFromWindow(holder);
}
I have many independent EditText with different id in each fragments of viewpager. For each swipe I want to clear these EditText and make them default.
I can clear text using:
holder.itemview.findViewById(R.id.first).setText("something");
but it won't a clear text.
What should I do?
Edit: whole testing Code:
I prepare a test fragment. When I click button,it changes text in current fragment. When I swipe to second fragment, It should be cleared or changed into its default value at xml.
TestFragment
public class TestFragment extends Fragment {
private TestViewModel mViewModel;
private ViewPager2 mViewPager;
private Button btnTest;
public static TestFragment newInstance() {
return new TestFragment();
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.test_fragment, container, false);
btnTest=(Button)view.findViewById(R.id.etTest);
return view;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mViewModel = ViewModelProviders.of(this).get(TestViewModel.class);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mViewPager = view.findViewById(R.id.myPager);
mViewPager.setSaveFromParentEnabled(false);
mViewPager.setOffscreenPageLimit(1);
mViewPager.setAdapter(new ViewPagerAdapter(getChildFragmentManager(),getLifecycle()));
TabLayout tabLayout = view.findViewById(R.id.tabs);
new TabLayoutMediator(tabLayout, mViewPager,
new TabLayoutMediator.TabConfigurationStrategy() {
#Override
public void onConfigureTab(#NonNull TabLayout.Tab tab, int position) {
tab.setText(((ViewPagerAdapter)(mViewPager.getAdapter())).mFragmentNames[position]);//Sets tabs names as mentioned in ViewPagerAdapter fragmentNames array, this can be implemented in many different ways.
}
}
).attach();
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
Fragment current=((ViewPagerAdapter)(mViewPager.getAdapter())).createFragment(tab.getPosition());//clear data here or below
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}});
btnTest.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
int cur=((ViewPagerAdapter)(mViewPager.getAdapter())).getCurrentPos();
switch (cur){
case 0:
Fragment current=((ViewPagerAdapter)(mViewPager.getAdapter())).createFragment(0);
TextView tF= current.getView().findViewById(R.id.first);
tF.setText("Clicked while 1");
break;
case 1:
Fragment current2=((ViewPagerAdapter)(mViewPager.getAdapter())).createFragment(1);
TextView tF2= current2.getView().findViewById(R.id.second);
tF2.setText("Clicked while 2");
break;
}
}
});
}
public class ViewPagerAdapter extends FragmentStateAdapter {
private int currentPos;
private final Fragment[] mFragments = new Fragment[] {
new FirstFragment(),
new SecondFragment(),
};
public final String[] mFragmentNames = new String[] {
"First",
"Second"
};
public ViewPagerAdapter(#NonNull FragmentManager fragmentManager, #NonNull Lifecycle lifecycle) {
super(fragmentManager, lifecycle);
}
#Override
public void onViewDetachedFromWindow(#NonNull FragmentViewHolder holder) {
super.onViewDetachedFromWindow(holder);
if(currentPos!=0){
TextView textView =(TextView)holder.itemView.findViewById(R.id.first);//clear data here or up
}
}
#Override
public int getItemCount() {
return mFragments.length;
}
#Override
public long getItemId(int position) {
this.setCurrentPos(position);
return super.getItemId(position);
}
public int getCurrentPos() {
return currentPos;
}
public void setCurrentPos(int currentPos) {
this.currentPos = currentPos;
}
#NonNull
#Override
public Fragment createFragment(int position) {
return mFragments[position];
}
}}
I can handle on onViewDetachedFromWindow or onTabUnselected. Both can change view.
First Fragment
public class FirstFragment extends Fragment {
private View mLeak;
private TextView tvTest;
public FirstFragment() {
}
public static FirstFragment newInstance(String param1, String param2) {
FirstFragment fragment = new FirstFragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mLeak = inflater.inflate(R.layout.fragment_first, container, false);
tvTest=mLeak.findViewById(R.id.first);
return mLeak;
}
#Override
public void onDetach() {
super.onDetach();
mLeak=null;
}}
Approach 1:
Set this line on your viewpager :
viewPager.setOffscreenPageLimit(1);
This will simply refresh each fragment again when it's loaded.
Approach 2:
Create an interface and implement it on each fragment. In your activity/fragment where viewpager is defined, use "addOnPageChangeListener" on viewpager, and when the different page is selected, simply use the interface to get back the fragment instance and call the required methods in the fragment, to clear/change the text.
Code :
//Your Activity
class HomeActivity extends Activity{
...Methods...
public void setUpViewpager(){
//setup your viewpager
viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
#Override
public void onPageSelected(int position) {
ChangeText fragment = (ChangeText) viewpager.getFragment(position);
fragment.changeText();
}
#Override
public void onPageScrollStateChanged(int state) {}
});
}
interface ChangeText{
void changeText();
}
}
//Your fragment
class FirstFragment extends Fragment implements HomeActivity.ChangeText{
...Methods...
public void changeText(){
//change the textview text here
}
}
class SecondFragment extends Fragment implements HomeActivity.ChangeText{
...Methods...
public void changeText(){
//change the textview text here
}
}
Related
Activity
public class GroupesActivity extends BaseActivity {
SelectedBundle selectedBundle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_groupes);
sectionsPagerAdapter = new GroupPagerAdapter(this, getSupportFragmentManager());
viewPager.setAdapter(sectionsPagerAdapter);
tabs.setupWithViewPager(viewPager);
}
private void getAllGroup() {
// api call retrive data
// send data using interface on response
// set data selectedBundle.onBundleSelect(isVisible,calanderModelList,groupModelList,eventModelList);
}
public void setOnBundleSelected(SelectedBundle selectedBundle) {
this.selectedBundle = selectedBundle;
}
public interface SelectedBundle {
void onBundleSelect(boolean isVisible, List<CalanderModel> calanderModelList, List<GroupModel> groupModelList, List<EventModel> eventModelList);
}
}
Frgment
public class FragmentOne extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View root = inflater.inflate(R.layout.fragment_all_groups_fragments, container, false);
// get data only once on oncreateview
((GroupesActivity) getActivity()).setOnBundleSelected(new GroupesActivity.SelectedBundle() {
#Override
public void onBundleSelect(boolean isVisible, List<CalanderModel> calanderModelListtt, List<GroupModel> groupModelList, List<EventModel> eventModelList) {
Log.e("retrive data","data")
}
});
return root;
}
}
GroupPagerAdapter
public class GroupPagerAdapter extends FragmentPagerAdapter {
#StringRes
private static final int[] TAB_TITLES = new int[]{R.string.tab_text_1, R.string.tab_text_2, R.string.tab_text_3};
private final Context mContext;
public GroupPagerAdapter(Context context, FragmentManager fm) {
super( fm);
this.mContext=context;
}
#NonNull
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new AllGroupsFragments();
case 1:
return new HostFragments();
case 2:
return new GuestFragments();
}
return null;
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return mContext.getResources().getString(TAB_TITLES[position]);
}
#Override
public int getCount() {
return 3;
}
}
problem
i have three fragments in tabview when i swipe this obove fragment
and then come again in this fragmnet that interface not called and i'm
not getting data from activity
How to get that data again from its parent activity, i need to only
retrive that data from activity on each time of fragments oncreateView
Thanks in adavance ;)
Use setMenuVisibility() method in Fragment to fix the issue.
//In fragments
#Override
public void setMenuVisibility(final boolean isVisible) {
super.setMenuVisibility(isVisible);
if (isVisible) {
//visible to user- do ur stuff
((GroupesActivity) getActivity()).setOnBundleSelected(new
GroupesActivity.SelectedBundle() {
#Override
public void onBundleSelect(boolean isVisible, List<CalanderModel>
calanderModelListtt, List<GroupModel> groupModelList, List<EventModel>
eventModelList) {
Log.e("retrive data","data")
}
});
}
}
the following link may help if you face any issues:
How to determine when Fragment becomes visible in ViewPager
I want to create a multi-step registration form in my android app. I wish to use the viewpager with multiple fragments and each fragment being a step in a registration.
At the end, I want to submit all the data submitted in each fragment using an activity to a mysql database. Can I get a small sample code for this?
This is what I have tried so far. I am able to implement a viewpager with multiple fragments. I have created an interface in the StepOne.java Fragment so as to communicate to an activity. But I am not able to retrieve data from these fragments. It throws a null-pointer exception on line 52.
Here is my code:
SliderActivity.java:
public class SliderActivity extends AppCompatActivity {
ViewPager viewPager;
EditText edName,edPassword, edConfPass;
TextView tvShowAll;
ViewPagerAdapter mPagerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_slider);
viewPager = findViewById(R.id.view_pager);
mPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(mPagerAdapter);
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
public void selectIndex(int newIndex) {
viewPager.setCurrentItem(newIndex);
}
#Override
public void onBackPressed() {
int currentPosition = viewPager.getCurrentItem();
if (currentPosition != 0) {
viewPager.setCurrentItem(viewPager.getCurrentItem()-1);
} else {
super.onBackPressed();
}
}
public class ViewPagerAdapter extends FragmentPagerAdapter {
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position)
{
case 0:
return new StepOne();
case 1:
return new StepTwo();
case 2:
return new StepThree();
}
return null;
}
#Override
public int getCount() {
return 3; //three fragments
}
}
}
StepOne.java:
public class StepOne extends Fragment {
Button buttonInFragment1;
EditText edName;
public interface ActivityFragmentCallback {
void onSetName(String name);
}
ActivityFragmentCallback listener;
public StepOne() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View rootView = inflater.inflate(R.layout.fragment_step_one, container, false);
edName = rootView.findViewById(R.id.edName);
buttonInFragment1 = rootView.findViewById(R.id.button_one);
if(buttonInFragment1 != null) {
buttonInFragment1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getContext(),edName.getText().toString(),Toast.LENGTH_SHORT).show();
if(edName != null) {
listener.onSetName(edName.getText().toString());
}
switch (view.getId()){
case R.id.button_one:
((SliderActivity)getActivity()).selectIndex(1);
break;
}
}
});
}
return rootView;
}
#Override
public void onAttach(Context context){
super.onAttach(context);
try {
listener = (ActivityFragmentCallback)context;
}catch (ClassCastException c){
c.printStackTrace();
}
}
}
MessageActivity.java: Here is where I need all the data submitted from all the fragments
public class MessageActivity extends AppCompatActivity implements StepOne.ActivityFragmentCallback {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_message);
}
#Override
public void onSetName(String name){
// tvShowAll = findViewById(R.id.tvShowAll);
// tvShowAll.setText(name);
Toast.makeText(getApplicationContext(),name, Toast.LENGTH_LONG).show();
}
}
Below is some reference link for step by step registration;
Hope you have help
https://github.com/stepstone-tech/android-material-stepper
https://github.com/baoyachi/StepView?utm_source=android-arsenal.com&utm_medium=referral&utm_campaign=3774
My app have a fragmentActivity with tabBar which control over the view pager and contain 3 fragments ,when i update my class User in fragmentB,i need to display him in fragmentC.
my question is how to refresh fragmentC every time when i add new User.
before i wrote this question i tried all the solution from this questions:
1.Update ViewPager dynamically?
2.refresh fragment at reload
3.Update Fragment from ViewPager
4.ViewPager PagerAdapter not updating the View
5.How to update fragment content from activity (viewpager)?
here is my code
FragmentActivity:
public class MainActivityTab extends FragmentActivity {
public SectionsPagerAdapter mSectionsPagerAdapter;
public ViewPager mViewPager;
public static MainActivityTab instance = null;
public static MainActivityTab getInstance(){
return instance;
}
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_tab);
getWindow().setStatusBarColor(Color.rgb(191,76,12));
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
final TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
tabLayout.getTabAt(0).setIcon(R.drawable.icon_A);
tabLayout.getTabAt(1).setIcon(R.drawable.icon_B);
tabLayout.getTabAt(2).setIcon(R.drawable.icon_C);
mViewPager.setCurrentItem(1,false);
}
FragmentStatePagerAdapter:
public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position){
case 0:
return FragmentA.newInstance();
case 1:
return FragmentA.newInstance();
case 2:
return FragmentC.newInstance();
default:
return null;
}
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
return null;
}
}
FragmentB:
public class FragmentB extends Fragment {
EditText name;
EditText age;
Button btnSave;
public static FragmentB newInstance() {
FragmentB fragment = new FragmentB();
return fragment;
}
public FragmentB() {}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_new2, container, false);
name = (EditText) rootView.findViewById(R.id.name);
age = (EditText) rootView.findViewById(R.id.age);
btnSave = (Button) rootView.findViewById(R.id.btnSave);
btnSave.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
UserManager.getInstance().creteUser(name.getText().toString(),age.getText().toString());
}
});
return rootView;
}
}
FragmentC:
public class FragmentC extends Fragment {
TextView nameTxt;
TextView ageTxt;
public static FragmentC newInstance(){
FragmentC instance = new FragmentC();
return instance;
}
public FragmentC(){
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_new3, container, false);
nameTxt = (TextView) rootView.findViewById(R.id.nameTxt);
ageTxt = (TextView) rootView.findViewById(R.id.ageTxt);
showUser();
return rootView;
}
public void showUser(){
if(UserManager.getInstance().getUser().getName()!=null){
nameTxt.setText(UserManager.getInstance().getUser().getName().toString());
ageTxt.setText(UserManager.getInstance().getUser().getAge().toString());
}
}
}
You could create a callback like:
public interface UserChangedCallback{
void onUserChanged();
}
and implement this callback on every view/fragment where you want to access the user:
#Override
public void onUserChanged() {
adapter.notifyDataSetChanged();
// or if you don't have an adapter refresh your textfields or whatever you want
}
Register the callback on the usermanager via UserManager.getInstance().registerCallback(this). Internally the usermanager have to add the callback to an internal list.
Create a private function inside your usermanager:
private void notifyCallbacks() {
for(UserChangedCallback callback : registeredCallbacks) {
callback.onUserChanged();
}
}
If you add/modify/delete a user you always have to call this function at the end. For example:
public void addUser(User user) {
users.add(user);
notifiCallbacks();
}
Now every view will be notified and refreshed.
Important!
Don't forget to unregister the callback from the usermanager on onDestroy() to avoid memory leaks.
Found solution:
i used in the method onPageSelected,when position is 2 my fragment detach and afterwards attach the fragment.
working perfectly!
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
if(position==2){
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction().add(R.id.fragmant_new3, FragmentC.newInstance());
fragmentTransaction.detach(FragmentC.newInstance());
fragmentTransaction.attach(FragmentC.newInstance());
fragmentTransaction.commit();
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
I have a viewpager with swipeable fragments and also a radiogroup that shows which view is selected. When I start the application, the first radiobutton is not selected, it is only selected when I swipe another view and get back. I am a beginner, so please share your knowledge. Here's my code:
Viewpager Adapter:
public class ViewPagerAdapter extends FragmentPagerAdapter {
public static int int_items = 3;
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new WelcomeOneFragment();
case 1:
return new WelcomeTwoFragment();
case 2:
return new WelcomeThreeFragment();
}
return null;
}
#Override
public int getCount() {
return int_items;
}
Fragment with the radiogroup:
public class TabFragment extends BaseFragment implements ViewPager.OnPageChangeListener, View.OnClickListener {
public static ViewPager mViewPager;
private Button mButtonMassage;
private RadioGroup mRadioGroup;
public static TabFragment newInstance() {
return new TabFragment();
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_tab, container, false);
initUi(rootView);
return rootView;
}
#Override
public void initUi(View rootView) {
mRadioGroup = (RadioGroup) rootView.findViewById(R.id.radio_group);
mViewPager = (ViewPager) rootView.findViewById(R.id.view_pager);
mButtonMassage = (Button) rootView.findViewById(R.id.buttonMassage);
initListeners();
}
#Override
public void initListeners() {
mButtonMassage.setOnClickListener(this);
mViewPager.addOnPageChangeListener(this);
initData();
}
#Override
public void initData() {
mViewPager.setAdapter(new ViewPagerAdapter(getChildFragmentManager()));
mViewPager.setCurrentItem(0);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.buttonMassage:
Intent i = new Intent(getActivity(), MassageActivity.class);
startActivity(i);
break;
default:
break;
}
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
mRadioGroup.check(mRadioGroup.getChildAt(position).getId());
}
#Override
public void onPageScrollStateChanged(int state) {
}
}
just call this
mRadioGroup.check(mRadioGroup.getChildAt(0).getId());
after
mViewPager.setCurrentItem(0);
as listner will not callup in starting and you have to set it for manually after setting adapter to viewpager
hope it will work for you!! :)
This is a pretty common issue with ViewPager. onPageSelected is not called upon start, so I would just call:
mRadioGroup.check(mRadioGroup.getChildAt(0).getId());
In your initUi() method.
I have a viewpager with 2 pages, on each fragment i put a button to switching fragment,
but if i change orientation switching doesn't work.
For switching fragment I using my OnChangePageButtonClick interface
Why is this happening?
ViewPager Activity:
public class ViewPagerMusic extends FragmentActivity implements OnChangePageButtonClick {
private ViewPager vp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_pager_music);
ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(super.getSupportFragmentManager(), fragments);
vp = (ViewPager)findViewById(R.id.viewpager);
vp.setAdapter(viewPagerAdapter);
}
private class ViewPagerAdapter extends FragmentStatePagerAdapter {
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch(position) {
case 0:
MainPage mainPage = new MainPage();
mainPage.setOnChengeButtonListener(ViewPagerMusic.this);
return mainPage;
case 1:
PlaylistPage playlistPage = new PlaylistPage();
playlistPage.setOnChengeButtonListener(ViewPagerMusic.this);
return playlistPage;
}
return null;
}
#Override
public int getCount() {
return 2;
}
}
#Override
public void selectPage(int page) {
vp.setCurrentItem(page);
}
}
my Frgamnets:
public class MainPage extends Fragment {
public MainPage() {
setRetainInstance(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.music_main_page, container, false);
ImageButton btnPlaylist = (ImageButton)v.findViewById(R.id.btnGoPlaylist2);
btnPlaylist.setOnClickListener(onButtonListener);
return v;
}
private OnClickListener onButtonListener = new OnClickListener() {
#Override
public void onClick(View view) {
onChangePageButtonClick.selectPage(1);
}
};
public void setOnBackButtonListener(OnChangePageButtonClick onChangePageButtonClick) {
this.onChangePageButtonClick = onChangePageButtonClick;
}
private OnChangePageButtonClick onChangePageButtonClick;
}
Playlist fragment is similar to MainPage fragment.
Your fragments are storing a reference to the ViewPagerMusic activity. However, after rotation, the activity is destroyed and recreated, so the fragments now contain a reference to the old activity.
Instead of storing a reference to the activity, you can call the activity's method from the fragment like this:
((ViewPagerMusic) getActivity()).selectPage(1);
just create this method in your view pager
#Override
public void selectPage(int page) {
vp.setCurrentItem(page);
}
and then call this in your onclick method
((ViewPagerMusic) getActivity()).selectPage(1);