(I figured out a solution - please see my post in the Answer section below.)
In my app, the user will start with a single view of his data. I'd like to add a ViewPager and allow the user to add more views as desired. How do I do this? (I dont' want to use the FragmentPagerAdapter.)
I've read countless posts and overviews but am still missing something. Here's what I think I understand:
MainActivity creates a ViewPager and PagerAdapter:
ViewPager pager = null;
MainPagerAdapter adapter = null;
public void onCreate (Bundle savedInstanceState)
{
super.onCreate (savedInstanceState);
pager = new ViewPager (this);
setContentView (pager);
adapter = new MainPagerAdapter();
pager.setAdapter (adapter);
View v0 = code_to_create_initial_view();
adapter.add (v0, 0);
}
Use a PagerAdapter to provide the sets of view. For this it seems I need methods to add and remove views, something like this; obviously more is needed to tell the ViewPager stuff has changed and how to show the change:
class MainPagerAdapter extends PagerAdapter
{
// This holds all the currently displayable views, in order from left to right.
private ArrayList<View> views = new ArrayList<View>();
public void addView (View v, int position)
{
views.add (position, v);
}
public void removeView (int position)
{
views.remove (position);
}
}
In addition, I need to implement the following vitual methods. I'm lost here - what calls them and what are they supposed to do (ok, getCount is obvious)?
public object instantiateItem (ViewGroup pager, int position);
public void destroyItem (ViewGroup, int, Object);
public int getCount ();
public boolean isViewFromObject (View, Object);
What are the ViewGroup params for - isn't the containing group the ViewPager itself?
What does isViewFromObject do - how does an object get associated with a view in the first place?
Should I be calling startUpdate and finishUdate when I add or remove views?
Thanks.
After figuring out which ViewPager methods are called by ViewPager and which are for other purposes, I came up with a solution. I present it here since I see a lot of people have struggled with this and I didn't see any other relevant answers.
First, here's my adapter; hopefully comments within the code are sufficient:
public class MainPagerAdapter extends PagerAdapter
{
// This holds all the currently displayable views, in order from left to right.
private ArrayList<View> views = new ArrayList<View>();
//-----------------------------------------------------------------------------
// Used by ViewPager. "Object" represents the page; tell the ViewPager where the
// page should be displayed, from left-to-right. If the page no longer exists,
// return POSITION_NONE.
#Override
public int getItemPosition (Object object)
{
int index = views.indexOf (object);
if (index == -1)
return POSITION_NONE;
else
return index;
}
//-----------------------------------------------------------------------------
// Used by ViewPager. Called when ViewPager needs a page to display; it is our job
// to add the page to the container, which is normally the ViewPager itself. Since
// all our pages are persistent, we simply retrieve it from our "views" ArrayList.
#Override
public Object instantiateItem (ViewGroup container, int position)
{
View v = views.get (position);
container.addView (v);
return v;
}
//-----------------------------------------------------------------------------
// Used by ViewPager. Called when ViewPager no longer needs a page to display; it
// is our job to remove the page from the container, which is normally the
// ViewPager itself. Since all our pages are persistent, we do nothing to the
// contents of our "views" ArrayList.
#Override
public void destroyItem (ViewGroup container, int position, Object object)
{
container.removeView (views.get (position));
}
//-----------------------------------------------------------------------------
// Used by ViewPager; can be used by app as well.
// Returns the total number of pages that the ViewPage can display. This must
// never be 0.
#Override
public int getCount ()
{
return views.size();
}
//-----------------------------------------------------------------------------
// Used by ViewPager.
#Override
public boolean isViewFromObject (View view, Object object)
{
return view == object;
}
//-----------------------------------------------------------------------------
// Add "view" to right end of "views".
// Returns the position of the new view.
// The app should call this to add pages; not used by ViewPager.
public int addView (View v)
{
return addView (v, views.size());
}
//-----------------------------------------------------------------------------
// Add "view" at "position" to "views".
// Returns position of new view.
// The app should call this to add pages; not used by ViewPager.
public int addView (View v, int position)
{
views.add (position, v);
return position;
}
//-----------------------------------------------------------------------------
// Removes "view" from "views".
// Retuns position of removed view.
// The app should call this to remove pages; not used by ViewPager.
public int removeView (ViewPager pager, View v)
{
return removeView (pager, views.indexOf (v));
}
//-----------------------------------------------------------------------------
// Removes the "view" at "position" from "views".
// Retuns position of removed view.
// The app should call this to remove pages; not used by ViewPager.
public int removeView (ViewPager pager, int position)
{
// ViewPager doesn't have a delete method; the closest is to set the adapter
// again. When doing so, it deletes all its views. Then we can delete the view
// from from the adapter and finally set the adapter to the pager again. Note
// that we set the adapter to null before removing the view from "views" - that's
// because while ViewPager deletes all its views, it will call destroyItem which
// will in turn cause a null pointer ref.
pager.setAdapter (null);
views.remove (position);
pager.setAdapter (this);
return position;
}
//-----------------------------------------------------------------------------
// Returns the "view" at "position".
// The app should call this to retrieve a view; not used by ViewPager.
public View getView (int position)
{
return views.get (position);
}
// Other relevant methods:
// finishUpdate - called by the ViewPager - we don't care about what pages the
// pager is displaying so we don't use this method.
}
And here's some snips of code showing how to use the adapter.
class MainActivity extends Activity
{
private ViewPager pager = null;
private MainPagerAdapter pagerAdapter = null;
//-----------------------------------------------------------------------------
#Override
public void onCreate (Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView (R.layout.main_activity);
... do other initialization, such as create an ActionBar ...
pagerAdapter = new MainPagerAdapter();
pager = (ViewPager) findViewById (R.id.view_pager);
pager.setAdapter (pagerAdapter);
// Create an initial view to display; must be a subclass of FrameLayout.
LayoutInflater inflater = context.getLayoutInflater();
FrameLayout v0 = (FrameLayout) inflater.inflate (R.layout.one_of_my_page_layouts, null);
pagerAdapter.addView (v0, 0);
pagerAdapter.notifyDataSetChanged();
}
//-----------------------------------------------------------------------------
// Here's what the app should do to add a view to the ViewPager.
public void addView (View newPage)
{
int pageIndex = pagerAdapter.addView (newPage);
// You might want to make "newPage" the currently displayed page:
pager.setCurrentItem (pageIndex, true);
}
//-----------------------------------------------------------------------------
// Here's what the app should do to remove a view from the ViewPager.
public void removeView (View defunctPage)
{
int pageIndex = pagerAdapter.removeView (pager, defunctPage);
// You might want to choose what page to display, if the current page was "defunctPage".
if (pageIndex == pagerAdapter.getCount())
pageIndex--;
pager.setCurrentItem (pageIndex);
}
//-----------------------------------------------------------------------------
// Here's what the app should do to get the currently displayed page.
public View getCurrentPage ()
{
return pagerAdapter.getView (pager.getCurrentItem());
}
//-----------------------------------------------------------------------------
// Here's what the app should do to set the currently displayed page. "pageToShow" must
// currently be in the adapter, or this will crash.
public void setCurrentPage (View pageToShow)
{
pager.setCurrentItem (pagerAdapter.getItemPosition (pageToShow), true);
}
}
Finally, you can use the following for your activity_main.xml layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</android.support.v4.view.ViewPager>
I was looking for simple solution to remove views from viewpager (no fragments) dynamically. So, if you have some info, that your pages belongs to, you can set it to View as tag. Just like that (adapter code):
#Override
public Object instantiateItem(ViewGroup collection, int position)
{
ImageView iv = new ImageView(mContext);
MediaMessage msg = mMessages.get(position);
...
iv.setTag(media);
return iv;
}
#Override
public int getItemPosition (Object object)
{
View o = (View) object;
int index = mMessages.indexOf(o.getTag());
if (index == -1)
return POSITION_NONE;
else
return index;
}
You just need remove your info from mMessages, and then call notifyDataSetChanged() for your adapter. Bad news there is no animation in this case.
There are quite a few discussions around this topic
ViewPager PagerAdapter not updating the View
Update ViewPager dynamically?
Removing fragments from FragmentStatePagerAdapter
Although we see it often, using POSITION_NONE does not seem to be the way to go as it is very inefficient memory-wise.
Here in this question, we should consider using Alvaro's approach:
... is to setTag() method in
instantiateItem() when instantiating a new view. Then instead of using
notifyDataSetChanged(), you can use findViewWithTag() to find the view
you want to update.
Here is a SO answer with code based on this idea
I did a similar program. hope this would help you.In its first activity four grid data can be selected. On the next activity, there is a view pager which contains two mandatory pages.And 4 more pages will be there, which will be visible corresponding to the grid data selected.
Following is the mainactivty
MainActivity
package com.example.jeffy.viewpagerapp;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.os.Parcel;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.GridView;
import java.lang.reflect.Array;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
SharedPreferences pref;
SharedPreferences.Editor editor;
GridView gridView;
Button button;
private static final String DATABASE_NAME = "dbForTest.db";
private static final int DATABASE_VERSION = 1;
private static final String TABLE_NAME = "diary";
private static final String TITLE = "id";
private static final String BODY = "content";
DBHelper dbHelper = new DBHelper(this);
ArrayList<String> frags = new ArrayList<String>();
ArrayList<FragmentArray> fragmentArray = new ArrayList<FragmentArray>();
String[] selectedData;
Boolean port1=false,port2=false,port3=false,port4=false;
int Iport1=1,Iport2=1,Iport3=1,Iport4=1,location;
// This Data show in grid ( Used by adapter )
CustomGridAdapter customGridAdapter = new CustomGridAdapter(MainActivity.this,GRID_DATA);
static final String[ ] GRID_DATA = new String[] {
"1" ,
"2",
"3" ,
"4"
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
frags.add("TabFragment3");
frags.add("TabFragment4");
frags.add("TabFragment5");
frags.add("TabFragment6");
dbHelper = new DBHelper(this);
dbHelper.insertContact(1,0);
dbHelper.insertContact(2,0);
dbHelper.insertContact(3,0);
dbHelper.insertContact(4,0);
final Bundle selected = new Bundle();
button = (Button) findViewById(R.id.button);
pref = getApplicationContext().getSharedPreferences("MyPref", MODE_PRIVATE);
editor = pref.edit();
gridView = (GridView) findViewById(R.id.gridView1);
gridView.setAdapter(customGridAdapter);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//view.findViewById(R.id.grid_item_image).setVisibility(View.VISIBLE);
location = position + 1;
if (position == 0) {
Iport1++;
Iport1 = Iport1 % 2;
if (Iport1 % 2 == 1) {
//dbHelper.updateContact(1,1);
view.findViewById(R.id.grid_item_image).setVisibility(View.VISIBLE);
dbHelper.updateContact(1,1);
} else {
//dbHelper.updateContact(1,0);
view.findViewById(R.id.grid_item_image).setVisibility(View.INVISIBLE);
dbHelper.updateContact(1, 0);
}
}
if (position == 1) {
Iport2++;
Iport1 = Iport1 % 2;
if (Iport2 % 2 == 1) {
//dbHelper.updateContact(2,1);
view.findViewById(R.id.grid_item_image).setVisibility(View.VISIBLE);
dbHelper.updateContact(2, 1);
} else {
//dbHelper.updateContact(2,0);
view.findViewById(R.id.grid_item_image).setVisibility(View.INVISIBLE);
dbHelper.updateContact(2,0);
}
}
if (position == 2) {
Iport3++;
Iport3 = Iport3 % 2;
if (Iport3 % 2 == 1) {
//dbHelper.updateContact(3,1);
view.findViewById(R.id.grid_item_image).setVisibility(View.VISIBLE);
dbHelper.updateContact(3, 1);
} else {
//dbHelper.updateContact(3,0);
view.findViewById(R.id.grid_item_image).setVisibility(View.INVISIBLE);
dbHelper.updateContact(3, 0);
}
}
if (position == 3) {
Iport4++;
Iport4 = Iport4 % 2;
if (Iport4 % 2 == 1) {
//dbHelper.updateContact(4,1);
view.findViewById(R.id.grid_item_image).setVisibility(View.VISIBLE);
dbHelper.updateContact(4, 1);
} else {
//dbHelper.updateContact(4,0);
view.findViewById(R.id.grid_item_image).setVisibility(View.INVISIBLE);
dbHelper.updateContact(4,0);
}
}
}
});
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
editor.putInt("port1", Iport1);
editor.putInt("port2", Iport2);
editor.putInt("port3", Iport3);
editor.putInt("port4", Iport4);
Intent i = new Intent(MainActivity.this,Main2Activity.class);
if(Iport1==1)
i.putExtra("3","TabFragment3");
else
i.putExtra("3", "");
if(Iport2==1)
i.putExtra("4","TabFragment4");
else
i.putExtra("4","");
if(Iport3==1)
i.putExtra("5", "TabFragment5");
else
i.putExtra("5","");
if(Iport4==1)
i.putExtra("6", "TabFragment6");
else
i.putExtra("6","");
dbHelper.updateContact(0, Iport1);
dbHelper.updateContact(1, Iport2);
dbHelper.updateContact(2, Iport3);
dbHelper.updateContact(3, Iport4);
startActivity(i);
}
});
}
}
Here TabFragment1,TabFragment2 etc are fragment to be displayed on the viewpager.And I am not showing the layouts since they are out of scope of this project.
MainActivity will intent to Main2Activity
Main2Activity
package com.example.jeffy.viewpagerapp;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.design.widget.CollapsingToolbarLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v4.widget.NestedScrollView;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.FrameLayout;
import java.util.ArrayList;
public class Main2Activity extends AppCompatActivity {
private ViewPager pager = null;
private PagerAdapter pagerAdapter = null;
DBHelper dbHelper;
Cursor rs;
int port1,port2,port3,port4;
//-----------------------------------------------------------------------------
#Override
public void onCreate (Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Toolbar toolbar = (Toolbar) findViewById(R.id.MyToolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
CollapsingToolbarLayout collapsingToolbar =
(CollapsingToolbarLayout) findViewById(R.id.collapse_toolbar);
NestedScrollView scrollView = (NestedScrollView) findViewById (R.id.nested);
scrollView.setFillViewport (true);
ArrayList<String > selectedPort = new ArrayList<String>();
Intent intent = getIntent();
String Tab3 = intent.getStringExtra("3");
String Tab4 = intent.getStringExtra("4");
String Tab5 = intent.getStringExtra("5");
String Tab6 = intent.getStringExtra("6");
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
tabLayout.addTab(tabLayout.newTab().setText("View"));
tabLayout.addTab(tabLayout.newTab().setText("All"));
selectedPort.add("TabFragment1");
selectedPort.add("TabFragment2");
if(Tab3!=null && !TextUtils.isEmpty(Tab3))
selectedPort.add(Tab3);
if(Tab4!=null && !TextUtils.isEmpty(Tab4))
selectedPort.add(Tab4);
if(Tab5!=null && !TextUtils.isEmpty(Tab5))
selectedPort.add(Tab5);
if(Tab6!=null && !TextUtils.isEmpty(Tab6))
selectedPort.add(Tab6);
dbHelper = new DBHelper(this);
// rs=dbHelper.getData(1);
// port1 = rs.getInt(rs.getColumnIndex("id"));
//
// rs=dbHelper.getData(2);
// port2 = rs.getInt(rs.getColumnIndex("id"));
//
// rs=dbHelper.getData(3);
// port3 = rs.getInt(rs.getColumnIndex("id"));
//
// rs=dbHelper.getData(4);
// port4 = rs.getInt(rs.getColumnIndex("id"));
Log.i(">>>>>>>>>>>>>>", "port 1" + port1 + "port 2" + port2 + "port 3" + port3 + "port 4" + port4);
if(Tab3!=null && !TextUtils.isEmpty(Tab3))
tabLayout.addTab(tabLayout.newTab().setText("Tab 0"));
if(Tab3!=null && !TextUtils.isEmpty(Tab4))
tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));
if(Tab3!=null && !TextUtils.isEmpty(Tab5))
tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
if(Tab3!=null && !TextUtils.isEmpty(Tab6))
tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
final ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
final PagerAdapter adapter = new PagerAdapter
(getSupportFragmentManager(), tabLayout.getTabCount(), selectedPort);
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
// setContentView(R.layout.activity_main2);
// Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
// setSupportActionBar(toolbar);
// TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
// tabLayout.addTab(tabLayout.newTab().setText("View"));
// tabLayout.addTab(tabLayout.newTab().setText("All"));
// tabLayout.addTab(tabLayout.newTab().setText("Tab 0"));
// tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));
// tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
// tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));
// tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
}
}
ViewPagerAdapter
Viewpageradapter.class
package com.example.jeffy.viewpagerapp;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Jeffy on 25-01-2016.
*/
public class PagerAdapter extends FragmentStatePagerAdapter {
int mNumOfTabs;
List<String> values;
public PagerAdapter(FragmentManager fm, int NumOfTabs, List<String> Port) {
super(fm);
this.mNumOfTabs = NumOfTabs;
this.values= Port;
}
#Override
public Fragment getItem(int position) {
String fragmentName = values.get(position);
Class<?> clazz = null;
Object fragment = null;
try {
clazz = Class.forName("com.example.jeffy.viewpagerapp."+fragmentName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
fragment = clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return (Fragment) fragment;
}
#Override
public int getCount() {
return values.size();
}
}
Layout for main2activity
acticity_main2.xml
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="#+id/MyAppbar"
android:layout_width="match_parent"
android:layout_height="256dp"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapse_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
android:background="#color/material_deep_teal_500"
android:fitsSystemWindows="true">
<ImageView
android:id="#+id/bgheader"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
android:background="#drawable/screen"
app:layout_collapseMode="pin" />
<android.support.v7.widget.Toolbar
android:id="#+id/MyToolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="parallax" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:id="#+id/nested"
android:layout_height="match_parent"
android:layout_gravity="fill_vertical"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/MyToolbar"
android:background="?attr/colorPrimary"
android:elevation="6dp"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</android.support.v4.view.ViewPager>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
Mainactivity layout
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.example.jeffy.viewpagerapp.MainActivity"
tools:showIn="#layout/activity_main">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/gridView1"
android:numColumns="2"
android:gravity="center"
android:columnWidth="100dp"
android:stretchMode="columnWidth"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</GridView>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="SAVE"
android:id="#+id/button" />
</LinearLayout>
</RelativeLayout>
Hope this would help someone... Click up button please if this helped you
Here's an alternative solution to this question. My adapter:
private class PagerAdapter extends FragmentPagerAdapter implements
ViewPager.OnPageChangeListener, TabListener {
private List<Fragment> mFragments = new ArrayList<Fragment>();
private ViewPager mPager;
private ActionBar mActionBar;
private Fragment mPrimaryItem;
public PagerAdapter(FragmentManager fm, ViewPager vp, ActionBar ab) {
super(fm);
mPager = vp;
mPager.setAdapter(this);
mPager.setOnPageChangeListener(this);
mActionBar = ab;
}
public void addTab(PartListFragment frag) {
mFragments.add(frag);
mActionBar.addTab(mActionBar.newTab().setTabListener(this).
setText(frag.getPartCategory()));
}
#Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
#Override
public int getCount() {
return mFragments.size();
}
/** (non-Javadoc)
* #see android.support.v4.app.FragmentStatePagerAdapter#setPrimaryItem(android.view.ViewGroup, int, java.lang.Object)
*/
#Override
public void setPrimaryItem(ViewGroup container, int position,
Object object) {
super.setPrimaryItem(container, position, object);
mPrimaryItem = (Fragment) object;
}
/** (non-Javadoc)
* #see android.support.v4.view.PagerAdapter#getItemPosition(java.lang.Object)
*/
#Override
public int getItemPosition(Object object) {
if (object == mPrimaryItem) {
return POSITION_UNCHANGED;
}
return POSITION_NONE;
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
mPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) { }
#Override
public void onTabReselected(Tab tab, FragmentTransaction ft) { }
#Override
public void onPageScrollStateChanged(int arg0) { }
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) { }
#Override
public void onPageSelected(int position) {
mActionBar.setSelectedNavigationItem(position);
}
/**
* This method removes the pages from ViewPager
*/
public void removePages() {
mActionBar.removeAllTabs();
//call to ViewPage to remove the pages
vp.removeAllViews();
mFragments.clear();
//make this to update the pager
vp.setAdapter(null);
vp.setAdapter(pagerAdapter);
}
}
Code to remove and add dynamically
//remove the pages. basically call to method removeAllViews from `ViewPager`
pagerAdapter.removePages();
pagerAdapter.addPage(pass your fragment);
After the advice of Peri Hartman, it started to work after I set null do ViewPager adapter and put the adapter again after the views removed. Before this the page 0 doesnt showed its list contents.
Thanks.
I've created a custom PagerAdapters library to change items in PagerAdapters dynamically.
You can change items dynamically like following by using this library.
#Override
protected void onCreate(Bundle savedInstanceState) {
/** ... **/
adapter = new MyStatePagerAdapter(getSupportFragmentManager()
, new String[]{"1", "2", "3"});
((ViewPager)findViewById(R.id.view_pager)).setAdapter(adapter);
adapter.add("4");
adapter.remove(0);
}
class MyPagerAdapter extends ArrayViewPagerAdapter<String> {
public MyPagerAdapter(String[] data) {
super(data);
}
#Override
public View getView(LayoutInflater inflater, ViewGroup container, String item, int position) {
View v = inflater.inflate(R.layout.item_page, container, false);
((TextView) v.findViewById(R.id.item_txt)).setText(item);
return v;
}
}
Thils library also support pages created by Fragments.
To remove you can use this directly:
getSupportFragmentManager().beginTransaction().remove(fragment).
commitAllowingStateLoss();
fragment is the fragment you want to remove.
I find a good solution for this issue, this solution can make it work and no need to recreate Fragments.
My key point is:
setup ViewPager every time you delete or add Tab(Fragment).
Override the getItemId method, return a specific id rather than position.
Source Code
package com.zq.testviewpager;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Arrays;
/**
* Created by z8888q#gmail.com on 2017/5/31.
* Implement dynamic delete or add tab(TAB_C in this test code).
*/
public class MainActivity extends AppCompatActivity {
private static final int TAB_A = 1001;
private static final int TAB_B = 1002;
private static final int TAB_C = 1003;
private static final int TAB_D = 1004;
private static final int TAB_E = 1005;
private Tab[] tabsArray = new Tab[]{new Tab(TAB_A, "A"),new Tab(TAB_B, "B"),new Tab(TAB_C, "C"),new Tab(TAB_D, "D"),new Tab(TAB_E, "E")};
private ArrayList<Tab> mTabs = new ArrayList<>(Arrays.asList(tabsArray));
private Tab[] tabsArray2 = new Tab[]{new Tab(TAB_A, "A"),new Tab(TAB_B, "B"),new Tab(TAB_D, "D"),new Tab(TAB_E, "E")};
private ArrayList<Tab> mTabs2 = new ArrayList<>(Arrays.asList(tabsArray2));
/**
* The {#link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {#link FragmentPagerAdapter} derivative, which will keep every
* loaded fragment in memory. If this becomes too memory intensive, it
* may be best to switch to a
* {#link android.support.v4.app.FragmentStatePagerAdapter}.
*/
private SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {#link ViewPager} that will host the section contents.
*/
private ViewPager mViewPager;
private TabLayout tabLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(mTabs, getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}else if (id == R.id.action_delete) {
int currentItemPosition = mViewPager.getCurrentItem();
Tab currentTab = mTabs.get(currentItemPosition);
if(currentTab.id == TAB_C){
currentTab = mTabs.get(currentItemPosition == 0 ? currentItemPosition +1 : currentItemPosition - 1);
}
mSectionsPagerAdapter = new SectionsPagerAdapter(mTabs2, getSupportFragmentManager());
mViewPager.setAdapter(mSectionsPagerAdapter);
tabLayout.setupWithViewPager(mViewPager);
mViewPager.setCurrentItem(mTabs2.indexOf(currentTab), false);
return true;
}else if (id == R.id.action_add) {
int currentItemPosition = mViewPager.getCurrentItem();
Tab currentTab = mTabs2.get(currentItemPosition);
mSectionsPagerAdapter = new SectionsPagerAdapter(mTabs, getSupportFragmentManager());
mViewPager.setAdapter(mSectionsPagerAdapter);
tabLayout.setupWithViewPager(mViewPager);
mViewPager.setCurrentItem(mTabs.indexOf(currentTab), false);
return true;
}else
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
public PlaceholderFragment() {
}
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e("TestViewPager", "onCreate"+getArguments().getInt(ARG_SECTION_NUMBER));
}
#Override
public void onDestroy() {
super.onDestroy();
Log.e("TestViewPager", "onDestroy"+getArguments().getInt(ARG_SECTION_NUMBER));
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
TextView textView = (TextView) rootView.findViewById(R.id.section_label);
textView.setText(getString(R.string.section_format, getArguments().getInt(ARG_SECTION_NUMBER)));
return rootView;
}
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
ArrayList<Tab> tabs;
public SectionsPagerAdapter(ArrayList<Tab> tabs, FragmentManager fm) {
super(fm);
this.tabs = tabs;
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
return PlaceholderFragment.newInstance(tabs.get(position).id);
}
#Override
public int getCount() {
return tabs.size();
}
#Override
public long getItemId(int position) {
return tabs.get(position).id;
}
#Override
public CharSequence getPageTitle(int position) {
return tabs.get(position).title;
}
}
private static class Tab {
String title;
public int id;
Tab(int id, String title){
this.id = id;
this.title = title;
}
#Override
public boolean equals(Object obj) {
if(obj instanceof Tab){
return ((Tab)obj).id == id;
}else{
return false;
}
}
}
}
Code is at my Github Gist.
Related
I have used view pager for load fragments using FragmentStatePagerAdapter.
when i will come first time it will working but if i am redirect to other fragment from pager adapter and come back it will display blank screen.
**fragment_community.xml**
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical">
<include
android:id="#+id/includeTop"
layout="#layout/layout_header"
android:layout_width="match_parent"
android:layout_height="50dp"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/includeTop"
android:orientation="vertical"
>
<android.support.design.widget.TabLayout
android:id="#+id/tabAddFriend"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_alignParentTop="true"
android:background="#drawable/tab_friend_selector"
android:fadeScrollbars="false"
app:tabGravity="fill"
app:tabIndicatorHeight="4dp"
app:tabMaxWidth="0dp"
app:tabMode="fixed"
app:tabSelectedTextColor="#color/colorDarkGray"
app:tabTextColor="#color/colorGray">
</android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="#+id/pagerCommunity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/tabAddFriend"/>
</LinearLayout>
</LinearLayout>
**Community Fragment :**
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import com.****.app.R;
import com.****.app.adapter.CommunityPagerAdapter;
import com.****.app.customcontrol.CustomTextViewMedium;
import com.****.app.customcontrol.CustomTextViewRegular;
import com.****.app.utils.General;
import com.****.app.utils.ManageFragment;
public class CommunityFragment extends Fragment{
public static final int FOLLOWERS = 0;
public static final int FOLLOWING = 1;
public static final int GROUPS = 2;
public static String LOGTAG = CommunityFragment.class.getSimpleName ();
// define activity layouts
LinearLayout linearBack, linearAction;
ImageView imgBack, imgAction;
CustomTextViewRegular txtTitle;
FragmentActivity activity;
String[] tabList;
//CustomViewPager pagerCommunity;
ViewPager pagerCommunity;
TabLayout tabAddFriend;
FragmentManager manager;
CommunityPagerAdapter communityPagerAdapter;
String operation="";
public CommunityFragment (){
}
#Override
public void onCreate (Bundle savedInstanceState){
super.onCreate (savedInstanceState);
activity = this.getActivity ();
tabList = activity.getResources ().getStringArray (R.array.communityArray);
//Bundle bundle=activity.getIntent ().getExtr
if(getArguments ()!=null){
operation= getArguments ().getString (General.REQUEST_TYPE);
}
}
#Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View view = inflater.inflate (R.layout.fragment_community, container, false);
linearAction = (LinearLayout) view.findViewById (R.id.linearAction);
linearAction.setVisibility (View.VISIBLE);
linearBack = (LinearLayout) view.findViewById (R.id.linearBack);
imgBack = (ImageView) view.findViewById (R.id.imgBack);
imgAction = (ImageView) view.findViewById (R.id.imgAction);
imgAction.setImageResource (R.drawable.ic_block);
txtTitle = (CustomTextViewRegular) view.findViewById (R.id.txtTitle);
txtTitle.setText (getString (R.string.community));
tabAddFriend = (TabLayout) view.findViewById (R.id.tabAddFriend);
pagerCommunity = (ViewPager) view.findViewById (R.id.pagerCommunity);
linearBack.setOnClickListener (new View.OnClickListener (){
#Override
public void onClick (View v){
ManageFragment.back (activity);
}
});
imgBack.setOnClickListener (new View.OnClickListener (){
#Override
public void onClick (View v){
ManageFragment.back (activity);
}
});
pagerCommunity.addOnPageChangeListener (new ViewPager.OnPageChangeListener (){
#Override
public void onPageScrolled (int position, float positionOffset, int positionOffsetPixels){
}
#Override
public void onPageSelected (int position){
if (position == FOLLOWERS){
imgAction.setImageResource (R.drawable.ic_block);
} else if (position == FOLLOWING){
imgAction.setImageResource (R.drawable.ic_plus);
} else if (position == GROUPS){
imgAction.setImageResource (R.drawable.ic_plus);
}
updateCustomTabTextView (position);
}
#Override
public void onPageScrollStateChanged (int state){
}
});
linearAction.setOnClickListener (new View.OnClickListener (){
#Override
public void onClick (View v){
int position = pagerCommunity.getCurrentItem ();
if (position == FOLLOWERS){
imgAction.setImageResource (R.drawable.ic_block);
ManageFragment.replace (activity, R.id.content_frame, new BlockedUsersFragment (), BlockedUsersFragment.LOGTAG, BlockedUsersFragment.LOGTAG);
} else if (position == FOLLOWING){
imgAction.setImageResource (R.drawable.ic_plus);
ManageFragment.replace (activity, R.id.content_frame, new FollowingAddFragment (), FollowingAddFragment.LOGTAG, FollowingAddFragment.LOGTAG);
} else if (position == GROUPS){
imgAction.setImageResource (R.drawable.ic_plus);
ManageFragment.replace (activity, R.id.content_frame, new NewGroupFragment (), NewGroupFragment.LOGTAG, NewGroupFragment.LOGTAG);
}
}
});
setTabLayout ();
return view;
}
private void setTabLayout (){
manager = activity.getSupportFragmentManager ();
communityPagerAdapter = new CommunityPagerAdapter (activity, manager);
pagerCommunity.setAdapter (communityPagerAdapter);
tabAddFriend.setupWithViewPager (pagerCommunity);
setCustomTabTextView ();
if(!operation.equalsIgnoreCase ("")){
int type=Integer.parseInt (operation);
if(type==FOLLOWERS){
imgAction.setImageResource (R.drawable.ic_block);
}else if(type==FOLLOWING){
imgAction.setImageResource (R.drawable.ic_plus);
}
pagerCommunity.setCurrentItem (type);
}
}
public void updateCustomTabTextView (int position){
for (int i = 0; i < tabAddFriend.getTabCount (); i++){
View view = tabAddFriend.getTabAt (i).getCustomView ();
CustomTextViewMedium textTabTitle = (CustomTextViewMedium) view.findViewById (R.id.textTabTitle);
if (i == position){
textTabTitle.setTextColor (ContextCompat.getColor (activity, R.color.colorDarkGray));
} else{
textTabTitle.setTextColor (ContextCompat.getColor (activity, R.color.colorGray));
}
}
}
private void setCustomTabTextView (){
for (int i = 0; i < tabAddFriend.getTabCount (); i++){
TabLayout.Tab tab = tabAddFriend.getTabAt (i);
View view = LayoutInflater.from (activity).inflate (R.layout.layout_add_friend_tab, null);
CustomTextViewMedium textTabTitle = (CustomTextViewMedium) view.findViewById (R.id.textTabTitle);
textTabTitle.setText (tabList[i]);
textTabTitle.setTextSize (12);
if (pagerCommunity.getCurrentItem () == i){
textTabTitle.setTextColor (ContextCompat.getColor (activity, R.color.colorDarkGray));
} else{
textTabTitle.setTextColor (ContextCompat.getColor (activity, R.color.colorGray));
}
tab.setCustomView (view);
}
}
}
**CommunityPagerAdapter.java**
import android.app.Activity;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import com.****.app.R;
import com.****.app.fragment.ActivityFragment;
import com.****.app.fragment.FollowingFragment;
import com.****.app.fragment.GroupFragment;
public class CommunityPagerAdapter extends FragmentStatePagerAdapter{
Activity activity;
public CommunityPagerAdapter (Activity activity, FragmentManager fm){
super (fm);
this.activity = activity;
}
#Override
public Fragment getItem (int position){
switch (position){
case 0:
return new ActivityFragment ();
case 1:
return new FollowingFragment ();
case 2:
return new GroupFragment ();
}
return null;
}
#Override
public int getCount (){
return 3;
}
#Override
public CharSequence getPageTitle (int position){
String title = " ";
switch (position){
case 0:
title = activity.getResources ().getString (R.string.followers);
break;
case 1:
title = activity.getResources ().getString (R.string.following);
break;
case 2:
title = activity.getResources ().getString (R.string.groups);
break;
}
return title;
}
}
Down-voted for providing the solution from another post? Thanks!
Alright, I give this another try to describe what happens and why Fragments aren't re-attached:
The restored Fragment (from going back a.k.a. popping the back-stack) is fully re-created with a View-hierarchy but not the View-hierarchy of the popped state. A workaround for this is to make sure that already restored Fragments' View is re-attached and one of doing it is to write another implementation of FragmentStatePagerAdapter were the original code is used and the following changes are made:
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position) {
// If we already have this item instantiated, there is nothing
// to do. This can happen when we are restoring the entire pager
// from its saved state, where the fragment manager has already
// taken care of restoring the fragments we previously had instantiated.
if (mFragments.size() > position) {
Fragment f = mFragments.get(position);
if (f != null) {
return f;
}
}
...
}
is modified slightly to:
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position) {
// If we already have this item instantiated, there is nothing
// to do. This can happen when we are restoring the entire pager
// from its saved state, where the fragment manager has already
// taken care of restoring the fragments we previously had instantiated.
if (mFragments.size() > position) {
Fragment f = mFragments.get(position);
if (f != null) {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
}
mCurTransaction.detach(f);
mCurTransaction.attach(f);
return f;
}
}
...
}
Please have a look at my recent post for a very similar scenario and the way I solved it.
https://stackoverflow.com/a/52661538/6391598
After 3 days of facing the problem what works for me is in onCreateView method check if the list size is greater than zero then set its adapter again
if (list.size() > 0) {
viewpager.setAdapter(viewPagerAdapter);
}
I faced this problem with viewpager, finally resolved by removing fragment and again load the same fragment
following is the code
FragmentManager fm = getSupportFragmentManager();
Fragment f = fm.findFragmentById(R.id.fragments);
FragmentManager fragmentManager = getSupportFragmentManager();
android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.remove(fragment); // here fragment is
fragmentTransaction.commit();
first this is my Activity
public class Main extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
viewpager = (ViewPager)findViewById(R.id.pager);
swipeadapter = new swipeadapter(this);
viewpager.setAdapter(swipeadapter);
//some condition remove textview or hide textview from current Pagerview
//position
//if(mm = oo){ //remove item from current pagerView adapter }
}
}
and this my adapter code
import android.app.Activity;
import android.content.Context;
import android.graphics.Point;
import android.support.v4.app.Fragment;
import android.support.v4.view.PagerAdapter;
import android.util.SparseArray;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import java.util.ArrayList;
import java.util.Calendar;
import ws.design.com.R;
public class swipeadapter extends PagerAdapter {
private Context ctx;
private LayoutInflater layoutInflater;
private LinearLayout player;
SparseArray<Fragment> registeredFragments = new SparseArray<>();
public swipeadapter(Context c){
this.ctx = c;
}
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
#Override
public boolean isViewFromObject(View view, Object o) {
return (view == (LinearLayout)o);
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
container.removeView((LinearLayout)object);
}
public void changeVisiblityOfTextView(int visiblity)
{
player.setVisibility(View.GONE);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
layoutInflater = (LayoutInflater)ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View inflatedView = layoutInflater.inflate(R.layout.player, container,false);
player = (LinearLayout)inflatedView.findViewById(R.id.buttons);
Display display = ((Activity)ctx).getWindowManager().getDefaultDisplay();
final Point size = new Point();
display.getSize(size);
container.addView(inflatedView);
return inflatedView;
}
#Override
public int getCount() {
return 10;
}
void setSimpleList(ListView listView){
ArrayList<String> contactsList = new ArrayList<String>();
for (int index = 0; index < 10; index++) {
contactsList.add("I am # index " + index + " today " + Calendar.getInstance().getTime().toString());
}
listView.setAdapter(new ArrayAdapter<String>(ctx,
R.layout.fb_comments_list_item, android.R.id.text1,contactsList));
}
}
i have pagerView and its work currently good but i want to hide item in current PagerView position thats shown to user if condition true how can i hide textView with id hideThis from this activity Main
Define a SparseArray in your ViewPager's adapter to keep fragment instances like below:
SparseArray<Fragment> registeredFragments = new SparseArray<>();
Note: Why SparseArray? https://developer.android.com/reference/android/util/SparseArray.html
Override instanstiateItem method of your FragmentPagerAdapter like below:
#Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
And override DestroyItem method:
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
Define a method to get current fragment like below:
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
Define a public method to change visibility of your TextViews in Fragmentsif your condition is True
public void changeVisiblityOfTextView(int visiblity)
{
mTextView.setVisiblity(visibility);
}
Add a new onPageChangeListener to your ViewPager:
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
YourFragment fragment = (YourFragment)yourPagerAdapter.getRegisteredFragment(position);
if(yourCondition){
fragment.changeVisiblityOfTextview(View.VISIBLE);
}
else{
fragment.changeVisiblityOfTextView(View.GONE)
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
I hope my answer helps you. Good Luck!
Edit:
YourPagerAdapter: FragmentPagerAdapter or FragmentStatePagerAdapter which you set to view pager.
YourFragment: It's your custom fragment which you extend from Support.Fragment and use in your view pager. (Fragment which you return in your adapter's public Fragment getItem(int position) method.
It's basically you add your fragment instances in a sparse array when you init return a new fragment in your view pager and get it to from adapter to change visibility of items which you put in your fragment.
I assume that your textview's in your view pager fragment's layout.
Edit 2:
Ops you do not use Fragments in your ViewPager so my solution is not suitable for you. You can change your ViewPager implementation to fragments or instead of keeping fragments in sparse array you can keep your inflated views which you add to container and instead of fragments you can go on with that views. And in onPageChanged method you can get view as in my example, find your textview and change it's visibility.
When i have time i'll add code here.
If you want to remove an item from your ViewPager, you need to remove it from the PagerAdapter and call notifyDatasetChanged() then set the adapter to the ViewPager again:
mAdapter.removeItem(position);
mViewPager.setAdapter(mAdapter);
You need to add a removeItem method in your adapter class (or however you want to remove the item):
public class MyAdapter extends PagerAdapter {
//...
public void removeItem(int position) {
if (position > -1 && position < items.size()) {
items.remove(position);
notifyDataSetChanged();
}
}
//...
}
This is the only way I got the ViewPager to refresh and fully remove the view in question.
You can store the current ViewPager position just before you remove the item and set the ViewPager to that position again.
So,I have this activity which has tabs with listviews in them, and the problems I'm facing are:
The first and second tabs are having the same content i.e. the content the second tab should have is in first and second tab.
The third tab has correct content, though this is because it only instantiates just first and second tabs initially.
When I set
mViewPager.setOffscreenPageLimit(2);
all the three tabs have same content, which is that of the third tab.
But after i've scrolled to third tab and then scroll back to the first one, the first one refreshes and has correct content.
Also, the next problem is the second tab never refreshes,because its always on the right or left to the tab which is opened.
I want the tabs to refresh every time they are opened since i'll be constantly changing the material in the lists.
package com.towntrot.anil.towntrot_eventmanager_02;
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;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
public class SlidingTabsBasicFragment extends Fragment {
ListView list;
public ArrayList<ListModel> CustomListViewValuesArr = new ArrayList<ListModel>();
public guestlist gg;
private SlidingTabLayout mSlidingTabLayout;
private ViewPager mViewPager;
private String[] eventtype={"CHECKED IN","CHECKED OUT","WAITING"};
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_sample, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
mViewPager = (ViewPager) view.findViewById(R.id.viewpager);
mViewPager.setAdapter(new SamplePagerAdapter());
mSlidingTabLayout = (SlidingTabLayout) view.findViewById(R.id.sliding_tabs);
mSlidingTabLayout.setViewPager(mViewPager);
}
class SamplePagerAdapter extends PagerAdapter {
#Override
public int getCount() {
return 3;
}
#Override
public boolean isViewFromObject(View view, Object o) {
return o == view;
}
#Override
public CharSequence getPageTitle(int position) {
return eventtype[position];
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
View view = getActivity().getLayoutInflater().inflate(R.layout.pager_item,
container, false);
guestlist gg=(guestlist)getActivity();
StringBuilder sb = new StringBuilder();
sb.append("");
sb.append(position);
String strI = sb.toString();
Toast.makeText(getActivity(),strI,Toast.LENGTH_LONG).show();
setListData(gg.getNamelist(), gg.getStatuslist(), gg.getNo0fPeople(), position);
list= ( ListView )view.findViewById(R.id.list);
CustomAdapter adapter;
adapter=new CustomAdapter( getActivity(), CustomListViewValuesArr);
list.setAdapter(adapter);
container.addView(view);
return view;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
public void setListData(String[] string,String[] status,int no,int pos) {
CustomListViewValuesArr.clear();
for (int i = 0; i < no; i++) {
final ListModel name = new ListModel();
int x=Integer.parseInt(status[i]);
if(pos==x){ name.setCompanyName(string[i]);
CustomListViewValuesArr.add(name);}
}
}
}
Please help me, I've seen a lot of answers but couldn't solve this. Any help is appreciated.
The problem is you are calling setListData every time a pager item is intantiated, which in turn populates the CustomListViewValuesArr with data of the given position. Then your list adapters are directly using this array cause it's defined in your fragment and depending on the last instantiated item, it's contents change.
Change CustomListViewValuesArr to a local variable; create a new ArrayList<ListModel> object in your setListData method and return it, use the returned object as your CustomAdapter constructor parameter.
you can download my zip here
ok so i made an app with Swipe+Tab View i want each tab to show a diffrent .xml page if u click above you can download my workspace to edit it .. i really need help please be spicific to if u want i can setup teamviwer if it could be faster.. if u dont want to download the file cause u think "it has a virus" just make a reply down below here is my code for the mainactivity.java
package twh.reviser.root;
import java.util.Locale;
import android.os.Bundle;
import android.renderscript.Int2;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.NavUtils;
import android.support.v4.view.ViewPager;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class MainActivity extends FragmentActivity {
/**
* The {#link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {#link android.support.v4.app.FragmentPagerAdapter} derivative, which
* will keep every loaded fragment in memory. If this becomes too memory
* intensive, it may be best to switch to a
* {#link android.support.v4.app.FragmentStatePagerAdapter}.
*/
SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {#link ViewPager} that will host the section contents.
*/
ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create the adapter that will return a fragment for each of the three
// primary sections of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#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 DummySectionFragment();
Bundle args = new Bundle();
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position + 1);
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
// Show 3 total pages.
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.title_section1).toUpperCase(l);
case 1:
return getString(R.string.title_section2).toUpperCase(l);
case 2:
return getString(R.string.title_section3).toUpperCase(l);
}
return null;
}
}
/**
* A dummy fragment representing a section of the app, but that simply
* displays dummy text.
*/
public static class DummySectionFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
public static final String ARG_SECTION_NUMBER = "section_number";
public DummySectionFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main_dummy, container, false);
TextView dummyTextView = (TextView) rootView.findViewById(R.id.section_label);
dummyTextView.setText(Integer.toString(getArguments().getInt(ARG_SECTION_NUMBER)));
return rootView;
}
}
}
Here is an example of my adapter that solves your problem. TabsPagerAdapter is just separate class.
/**
* This is a helper class that implements the management of tabs and all
* details of connecting a ViewPager with associated TabHost. It relies on a
* trick. Normally a tab host has a simple API for supplying a View or
* Intent that each tab will show. This is not sufficient for switching
* between pages. So instead we make the content part of the tab host
* 0dp high (it is not shown) and the TabsAdapter supplies its own dummy
* view to show as the tab content. It listens to changes in tabs, and takes
* care of switch to the correct paged in the ViewPager whenever the selected
* tab changes.
*/
public class TabsPagerAdapter extends FragmentPagerAdapter implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener{
private final Context mContext;
private final TabHost mTabHost;
private final ViewPager mViewPager;
private final OnPageChangeListener mListener;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
private final FragmentManager mFragmentManager;
static final class TabInfo {
private final String tag;
private final Class<?> clss;
private final Bundle args;
TabInfo(String _tag, Class<?> _class, Bundle _args) {
tag = _tag;
clss = _class;
args = _args;
}
}
static class DummyTabFactory implements TabHost.TabContentFactory {
private final Context mContext;
public DummyTabFactory(Context context) {
mContext = context;
}
#Override
public View createTabContent(String tag) {
View v = new View(mContext);
v.setMinimumWidth(0);
v.setMinimumHeight(0);
return v;
}
}
public void addTab(String label, String tag, Drawable drawable, Class<?> c, int resourse) {
addTab(this.mContext, label, tag, drawable, c, resourse);
}
public void addTab(Context context, String label, String tag, Drawable drawable, Class<?> c, int resourse) {
Intent intent = new Intent(context, c);
TabHost.TabSpec spec = mTabHost.newTabSpec(tag);
View tabIndicator = LayoutInflater.from(context).inflate(resourse, (TabWidget)mTabHost.findViewById(android.R.id.tabs), false);
ImageView icon = (ImageView) tabIndicator.findViewById(R.id.icon);
icon.setImageDrawable(drawable);
icon.setScaleType(ImageView.ScaleType.FIT_CENTER);
spec.setIndicator(tabIndicator);
spec.setContent(intent);
this.addTab(spec, c, null);
}
public TabsPagerAdapter(FragmentActivity activity, TabHost tabHost, ViewPager pager, OnPageChangeListener listener, FragmentManager manager) {
super(manager);
mFragmentManager = manager;
mContext = activity;
mTabHost = tabHost;
mViewPager = pager;
mListener = listener;
mTabHost.setOnTabChangedListener(this);
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) {
tabSpec.setContent(new DummyTabFactory(mContext));
String tag = tabSpec.getTag();
TabInfo info = new TabInfo(tag, clss, args);
mTabs.add(info);
mTabHost.addTab(tabSpec);
notifyDataSetChanged();
}
#Override
public int getCount() {
return mTabs.size();
}
#Override
public CharSequence getPageTitle (int position){
}
public Fragment getCurrentFragment() {
return getFragmentAt(mTabHost.getCurrentTab());
}
public Fragment getFragmentAt(int position){
return mFragmentManager.findFragmentByTag("android:switcher:" + mViewPager.getId() + ":" + position);
}
#Override
public Fragment getItem(int position) {
TabInfo info = (TabInfo) mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
#Override
public void onTabChanged(String tabId) {
//called when the user clicks on a tab.
int position = mTabHost.getCurrentTab();
if(mViewPager.getCurrentItem() != position){
mViewPager.setCurrentItem(position);
}
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if(mListener!=null){
mListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
#Override
public void onPageSelected(int position) {
// Unfortunately when TabHost changes the current tab, it kindly
// also takes care of putting focus on it when not in touch mode.
// The jerk.
// This hack tries to prevent this from pulling focus out of our
// ViewPager.
TabWidget widget = mTabHost.getTabWidget();
int oldFocusability = widget.getDescendantFocusability();
widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
mTabHost.setCurrentTab(position);
widget.setDescendantFocusability(oldFocusability);
if(mListener!=null){
mListener.onPageSelected(position);
}
}
#Override
public void onPageScrollStateChanged(int state) {
if(mListener!=null){
mListener.onPageScrollStateChanged(state);
}
}
}
This is android example framentadapter with tiny modifications.
Example usage
MainActivity.java
class MainActivity extends FragmentActivuty{
public void onCreate(Bundle savedInstanceState){
setContentView(R.layout.activity_main);
mTabHost = (TabHost) findViewById(android.R.id.tabhost);
mTabHost.setup();
mViewPager = (ViewPager) findViewById(R.id.pager);
mTabsAdapter = new TabsPagerAdapter(this, mTabHost, mViewPager,null, getSupportFragmentManager());
mTabsAdapter.addTab("Button", "button",getResources().getDrawable(R.drawable.yourdrawable),
ButtonFragment.class, R.layout.yourtablayout);
mTabsAdapter.addTab("Text","text",getResources().getDrawable(R.drawable.yourdrawable), TextFragment.class, R.layout.yourtablayout);
//This is needed so your tabs do not reload each time
mViewPager.setOffscreenPageLimit(mTabsAdapter.getCount());
}
I integrated some code that I wrote with the code you provided. I think this should work, based upon you having used the generic Android ADT setup.
package twh.reviser.root;
import java.util.Locale;
import android.os.Bundle;
import android.renderscript.Int2;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.NavUtils;
import android.support.v4.view.ViewPager;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class MainActivity extends FragmentActivity {
static final int NUM_ITEMS = 3;
/**
* The {#link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {#link android.support.v4.app.FragmentPagerAdapter} derivative, which
* will keep every loaded fragment in memory. If this becomes too memory
* intensive, it may be best to switch to a
* {#link android.support.v4.app.FragmentStatePagerAdapter}.
*/
SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {#link ViewPager} that will host the section contents.
*/
ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create the adapter that will return a fragment for each of the three
// primary sections of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
/** possibly missing from your code*/
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
actionBar.addTab(actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
#Override
public void onTabSelected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in
// the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabReselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
Context c;
public SectionsPagerAdapter(Context c,FragmentManager fm) {
super(fm);
this.c = c;
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
if (position == 0) {
fragment = new FragmentPage1(c);
Bundle args = new Bundle();
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position + 1);
fragment.setArguments(args);
}
if (position == 1) {
fragment = new FragmentPage2(c);
Bundle args = new Bundle();
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position + 1);
fragment.setArguments(args);
}
if (position == 2) {
fragment = new FragmentPage3(c);
Bundle args = new Bundle();
args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position + 1);
fragment.setArguments(args);
}
return fragment;
}
#Override
public int getCount() {
// Show 3 total pages.
return NUM_ITEMS;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.title_section1).toUpperCase(l);
case 1:
return getString(R.string.title_section2).toUpperCase(l);
case 2:
return getString(R.string.title_section3).toUpperCase(l);
}
return null;
}
}
/**
* A dummy fragment representing a section of the app, but that simply
* displays dummy text.
*/
public static class DummySectionFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
public static final String ARG_SECTION_NUMBER = "section_number";
public DummySectionFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main_dummy, container, false);
TextView dummyTextView = (TextView) rootView.findViewById(R.id.section_label);
dummyTextView.setText(Integer.toString(getArguments().getInt(ARG_SECTION_NUMBER)));
return rootView;
}
}
}
Create three xml files for each of the three fragments in res/layout/
Fragment_1.xml
<?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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin" >
<TextView
android:id="#+id/textview1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Fragment_2.xml
<?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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin" >
<TextView
android:id="#+id/textview1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Fragment_3.xml
<?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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin" >
<TextView
android:id="#+id/textview1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Create three java files for the three fragments in src/twh.reviser.root
FragmentPage1.java
package twh.reviser.root;
public class FragmentPage1 extends Fragment {
Context c;
public FragmentInputPage1(){
}
public FragmentInputPage1(Context c) {
this.c = c;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.Fragment_1, null);
return v;
}
}
FragmentPage2.java
package twh.reviser.root;
public class FragmentPage2 extends Fragment {
Context c;
public FragmentInputPage2(){
}
public FragmentInputPage2(Context c) {
this.c = c;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.Fragment_2, null);
return v;
}
}
FragmentPage3.java
package twh.reviser.root;
public class FragmentPage3 extends Fragment {
Context c;
public FragmentInputPage3(){
}
public FragmentInputPage3(Context c) {
this.c = c;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.Fragment_3, null);
return v;
}
}
If you want to get the value of an id from another fragment you can use the below, based upon FragmentPage1 having the following public variables declared
public static String a,b,c;
Within FragmentPage1.java
public class FragmentPage3 extends Fragment {
Context c;
String a = "";
String b = "";
String c = "";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.Fragment_3, null);
a = FragmentPage1.a;
b = FragmentPage1.b;
c = FragmentPage1.c;
I have a android application using a pager as navigation. For the tabs I have 3 layouts as content. On one of the fragments is a gallery and I want to add images to it. For that I have to set an ImageAdapter but I need to know how to access the context of a fragment.
final LayoutInflater factory = getLayoutInflater();
final View view = factory.inflate(R.layout.pictures, null);
Gallery g = (Gallery) view.findViewById(R.id.gallery1);
g.setAdapter(new ImageAdapter(view.getContext()));
I use this code above in the onCreate method to get the gallery from a layout that is not the contentview.
I have to give a Context to the ImageAdapter. But what context do I have to set there?
EDIT: This is my complete code:
package com.bw2801.uwelugemediathek;
import java.util.Locale;
import android.app.ActionBar;
import android.app.FragmentTransaction;
import android.content.Context;
import android.database.DataSetObserver;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.SpinnerAdapter;
import android.widget.Toast;
public class MainActivity extends FragmentActivity implements
ActionBar.TabListener {
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
PicturesSectionFragment ps = new PicturesSectionFragment();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set up the action bar.
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Create the adapter that will return a fragment for each of the three
// primary sections of the app.
mSectionsPagerAdapter = new SectionsPagerAdapter(
getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
// When swiping between different sections, select the corresponding
// tab. We can also use ActionBar.Tab#select() to do this if we have
// a reference to the Tab.
mViewPager
.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
// Create a tab with text corresponding to the page title defined by
// the adapter. Also specify this Activity object, which implements
// the TabListener interface, as the callback (listener) for when
// this tab is selected.
actionBar.addTab(actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
final LayoutInflater factory = getLayoutInflater();
final View view = factory.inflate(R.layout.pictures, null);
Gallery g = (Gallery) view.findViewById(R.id.gallery1);
g.setAdapter(new ImageAdapter(ps.getActivity()));
}
public class ImageAdapter extends BaseAdapter {
private Context mContext;
private Integer[] mImageIds = {
R.drawable.image01,
R.drawable.image02,
R.drawable.image03,
R.drawable.image04,
R.drawable.image05,
R.drawable.image06,
R.drawable.image07,
R.drawable.image08,
};
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return mImageIds.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ImageView i = new ImageView(mContext);
i.setImageResource(mImageIds[position]);
i.setLayoutParams(new Gallery.LayoutParams(150, 100));
i.setScaleType(ImageView.ScaleType.FIT_XY);
return i;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onTabSelected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in
// the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
#Override
public void onTabReselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch(position) {
case 0:
return new DummySectionFragment();
case 1:
return new SoundSectionFragment();
case 2:
return ps;
}
return new DummySectionFragment();
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Informationen";
case 1:
return "Soundboard";
case 2:
return "Galerie";
}
return null;
}
}
public static class DummySectionFragment extends Fragment {
public DummySectionFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.info, container, false);
}
}
public static class PicturesSectionFragment extends Fragment {
public PicturesSectionFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.pictures, container, false);
}
}
public static class SoundSectionFragment extends Fragment {
public SoundSectionFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.sounds, container, false);
}
}
}
Fragments don't have their own Context, they use parent Activity.
To get parent Activity Context, use getActivity()
To use Application Context, use getActivity().getApplicationContext()
Prefer Application Context wherever possible.
UPDATE:
getActivity() of a Fragment returns an Activity instance if and only if, the said Fragment is currently attached to an Activity.
So,
Fragment f = new MyFragment();
creates a fragment, but it is not attached to an activity yet. Hence f.getActivity() returns null.
After its added to an activity:
getFragmentManager().beginTransaction().add(f,"fragment").commit();
Now, getActivity() will return an Activity instance.
Again, if we detach the fragment from Activity:
getFragmentManager().beginTransaction().detach(f).commit()
getActivity() will again return a null value.
So, we should not use getActivity() outside the Fragment class, because we can't be sure of attached status. Thus I'll advice you to used getActivity() inside the fragment's own class in its methods: onAttach(), onCreate() or onActivityCreated().
you can use like this
g.setAdapter(new ImageAdapter(getActivity()));
The easiest and most precise way to get the context of the fragment that I found is to get it directly from the ViewGroup when you call onCreateView method at least here you are sure not to get null for getActivity()
public class Animal extends Fragment {
Context thiscontext;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
thiscontext = container.getContext();
write under code in Your CoreApplication.java
step1)
public class CoreApplication extends Application {
private static CoreApplication instance;
}
step2) onCreate(){
instance = this;
}
step3 )
add under method()
public static CoreApplication getGlobalApplicationContext() {
if (instance == null) {
throw new IllegalStateException("this application does not
inherit GlobalApplication"); " +
"}
return instance;
}
Step4)
g.setAdapter(new ImageAdapter(getGlobalApplicationContext()));