Display Fragment Viewpager Within a Fragment

Display fragment viewpager within a fragment

use AsyncTask to set the adapter for viewPager. It works for me. The asyncTask is to make the original fragment complete it's transition. and then we proceed with viewPager fragments, basically to avoid recursion.

 @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

mView = inflater.inflate(R.layout.team_card_master, container, false);
mViewPager = (ViewPager)mView.findViewById(R.id.team_card_master_view_pager);

final Button button = (Button)mView.findViewById(R.id.load_viewpager_button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mViewPager.setAdapter(mAdapter);
button.setVisibility(View.GONE);
}
});

mAdapter = new ViewPagerAdapter(getFragmentManager());
new setAdapterTask().execute();

return mView;
}

private class setAdapterTask extends AsyncTask<Void,Void,Void>{
protected Void doInBackground(Void... params) {
return null;
}

@Override
protected void onPostExecute(Void result) {
mViewPager.setAdapter(mAdapter);
}
}

How to put viewpager inside fragment in android?

To have a ViewPager be in a fragment, and to have fragments be the pages in that ViewPager, you need to use nested fragments. If your minSdkVersion is 17 or higher, the native implementation of fragments supports nested fragments. Otherwise, you will need to use the support-v13 (or support-v4) backport of fragments.

Then, you just need to give getChildFragmentManager() to your FragmentPagerAdapter or FragmentStatePagerAdapter:

/***
Copyright (c) 2012 CommonsWare, LLC
Licensed under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required
by applicable law or agreed to in writing, software distributed under the
License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
OF ANY KIND, either express or implied. See the License for the specific
language governing permissions and limitations under the License.

From _The Busy Coder's Guide to Android Development_
http://commonsware.com/Android
*/

package com.commonsware.android.pagernested;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class PagerFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View result=inflater.inflate(R.layout.pager, container, false);
ViewPager pager=(ViewPager)result.findViewById(R.id.pager);

pager.setAdapter(buildAdapter());

return(result);
}

private PagerAdapter buildAdapter() {
return(new SampleAdapter(getActivity(), getChildFragmentManager()));
}
}

(from this sample project)

How to display fragment in viewpager, in fragment class?

I'm doing something similar right now. I only have the the ViewPager below the navigation drawer, but if you have a more complicated layout the same principal should work.

To start, I have the activity layout (most of this was generated by Android Studio)

<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.you.yourapp.YourActivity">

<FrameLayout android:id="@+id/your_container" android:layout_width="match_parent"
android:layout_height="match_parent" />

<fragment android:id="@+id/navigation_drawer"
android:layout_width="@dimen/navigation_drawer_width" android:layout_height="match_parent"
android:layout_gravity="start"
android:name="com.example.you.yourapp.NavigationDrawerFragment"
tools:layout="@layout/fragment_navigation_drawer" />

</android.support.v4.widget.DrawerLayout>

The activity uses the FragmentManager to swap in another fragment that contains the ViewPager into the FrameLayout

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_your);

...

Fragment fragment = YourFragment.newInstance(Bundle args);
getSupportFragmentManager()
.beginTransaction().replace(R.id.your_container, fragment)
.commit();
}

The Fragment that has the ViewPager is simple

<android.support.v4.view.ViewPager android:id="@+id/your_view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

in YourFragment.java implement your FragmentPagerAdapter(you could do this as an inner class, but I ran into problems with static allocation, plus this is cleaner)

public class YourFragment extends android.support.v4.app.Fragment {

private ViewPager mPager;

public YourFragment() {

}

public static TaskFragment newInstance(Uri uri, String outlineText) {
TaskFragment fragment = new YourFragment();

Bundle args = new Bundle();
//set args
fragment.setArguments(args);

return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

...
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.fragment_your, null);
mPager = (ViewPager) rootView.findViewById(R.id.your_view_pager);

TaskPagerAdapter adapter = new TaskPagerAdapter(getFragmentManager());
mPager.setAdapter(adapter);

return rootView;
}

...

private class YourPagerAdapter extends FragmentStatePagerAdapter {

public YourPagerAdapter(FragmentManager fm) {
super(fm);
}

@Override
public int getCount() {
return count; //however you get the count
}

@Override
public android.support.v4.app.Fragment getItem(int position) {
//set the arguments for your page
return PageFragment.newInstance(args);
}

}

}

ETA:
So now implement a custom interface for your navigation drawer callbacks

...
private NavigationDrawerCallbacks mCallbacks

@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mCallbacks = (NavigationDrawerCallbacks) activity;
}

...

@Override
public void onClick(View view) { //whatever your click listener is
Fragment fragment = getFragmentSomehow(); //get your fragment
mCallbacks.onNavigationItemSelected(fragment);
}

...

public static interface NavigationDrawerCallbacks {
void onNavigationDrawerItemSelected(Fragment fragment);
}

