I have implemented swipe fragments using
https://developer.android.com/training/animation/screen-slide.html
or
https://developer.android.com/training/implementing-navigation/lateral.html
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/some_background_fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
Here is MyActivity.java:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_overlay);
// Instantiate a ViewPager and a PagerAdapter.
mPager = findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
mPager.setCurrentItem(1);
}
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter{
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
if (position == 0)
return new Page0Fragment();
else
return new Page1Fragment();
}
#Override
public int getCount() {
return NUM_PAGES;
}
}
Now I am trying to access the currently viewed fragment like this
public void myonclickmethod(View view) {
FragmentManager fm = getSupportFragmentManager();
fragment = fm.findFragmentById(R.id.pager);//<=**This is coming as instance of Page0Fragment inspite of me intializing the activity with Page1Fragment and also currently standing on Page1Fragment without any swiping**
}
First, you need to change your ScreenSlidePagerAdapter to return the same instance everytime instead of new Page0Fragment like:
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter{
List<Fragment> fragments = new ArrayList<>();
public ScreenSlidePagerAdapter(FragmentManager fm) {
super(fm);
fragments.add(new Page0Fragment());
fragments.add(new Page1Fragment());
}
#Override
public Fragment getItem(int position) {
return fragments.get(position);
}
#Override
public int getCount() {
return fragments.size();
}
Now for getting visible fragment, do like:
public void myonclickmethod(View view) {
int currentPosition = mPager.getCurrentItem();
if(currentPosition == 0 {
Page0Fragment page0Fragment = (Page0Fragment)mPagerAdapter.getItem(currentPosition);
page0Fragment.doSomething();
} else {
Page1Fragment page1Fragment =(Page1Fragment)mPagerAdapter.getItem(currentPosition);
pag1Fragment.doSomething();
}
You can get the current fragment by calling getItem() with the current position on your adapter like this
public void myonclickmethod() {
Fragment fragment = adapter.getItem(viewpager.getCurrentItem())
}
Related
I am using a TabLayout inside a Fragment. The content of the TabLayout (made of 2 fragments) is displayed but not the title of the tabs. I believe it's a layout problem but i'm not sure on how to fix it.
Also what would be the overrided method for ViewPager2 that was used in ViewPager (getPagetitle) ?
main Fragment
public class CommunityFragment extends Fragment {
private TabLayout tbL;
private ViewPager2 vp;
private RecipeViewPagerAdapter rvpa;
public CommunityFragment() {
// Required empty public constructor
}
public static CommunityFragment newInstance(){
return new CommunityFragment();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_community, container, false);
tbL = rootView.findViewById(R.id.tabL);
vp = rootView.findViewById(R.id.pager);
rvpa = new RecipeViewPagerAdapter(this);
vp.setAdapter(rvpa);
rvpa.addFragment(new AllFragment(),"All time");
rvpa.addFragment(new DayFragment(),"Today");
new TabLayoutMediator(tbL, vp, new TabLayoutMediator.TabConfigurationStrategy() {
#Override public void onConfigureTab(#NonNull TabLayout.Tab tab, int position) {
//////title????
}
}).attach();
return rootView;
}
}
Adapter
public class RecipeViewPagerAdapter extends FragmentStateAdapter {
private ArrayList<Fragment> listF = new ArrayList<>();
private ArrayList<String> listT = new ArrayList<>();
public RecipeViewPagerAdapter(#NonNull Fragment fragment) {
super(fragment);
}
#NonNull
#Override
public Fragment createFragment(int position) {
return listF.get(position);
}
//new method ????
public CharSequence getPageTitle(int position){
return listT.get(position);
}
#Override
public int getItemCount() {
return listT.size();
}
public void addFragment(Fragment frag, String title){
listF.add(frag);
listT.add(title);
}
}
fragment layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".fragments.CommunityFragment">
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabL"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabGravity="fill"
app:tabIndicatorColor="#color/yellowCool"/>
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
put this in your main activity....
myAdapter=new FragmentAdapter(this);
myViewPager2.setAdapter(myAdapter);
String [] tabTtiles={"Home","Chat","Notification","Account"};
new TabLayoutMediator(myTabLayout, myViewPager2,(myTabLayout, position) ->
myTabLayout.setText(tabTtiles[position])).attach();
Your tabLayout doesn't display. Use this:
<androidx.viewpager2.widget.ViewPager2
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" // add this line
/>
TabLayoutMediator:
new TabLayoutMediator(tbL, vp, new TabLayoutMediator.TabConfigurationStrategy() {
#Override public void onConfigureTab(#NonNull TabLayout.Tab tab, int position) {
if(position == 0)
tab.setText("All time");
else
tab.setText("Today");
}
}).attach();
You can use the following adapter for the viewPager2:
public class ViewPagerAdapter extends FragmentStateAdapter {
private static final int CARD_ITEM_SIZE = 10;
public ViewPagerAdapter(#NonNull FragmentActivity fragmentActivity) {
super(fragmentActivity);
}
#NonNull #Override public Fragment createFragment(int position) {
return CardFragment.newInstance(position);
}
#Override public int getItemCount() {
return CARD_ITEM_SIZE;
}
}
on the mainActivity you need to have something inline with the following:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = findViewById(R.id.view_pager);
tabLayout = findViewById(R.id.tabs);
viewPager.setAdapter(new ViewPagerAdapter(this));
new TabLayoutMediator(tabLayout, viewPager,
new TabLayoutMediator.TabConfigurationStrategy() {
#Override public void onConfigureTab(#NonNull TabLayout.Tab tab, int position) {
tab.setText("Tab " + (position + 1));
}
}).attach();
}
}
As per documentation:
The TabLayoutMediator object also handles the task of generating page
titles for the TabLayout object, which means that the adapter class
does not need to override getPageTitle():
And to do that:
TabLayout tabLayout = view.findViewById(R.id.tab_layout);
new TabLayoutMediator(tabLayout, viewPager,
(tab, position) -> tab.setText("OBJECT " + (position + 1))
).attach();
Is it possible to change fragment defined i xml?
<fragment
android:id="#+id/fragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
A have a lot of screens to show and switch. A tab-like menu on the right. Every tab have another tabs. I want to simply change this one by one. Maybe someone have better idea?
SOLVED
I used ViewPager and FragmentPagerAdapter
http://developer.android.com/reference/android/support/v4/app/FragmentPagerAdapter.html
private ViewPager pager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_content);
pager = (ViewPager) findViewById(R.id.pager);
ControllerFragment cf = new ControllerFragment(getSupportFragmentManager(), getFragment());
pager.setAdapter(cf);
}
private List<Fragment> getFragments() {
List<Fragment> list = new ArrayList<Fragment>();
FirstFragment fragment = new FirstFragment();
list.add(fragment);
return list;
}
public void onTabSelected(View v) {
switch (v.getId()) {
case R.id.ivProfile:
pager.setCurrentItem(0);
}
}
public class ControllerFragment extends FragmentPagerAdapter {
List<Fragment> fragments;
public ControllerFragment(FragmentManager fm, List<Fragment> fragments){
super(fm);
this.fragments = fragments;
}
#Override
public Fragment getItem(int arg0){
return this.fragments.get(arg0);
}
#Override
public int getCount(){
return this.fragments.size();
}
}
I am having trouble showing my new fragment . Basically what i doing is i have a viewpager having 3 pages , in the second page i m hiding the current fragment and adding a new one. Everything goes perfectly except that i can't see my new fragment.
My Mainactivity.java
public class MainActivity extends AppCompatActivity {
ViewPager viewPager = null;
NavigationDrawerFragement drawerFragement;
Bitmap image = null;
int notificationExtra = 0;
int nid=0;
Toolbar toolbar;
private void startGetLocationService() {
Intent i = new Intent(this, GetUserLocationService.class);
startService(i);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_register);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.app_bar);
setSupportActionBar(toolbar);
drawerFragement = (NavigationDrawerFragement) getSupportFragmentManager().findFragmentById(R.id.fragment_navigation_drawer);
drawerFragement.setUp((DrawerLayout) findViewById(R.id.drawer_layout),toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
getSupportActionBar().setHomeButtonEnabled(false);
//getSupportActionBar().setIcon(R.drawable.account);
getSupportActionBar().setTitle("Eventyze");
viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPager.setAdapter(new MyAdapter(getSupportFragmentManager()));
PagerSlidingTabStrip tabs = (PagerSlidingTabStrip) findViewById(R.id.tabs);
tabs.setViewPager(viewPager);
}
class MyAdapter extends FragmentPagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
Fragment fragment = null;
if (i == 0)
fragment = new ReminderFragment();
if (i == 1)
fragment = new EventFragment();
if (i == 2)
fragment = new InvitationFragment();
return fragment;
}
#Override
public CharSequence getPageTitle(int position) {
if (position == 0)
return "Reminders";
if (position == 1)
return "Events";
if (position == 2)
return "Invitations";
return null;
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return 3;
}
}
#Override
protected void onResume() {
super.onResume();
if(notificationExtra==1){
viewPager.setCurrentItem(2);
}
}
}
the onclick in my 2nd page .
FragmentManager fragmentManager2 = getFragmentManager();
FragmentTransaction fragmentTransaction2 = fragmentManager2.beginTransaction();
InvitedEventsFragment fragment2 = new InvitedEventsFragment();
fragmentTransaction2.hide(EventFragment.this);
fragmentTransaction2.add(R.id.viewpager, fragment2);
fragmentTransaction2.commit();
My InvitedEventsFragment.java
public class InvitedEventsFragment extends Fragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater,
#Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_invited_events_fragment, container, false);
}
return view;
} }
My activity_invited_events_fragment.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#android:color/black">
<Button
android:id="#+id/btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/appbarcol2"
android:text="New Fragment"
android:textAllCaps="true"
android:textColor="#android:color/white"
android:textStyle="bold" /> </LinearLayout>
Can someone tell me why it doesn't show anything i the new fragment.
If you're using a ViewPager, the adapter should manage the Fragments.
import android.app.Fragment;
import android.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import java.util.List;
public class ExampleAdapter extends FragmentPagerAdapter
{
List<Fragment> fragmentList;
public ExampleAdapter(FragmentManager fm, List<Fragment> fragmentList)
{
super(fm);
this.fragmentList = fragmentList;
}
#Override public Fragment getItem(int position)
{
return fragmentList.get(position);
}
#Override public int getCount()
{
return fragmentList.size();
}
public void removeItem(int position, ViewPager pager)
{
pager.setAdapter(null);
this.fragmentList.remove(position);
pager.setAdapter(this);
}
}
How can I lock paging in fragment activity of viewpager for fragment swipe.I'm performing some operations using progressbar in one fragment.While progressing progressbar fragment gets changes because of swipe action.so while progessing progressbar I want to stop swiping.How to do this?is there any solution??
activity.xml file-
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainFragmentActivity" >
<android.support.v4.view.PagerTitleStrip
android:id="#+id/pager_title_strip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:background="#drawable/title"
android:paddingBottom="4dp"
android:paddingTop="4dp"
android:textColor="#fff" />
</android.support.v4.view.ViewPager>
fragment activity-
public class MainFragmentActivity extends FragmentActivity {
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
private Context mContext;
private PagerTitleStrip pt;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager(),mContext);
mContext=this;
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
pt=(PagerTitleStrip) findViewById(R.id.pager_title_strip);
}
SectionsPagerAdapter-
public class SectionsPagerAdapter extends FragmentPagerAdapter {
Context mContext;
Fragment fragment;
public SectionsPagerAdapter(FragmentManager fm, Context context) {
super(fm);
mContext=context;
}
#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.
if(position==0){
fragment = new SelectItem();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, position + 1);
fragment.setArguments(args);
}
if(position==1){
fragment = new culation();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, position + 1);
fragment.setArguments(args);
}
if(position==2){
fragment = new GraphDisplay();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, position + 1);
fragment.setArguments(args);
}
return fragment;
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0 :
return "Select item";
case 1:
return "Calculation";
case 2:
return "Graph";
}
return null;
}
}
Try setting clickable to false:
mViewPager.setClickable(false);
If that works what you can do is create a function in activity to disable swipe event on view pager and call that function in fragment in event of progress bar show and a function to enable it.
Subclass ViewPager and override onTouch event for example:
EDIT
public class NonSwipeableViewPager extends ViewPager {
private boolean lock;
public void lock(){
lock=true;
}
public void unlock(){
lock=false;
}
public NonSwipeableViewPager(Context context) {
super(context);
}
public NonSwipeableViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if(lock)
return false;else{
return super.onTouchEvent(event);
}
}
}
reference:
How do disable paging by swiping with finger in ViewPager but still be able to swipe programmatically?
I found a simple way to do this, with its adapter.
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
/**
* Created by paul.boldijar on 2/24/2015.
*/
public class SimpleFragmentAdapter extends FragmentPagerAdapter {
private Fragment[] fragments;
private boolean locked = false;
private int lockedIndex;
public void setLocked(boolean locked, int page) {
this.locked = locked;
lockedIndex = page;
notifyDataSetChanged();
}
public SimpleFragmentAdapter(FragmentManager fm, Fragment[] fragments) {
super(fm);
this.fragments = fragments;
}
#Override
public Fragment getItem(int position) {
if (locked) return fragments[lockedIndex];
return fragments[position];
}
#Override
public int getCount() {
if (locked) return 1;
return fragments.length;
}
}
If you want to lock your fragment to a page, just call fragment.setLocked(true,page);
Where page is the index of the page you want to lock.
Based on the solution by Paul, I modified it to support displaying titles as well
public static class MainPagerAdapter extends FragmentStatePagerAdapter {
private Fragment[] fragments;
private String[] titles;
private boolean locked = false;
private int lockedIndex;
public MainPagerAdapter(FragmentManager fm, Fragment[] fragments, String[] titles) {
super(fm);
this.fragments = fragments;
this.titles = titles;
}
public void setLocked(boolean locked, int page) {
this.locked = locked;
lockedIndex = page;
notifyDataSetChanged();
}
#Override
public Fragment getItem(int position) {
if (locked) return fragments[lockedIndex];
return fragments[position];
}
#Override
public int getCount() {
if (locked) return 1;
return fragments.length;
}
#Override
public CharSequence getPageTitle(int position) {
if (locked) return titles[lockedIndex];
return titles[position];
}
}
The way I use it is to say
Fragment[] fragments = {//Create fragment objects here...};
String[] titles = getResources().getStringArray(R.array.tabs);
MainPagerAdapter adapter = new MainPagerAdapter(getSupportFragmentManager(), fragments, titles);
adapter.setLocked(true, 0);
mPager.setAdapter(adapter);
You can use this View:
https://github.com/mr-sarsarabi/lockableViewPager
It lets you lock the swipe gesture with a method: viewPager.setSwipeLocked(true);
I have an activity that has a viewpager fragment in it
one of the pages has another viewpager fragment in it
the problem is, when i reach the page of the inner viewpager fragment, the "onCreateView" of the inner viewpager fragments doesnt get called, and so the page is blank.
Why is that ?
here is my code :
fragment_viewpager.xml
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1" >
</android.support.v4.view.ViewPager>
fragment_viewpager_with_logo.xml
<include layout="#layout/logo" />
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="0px"
android:layout_weight="1" >
</android.support.v4.view.ViewPager>
public class ViewPagerFragment extends Fragment {
private ViewPager fragmentPager;
private PagerAdapter fragmentAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (container instanceof ViewPager) {
return inflater.inflate(R.layout.fragment_viewpager_with_logo, container, false);
}
return inflater.inflate(R.layout.fragment_viewpager, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
fragmentPager = (ViewPager)getView().findViewById(R.id.pager);
fragmentPager.setAdapter(fragmentAdapter);
}
public void setAdapter(PurchaseFragmentStatePagerAdapter fragmentAdapter) {
this.fragmentAdapter = fragmentAdapter;
}
public void setCurrentItem(int i) {
fragmentPager.setCurrentItem(i);
}
public int getCurrentItem() {
return fragmentPager.getCurrentItem();
}
public void setOnPageChangeListener(OnPageChangeListener l) {
if (fragmentPager == null) {
fragmentPager = (ViewPager) getView().findViewById(R.id.pager);
}
fragmentPager.setOnPageChangeListener(l);
}
}
in some activity :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_container);
MyFragmentStatePagerAdapter fragmentAdapter = new MyStatePagerAdapter(getSupportFragmentManager());
List<Fragment> fragments = new ArrayList<Fragment>();
fragments.add(settingsFragment);// settings
ViewPagerFragment vpFragment = new ViewPagerFragment();
fragments.add(vpFragment);
fragmentAdapter.setFragments(fragments);
fragmentPager.setAdapter(fragmentAdapter);
MyFragmentStatePagerAdapter innerFragmentAdapter = new MyFragmentStatePagerAdapter(getSupportFragmentManager());
List<Fragment> innerFragments = new ArrayList<Fragment>();
innerFragments.add(settingsFragment);
innerFragmentAdapter.setFragments(innerFragments);
vpFragment.setAdapter(innerFragmentAdapter);
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.content_fragment, fragmentPager).commit();
}
MyFragmentStatePagerAdapter
public class MyFragmentStatePagerAdapter extends FragmentStatePagerAdapter {
private List<BaseFragment> fragments;
#Inject
public MyFragmentStatePagerAdapter(FragmentManager fm) {
super(fm);
}
public void setFragments(List<Fragment> fragments) {
this.fragments = fragments;
}
#Override
public BaseFragment getItem(int position) {
return fragments.get(position);
}
#Override
public int getCount() {
return fragments == null ? 0 : fragments.size();
}
}
In the Fragment use fragment.getChildFragmentManager() in FragmentPagerAdapter's constructor instead of getActivity().getFragmentManager()