I have 3 fragments (totally different from each other) and one activity (MainActivity). What I would like to do is to be able to swipe between them (with finger, not with buttons) with a transition like a TabLayout.
According to what I saw, I can do it using ViewPager. But the problem is that ViewPager uses TabLayout.
There is a way to swipe betweens fragments, using Viewpager, without TabLayout ?
This code will help you
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
Set up the child Fragments you would like to display. I made 3 child Fragments, calling them ChildFragment1, ChildFragment2, and ChildFragment3. Remember to have them extend support.v4.app.fragment. Now make layouts for all three of the Fragments. I call them child_fragment_1_layout, child_fragment_2_layout, and child_fragment_3_layout.
public class ChildFragment1 extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View rootView = inflater.inflate(R.layout.child_fragment_1_layout, container, false);
Button buttonInFragment1 = rootView.findViewById(R.id.button_1);
buttonInFragment1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getContext(), "button in fragment 1", Toast.LENGTH_SHORT).show();
}
});
return rootView;
}
}
Make an adapter for the ViewPager. You will have to extend either theFragmentPagerAdapter or the FragmentStatePagerAdapter. For this tutorial we will use the FragmentPagerAdapter . The difference between the two can be found here. After extending the FragmentPagerAdapter, you will need to call super(FragmentManager) in your constructor and implement the methods getItem(position) and getCount(). The getItem(position)method is used to return the fragment at the corresponding position, ordered from left to right. So ChildFragment1 would be at position 0, ChildFragment2 would be at position 1, and ChildFragment3 would be at position 2. The getCount() method is to count how many Fragments there are to display, and in this case, there are 3.
public class ViewPagerAdapter extends FragmentPagerAdapter {
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position)
{
case 0:
return new ChildFragment1(); //ChildFragment1 at position 0
case 1:
return new ChildFragment2(); //ChildFragment2 at position 1
case 2:
return new ChildFragment3(); //ChildFragment3 at position 2
}
return null; //does not happen
}
#Override
public int getCount() {
return 3; //three fragments
}
}
Now find your ViewPager in MainActivity and call the setAdapter() method and pass in your custom adapter. If you are doing this in another Fragment (Nested Fragments), you will have to pass in getChildFragmentManager() in the argument of your adapter instead. Now your ViewPager is all set
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager()));
}
}
Related
First off: I am aware there are a number of similar questions, however, none of the suggestions worked.
I have a ViewPager that I would like to use with fragments. The ViewPager works, and I can see in the log that I can scroll left and right. I can see the animation when I try to scroll left and there's no previous item (or right when there's no following item). However, the screen remains blank. The fragment itself is functional, however, I've tried it in a different context.
I am using the androidx namespaced packages.
Things I've tried (<--> means I've tried both):
FragmentPagerAdapter <--> FragmentStatePagerAdapter
getFragmentManager() <--> getChildFragmentManager()as the FragmentManager for the adapter
setSaveFromParentEnabled to false.
setOffscreenPageLimit to the number of fragments.
Relevant code (I have taken out sections of code that are irrelevant to this question):
The Fragment that contains the ViewPager:
public class AddListingMediaFragment extends Fragment {
private ViewPager viewPagerTop;
private AddMediaAdapter addMediaAdapter;
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_add_listing_media, container, false);
setupViewPagerTop(view);
return view;
}
private void setupViewPagerTop(View view) {
viewPagerTop = view.findViewById(R.id.view_pager_top);
addMediaAdapter = new AddMediaAdapter(getChildFragmentManager());
viewPagerTop.setAdapter(addMediaAdapter);
viewPagerTop.setSaveFromParentEnabled(false);
viewPagerTop.setOffscreenPageLimit(5);
}
}
The Adapter (please do note, as mentioned, that I've tried both FragmentPagerAdapter and FragmentStatePagerAdapter:
public class AddMediaAdapter extends FragmentPagerAdapter {
private static final String TAG = AddMediaAdapter.class.getSimpleName();
public AddMediaAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return 5;
}
#Override
public Fragment getItem(int position) {
Log.i(TAG, "getItem: " + String.valueOf(position));
return new AddListingMediaCameraFragment();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
}
The layout file:
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.viewpager.widget.ViewPager
android:id="#+id/view_pager_top"
android:layout_width="300dp"
android:layout_height="300dp"
/>
<include
layout="#layout/bottom_sheet_add_listing_media_gallery"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
You do not need to override isViewFromObject in your adapter, FragmentPagerAdapter has already taken care of it. ViewPager calls this method to decide how to render the pages.
Your view == object will return false because the object is always a Fragment not a View. So just drop the override, and it will fix the issue.
I basically have everything set up already and I don't why it's not working. The only problem I have is that the Vertical won't work when I set it up together. Look at the code down below.
My Main Acitvity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//HorizontalViewPagerAdapter
View background = findViewById(R.id.am_background_view);
ViewPager viewPager = findViewById(R.id.am_view_pager);
HorizontalViewPagerAdapter adapter = new HorizontalViewPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
viewPager.setCurrentItem(1);
}
My Controller Fragment
public class ControllerFragment extends Fragment {
public static ControllerFragment create() {
return new ControllerFragment();
}
VerticalViewPager verticalViewPager;
VerticalViewPagerAdapter verticalPageAdapter;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.vertical, null);
verticalViewPager = view.findViewById(R.id.am_scrollView);
verticalPageAdapter = new VerticalViewPagerAdapter(getChildFragmentManager());
verticalViewPager.setAdapter(verticalPageAdapter);
return inflater.inflate(R.layout.vertical, null);
}
public class VerticalViewPagerAdapter extends FragmentPagerAdapter {
public VerticalViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return SettingsFragment.create();
case 1:
return EmptyFragment.create();
case 2:
return ExtrasFragment.create();
}
return null;
}
#Override
public int getCount() {
return 3;
}
}
}
This is my HorizontalAdapter
public class HorizontalViewPagerAdapter extends FragmentPagerAdapter {
public HorizontalViewPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return ChatFragment.create();
case 1:
return ControllerFragment.create();
case 2:
return StoryFragment.create();
}
return null;
}
#Override
public int getCount() {
return 3;
}
Its like the whole code is completely ignoring the VerticalView Pager because it doesnt show at all in my app and its completely the same as a normal ViewPager
Having understood what you want to achieve, here's how you'd achieve it!
There are 6 fragments in total.
Home
Left
Right
Top
Botton
Controller
Update
The previous method overrides and prevents horizontal gestures from being captured. I've searched a bit and found an alternative.
First of all, you need a different vertical pager library. I tried the one here and it works perfectly.
So what you wanna do is, get that java file on your project and change your controller's XML like this
<?xml version="1.0" encoding="utf-8"?>
<c.kristofer.jax2.VerticalPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/am_scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/top"
class="c.kristofer.jax2.Fragments.SettingsFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<fragment
android:id="#+id/home"
class="c.kristofer.jax2.Fragments.HomeFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<fragment
android:id="#+id/bottom"
class="c.kristofer.jax2.Fragments.SettingsFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</c.kristofer.jax2.VerticalPager>
This ViewPager does not take an adapter, rather it takes <fragment> tags for its child views. The Controller's java code will also change a bit
VerticalPager verticalViewPager = view.findViewById(R.id.am_scrollView);
verticalViewPager.snapToPage(1);
The result can be seen here. You can play around with the code and see what suits you best.
Previous Method
The activity will have one of the ViewPagers, either the Horizontal one or the Vertical one. The middle fragment of that ViewPager will be the Controller. Controller will be responsible for the second ViewPager. The middle fragment of this ViewPager will be Home.
This way, you will have 2 degrees of freedom from the Activity, and 2 degrees of freedom from the Controller.
How to add a listview inside a viewpager (without using fragments)? Could you please help me? Thanks in advance.
It will be easy if you use Fragment in ViewPager, BUT if you dont want to use ViewPager with Fragment than ViewPager Without Fragments is example where you add Views and layouts to ViewPager and is more complex.
A good example is an image gallery, where the user can swipe between different pictures. On these types of pages, all you really want to display is a view of static content (in this case, an image), how to utilize the ViewPager with just plain-old Views and layouts.
It will be best to use fragment for each pages of viewPager. In this way you will be able to maintain individual pages easily.
In your fragment class(a java class which extends Fragment) you can work with your listview like initializing,setting adapter to listview,setting onClickListner for listview items same as you do in Activity
You can't use ViewPager to swipe between Activities. You need to convert each of you Activities into Fragments, then combine everything in one FragmentActivity with the Adapter you use with ViewPager.
This is not how ViewPager works. You feed the pages to ViewPager with a PagerAdapter. Your ListView will be contained within a Fragment created by the PagerAdapter.
In the layout:
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/home_pannels_pager" />
In the FragmentActivity with this layout:
ViewPager pager = (ViewPager) findViewById(R.id.viewPager);
pager.setAdapter(new PagerAdapter(getSupportFragmentManager()));
Example of simle PagerAdapter:
public class PagerAdapter extends FragmentPagerAdapter {
public FrontPageAdapter(FragmentManager Fm) {
super(Fm);
}
#Override
public Fragment getItem(int position) {
Bundle arguments = new Bundle();
arguments.putInt("position", position);
FragmentPage fragment = new FragmentPage();
fragment.setArguments(arguments);
return fragment;
}
#Override
public int getCount() {
// return count of pages
return 3;
}
}
Example of FragmentPage:
public class FragmentPage extends Fragment {
public FragmentPage() {}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_frontpage, container, false);
// probably cast to ViewGroup and find your ListView
Bundle arguments = getArguments();
int position = b.getInt("position");
return view;
}
}
Answered here - https://stackoverflow.com/a/28798795/7764015
I am using a ViewPager to show 9 fragments. In each of these fragments, I want to just show a different picture. I want to use one single fragment layout, but dynamically add in the picture. Also, would like add a "Continue" button on the last fragment that when pressed will go to another activity.
How do I go about making a fragment layout dynamic?
Main Activity
public class StoryboardPageActivity extends FragmentActivity {
// The number of pages (wizard steps) to show in this demo.
private static final int NUM_PAGES = 9;
// The pager widget, which handles animation and allows swiping horizontally to access previous and next wizard steps.
private ViewPager mPager;
// The pager adapter, which provides the pages to the view pager widget.
private PagerAdapter mPagerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_storyboard_page);
// Instantiate a ViewPager and a PagerAdapter.
mPager = (ViewPager) findViewById(R.id.storyboardPager);
mPagerAdapter = new StoryboardPagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter);
}
#Override
public void onBackPressed() {
if (mPager.getCurrentItem() == 0) {
// If the user is currently looking at the first step, allow the system to handle the
// Back button. This calls finish() on this activity and pops the back stack.
super.onBackPressed();
} else {
// Otherwise, select the previous step.
mPager.setCurrentItem(mPager.getCurrentItem() - 1);
}
}
// A simple pager adapter that represents 5 fragment objects, in sequence.
private class StoryboardPagerAdapter extends FragmentStatePagerAdapter {
public StoryboardPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return StoryboardFragment.newInstance(position);
}
#Override
public int getCount() {
return NUM_PAGES;
}
}
}
Fragment
public class StoryboardFragment extends Fragment {
private static final String KEY_POSITION = "position";
static StoryboardFragment newInstance(int position) {
StoryboardFragment frag = new StoryboardFragment();
Bundle args = new Bundle();
args.putInt(KEY_POSITION, position);
frag.setArguments(args);
return(frag);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_storyboard_page, container, false);
ImageView image = (ImageView)rootView.findViewById(R.id.imgStoryboard);
int position = getArguments().getInt(KEY_POSITION, -1);
int[] images = {R.drawable.storyboard1, R.drawable.storyboard2, R.drawable.storyboard3,
R.drawable.storyboard4, R.drawable.storyboard5, R.drawable.storyboard6,
R.drawable.storyboard7, R.drawable.storyboard8, R.drawable.storyboard9};
image.setImageResource(images[position]);
return rootView;
}
}
Fragment XML
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff" >
<ImageView
android:id="#+id/imgStoryboard"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:contentDescription="#string/storyboardSlide" />
</RelativeLayout>
How do I go about making a fragment layout dynamic?
The same way you make any other "layout dynamic". If you want to put an image in an ImageView, call setImageBitmap() or setImageDrawable() or whatever. For example, the PagerAdapter could supply the position to the fragment (via a factory method), and the fragment could then know what image to load.
This sample project demonstrates populating the hint of an EditText with a custom value based upon the page's position.
With respect to the "Continue" button, either have a separate fragment class for that (and appropriate smarts in your PagerAdapter, or always have the button in your layout, but set to android:visibility="gone" by default, toggling it via setVisibility(View.VISIBLE) for the fragment that needs it.
I have five activities/screens that I would like to be able to swipe between, each has a different function but are interrelated hence the UI concept of swiping between each.
I have found many discussions around ViewPager and PagerAdapters etc. but cannot seem to find one where swiping switches between different activity screens.
Is this even possible? Could someone point me towards an example project of this with source code? Or show me how to adapt an existing tutorial to do what I wish?
Thanks so much, have a good one!
You can't use ViewPager to swipe between Activities. You need to convert each of you five Activities into Fragments, then combine everything in one FragmentActivity with the Adapter you use with ViewPager.
Here's a link that goes into detail on converting your current Activities info Fragments.
This is the Fragment topic on the Android Developers website, it has a lot of useful info.
Here's another example (full source) that inflates TextViews on each page.
Here's an example that I typed up:
PagerAdapter:
public class PagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragments = new ArrayList<Fragment>();
public PagerAdapter(FragmentManager manager) {
super(manager);
}
public void addFragment(Fragment fragment) {
mFragments.add(fragment);
notifyDataSetChanged();
}
#Override
public int getCount() {
return mFragments.size();
}
#Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
}
This should be called in onCreate of your FragmentActivity:
private void initPaging() {
FragmentOne fragmentOne = new FragmentOne();
FragmentTwo fragmentTwo= new FragmentTwo();
PagerAdapter pagerAdapter = new PagerAdapter(getSupportFragmentManager());
pagerAdapter.addFragment(fragmentOne);
pagerAdapter.addFragment(fragmentTwo);
ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);
viewPager.setAdapter(pagerAdapter);
}
This is an example of the layout you'd use for your FragmnetActivity:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<android.support.v4.view.ViewPager
android:id="#+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
To create Fragment create a new class that extends Fragment. The first two methods you'll want to override are onActivityCreated and onCreateView.
Here's how you could do that:
public class FragmentOne extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(THE_LAYOUT_FROM_YOUR_ORIGINAL_ACTIVITY, container, false);
return view;
}
}
Fix For mPageradapter
PagerAdapter pagerAdapter = new PagerAdapter(getSupportFragmentManager());
pagerAdapter.addFragment(fragmentOne);
pagerAdapter.addFragment(fragmentEvents);
viewPager = (ViewPager) super.findViewById(R.id.pager);
viewPager.setAdapter(pagerAdapter);