Now have YourActivity implement this interface

public class YourFragment extends Activity
implements NavigationDrawerCallbacks
{

...

@Override
public void onNavigationDrawerItemSelected(Fragment fragment) {
getSupportFragmentManeger()
.beginTransaction()
.replace(R.id.you_container, fragment)
.commit();
}
...
}

I think this is what you mean to do.
Hope this helps

How to set a ViewPager inside a Fragment

Starting in Android 4.2, there are nested fragments.http://developer.android.com/about/versions/android-4.2.html#NestedFragments The support library now also includes support for this for older Android versions.

So you can do something like this:

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);

ViewPager mViewPager = (ViewPager) view.findViewById(R.id.viewPager);
mViewPager.setAdapter(new MyAdapter(getChildFragmentManager()));
}

Full implementation available here: https://github.com/marcoRS/nested-fragments/tree/master/src/com/burnside/digital/nestedfragments

Why it is not possible to use ViewPager within a Fragment? It actually is

UPDATE: Since this answer was originally written, you now can have nested fragments, which means it is possible to have a ViewPager use fragments for pages and be in a fragment itself. This sample project demonstrates the technique.

I now return you to your regularly-scheduled answer, presented in its entirety...


Quoting myself from the book:

The simplest way to use a ViewPager is to have it page fragments in and out of the
screen based on user swipes. This only works if the ViewPager itself is not contained
within a fragment, as you cannot have fragments nested inside of other fragments.

Quoting Dianne Hackborn:

Nested fragments are not currently supported. Trying to put a fragment within the UI of another fragment will result in undefined and likely broken behavior.

It is perfectly possible to put a ViewPager inside a Fragment, so long as the contents of the ViewPager do not themselves contain fragments. Since the concrete implementations of PagerAdapter supplied by the Android Support package use fragments, you have to roll your own fragment-less PagerAdapter to put the ViewPager in a fragment.

I will endeavor to make this point clearer in the next edition of the book (unless you're British, in which case I'll endeavour to make this point clearer :-).

Add ViewPager in Fragment in Android

In FirstFragment , Use this code and try

public View view; // declare view as global variable

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
if(view == null){
view = inflater.inflate(R.layout.first_fragment, null);
mViewPager = (ViewPager) view.findViewById(R.id.view_pager);
ViewPagerAdapter adapter = new ViewPagerAdapter(mainActivity.getSupportFragmentManager());
mViewPager.setAdapter(adapter);
}
return view;
}

As Divyesh comment has good suggestion there is also need to add

mViewPager.setOffscreenPageLimit(3);

Showing a fragment over a viewpager

I solved it by adding the viewpager in a fragment(instead of having it directly in my activity itself).

My activity now is

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />

and I moved the previous activity layout (mentioned in the question) to a ViewPagerFragment

Now in my activity's onCreate I do

ViewPagerFragment viewPagerFragment = new ViewPagerFragment();

getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, viewPagerFragment)
.commit();

and for showing a new fragment over the viewpager on clicking an item inside the viewpager's fragment, I do

listView.setOnItemClickListener(new AdapterView.OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mListener.onFragmentInteraction(null);
}
});

The listener is an interface implemented in the parent activity as follows

@Override
public void onFragmentInteraction(Uri uri) {
ItemDetailFragment itemDetailFragment = ItemDetailFragment.newInstance("ab","cd");
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container,itemDetailFragment)
.addToBackStack(null)
.commit();
}

I implemented this via the listener interface because as per the docs

All Fragment-to-Fragment communication is done through the associated Activity. Two Fragments should never communicate directly.

And it works now! :D

Fragment with ViewPager inside Fragment and FragmentStatePagerAdapter results in Exception (with complete example)

Add an additional FrameLayout to your layout of the main activity. This is where you put the Fragment.

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >

<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="Button1" />

<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="Button2" />
<!-- add this -->
<FrameLayout
android:id="@+id/fragment_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" >

</FrameLayout>

</LinearLayout>

</FrameLayout>

Since you are adding your Fragments to the BackStack, there is no need for saving an instance of them. This is the reason why you app crashes. Adjust your onClick() method as follows:

    @Override
public void onClick(View v)
{
Fragment nextFragment = null;
String nextFragmentTag = null;
if (v.getId() == R.id.button1)
{
nextFragment = ContainerFragment.newInstance(1);
nextFragmentTag = "fragment1";
}
else if (v.getId() == R.id.button2)
{
nextFragment = ContainerFragment.newInstance(2);
nextFragmentTag = "fragment2";
}

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_frame, nextFragment, nextFragmentTag);
transaction.addToBackStack(null);
transaction.commit();
}

I tested the code. Changing the Fragments with the buttons works, and
the state the ViewPager was left when returing to it is preserved.



Related Topics



Leave a reply



Submit