Android PagerAdapter not calling instantiateItem - android

I'm trying to implement ViewPager with PagerAdapter in my app. I'm mainly working off this example.
My PagerAdapter is called DataPagerAdapter and uses the following constructor and instantiateItem, where I inflate a view from data_list_view.xml:
public class DataPagerAdapter extends PagerAdapter
implements TitleProvider {
private LayoutInflater mInflater;
private static String[] titles = new String[]
{
"Page 1",
"Page 2",
"Page 3"
};
private final Context context;
public DataPagerAdapter( Context context )
{
this.context = context;
}
#Override
public String getTitle( int position )
{
return titles[ position ];
}
#Override
public int getCount()
{
return titles.length;
}
#Override
public Object instantiateItem( View pager, int position )
{
ListView v = (ListView) mInflater.inflate(R.layout.data_list_view, null);
((ViewPager)pager).addView( v, 0 );
return v;
}
#Override
public void destroyItem( View pager, int position, Object view )
{
((ViewPager)pager).removeView( (ListView)view );
}
#Override
public boolean isViewFromObject( View view, Object object )
{
return view.equals( object );
}
#Override
public void finishUpdate( View view ) {}
#Override
public void restoreState( Parcelable p, ClassLoader c ) {}
#Override
public Parcelable saveState() {
return null;
}
#Override
public void startUpdate( View view ) {}
}
And in my activity I get my adapter:
DataPagerAdapter adapter = new DataPagerAdapter( this );
And then later I want to refer to my dataListView in code:
dataListView = (ListView) findViewById(R.id.listViewData);
Problem is, the dataListView is returned as null by the findViewById call since the instantiateItem is never processed.
When is instantiateItem called and is this done automatically (as the example seems to suggest) or do I have to force it somehow?

Note, that your adapter uses deprecated methods:
public Object instantiateItem(View container, int position)
public void destroyItem(View container, int position, Object object)
The API says to use these instead:
public Object instantiateItem(ViewGroup container, int position)
public void destroyItem(ViewGroup container, int position, Object object)

In my case the problem was I set ViewPager visibility to GONE by mistake and it was not getting called . Just make viewPager visibility to visible in layout.

Related

What is the best place to retrive ViewPager child's layout?

Good morning,
I have a Fragment which its layout has a ViewPager, I provide a custom PageAdapter to show two child layouts. One layout is to fill with personal data and another layout is to fill with Address data by the user. On my fragment I want to retrieve both layouts data and fill a object Pessoa(Person) with an attribute Endereco (Address). So far my ViewPager is working and both layout are displayed, however when I try to get the fields on both layouts, either on onCreateView or onResume fragment's method, using :
viewpager.getChildAt(0).findViewById(R.id.txt1)
I got an NullPointerException, but if I add an OnPageChangeListener this works, I not sure if it's the best approach. Is There a best place to retrieve a reference to the viewpager child's layout?
Ps. I don't want to use two other Fragments in order to display each of the layouts.
PageAdapter
public class ViewPagerCadastroPessoaAdapter extends PagerAdapter {
private Context context;
private int[] views = {R.layout.layout_cadastro_dados_pessoais,R.layout.layout_cadastro_endereco };
public ViewPagerCadastroPessoaAdapter(Context context) {
this.context = context;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
LayoutInflater inflater = LayoutInflater.from(this.context);
View layout = inflater.inflate(views[position], container, false);
container.addView(layout, position);
return layout;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position){
case 0:
return "Dados Pessoais";
case 1:
return "Endereço";
}
return super.getPageTitle(position);
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}}
ViewPager's holder Fragment
public class CadastroPessoaFragment extends Fragment {
private ViewPager viewPagerCadastroPessoa;
private TabLayout tabLayoutCadastroPessoa;
public CadastroPessoaFragment() {
}
public static CadastroPessoaFragment newInstance() {
return new CadastroPessoaFragment();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_cadastro_pessoa, container, false);
tabLayoutCadastroPessoa = root.findViewById(R.id.tabLayoutCadastroPessoa);
viewPagerCadastroPessoa = root.findViewById(R.id.viewPagerCadastroPessoa);
viewPagerCadastroPessoa.setOffscreenPageLimit(2);
viewPagerCadastroPessoa.setAdapter(new ViewPagerCadastroPessoaAdapter(getContext()));
tabLayoutCadastroPessoa.setupWithViewPager(viewPagerCadastroPessoa);
int cor = ContextCompat.getColor(getContext(), android.R.color.white);
tabLayoutCadastroPessoa.setTabTextColors(cor, cor);
//get a null pointer
viewPagerCadastroPessoa.getChildAt(0).findViewById(R.id.txt1);
viewPagerCadastroPessoa.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
//works fine
viewPagerCadastroPessoa.getChildAt(0).findViewById(R.id.txt1);
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
return root;
}
#Override
public void onResume() {
super.onResume();
//get a null pointer
viewPagerCadastroPessoa.getChildAt(0).findViewById(R.id.txt1);
}
}
Thank you all in advance
UPDATE
According with
Anton Malyshev answer
The way Viewpager creates its pages is kind of "unsynchronized", so I used the following approach to solve my problem:
On my custom adapter I definied an interface with a single method onViewPagerReady(), as my Viewpager will always have only two pages, inside instantiateItem I check when position is 1 (once position starts with 0), if position == 1 I call the method onViewPagerReady that my fragment viewpager's holder implements, so inside this method I retrieve the layout of viewpager's children
public class ViewPagerCadastroPessoaAdapter extends PagerAdapter {
public interface ViewPagerObserver{
void onViewPagerReady();
}
private Context context;
private int[] views = {R.layout.layout_cadastro_dados_pessoais,R.layout.layout_cadastro_endereco };
private ViewPagerObserver observer;
public ViewPagerCadastroPessoaAdapter(Context context, ViewPagerObserver observer) {
this.context = context;
this.observer = observer;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
LayoutInflater inflater = LayoutInflater.from(this.context);
View layout = inflater.inflate(views[position], container, false);
container.addView(layout, position);
if(position == 1){
observer.onViewPagerReady();
}
return layout;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position){
case 0:
return "Dados Pessoais";
case 1:
return "Endereço";
}
return super.getPageTitle(position);
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
}
Fragment Viewpager's Holder
#Override
public void onViewPagerReady() {
View rootCadastroDadosPessoais = viewPagerCadastroPessoa.getChildAt(0);
View rootCadastroEnderecos =viewPagerCadastroPessoa.getChildAt(1);
}
Thank you all.
Just wait until viewPagerCadastroPessoa.getChildCount() will be greater than 0. The pages in ViewPager are not created yet in onResume (they are created asynchronously).

Unable to invoke instantiateitems method in viewpager pageadapter

I am unable to invoke the instantiateitem method while trying to make an image slider in Android activity. There aren't any errors showing but the images aren't visible, here is the adapter code:
public class CustomSwipeAdapter extends PagerAdapter
{
ImageView imageView;
private int[] image_resources={R.drawable.bus,R.drawable.cp,R.drawable.ty};
private Context ctx;
private LayoutInflater layoutInflater;
#Override
public int getCount() {
return 0;
}
public CustomSwipeAdapter(Context ctx)
{
Log.d("**************","**************5");
this.ctx=ctx;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return (view==(LinearLayout)object);
}
#Override
public Object instantiateItem(ViewGroup container, int position)
{
Log.d("**************","**************7");
layoutInflater=(LayoutInflater)ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view=layoutInflater.inflate(R.layout.swipe_layout,null);
imageView=(ImageView)view.findViewById(R.id.image_view1);
imageView.setImageResource(image_resources[position]);
ViewPager vp=(ViewPager)container;
vp.addView(view,0);
//container.addView(view);
Log.d("**************","**************8");
return view;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object)
{
ViewPager vp =(ViewPager)container;
View view=(View)object;
vp.removeView(view);
//container.removeView((LinearLayout)object);
}
}
You are returning 0 in getCount(). Return length of the number of images you want to show like this:
#Override
public int getCount() {
return image_resources.length;
}

ViewPager extending PagerAdapter is not able to set view

My code for this class is unable to show view at the 0th position and is also showing irrelevant data sometime. This view pager is attached with a tablayout.
I want to know why this is happening and if there is some other way to handle viewpager extending PagerAdapter.I will be happy if I will come to know about some another class relevant to PagerAdapter but without using Fragment.
public class JobcardListViewPagerAdapter extends PagerAdapter implements IWebServiceAdapter {
Context mContext;
LayoutInflater mLayoutInflater;
List<TabLayoutDetails> tabLayoutDetailsList;
ActiveJobCardListResponse activeJobCardListResponse;
Activity activity;
View itemView;
WebService webService;
public JobcardListViewPagerAdapter(Context context, List<TabLayoutDetails> tabLayoutDetailsList) {
mContext = context;
mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.tabLayoutDetailsList = tabLayoutDetailsList;
webService = new WebService();
}
public JobcardListViewPagerAdapter() {
}
#Override
public int getCount() {
return tabLayoutDetailsList.size(); // value of tabLayoutDetailsList.size() returning 10;
}
#Override
public CharSequence getPageTitle(int position) {
return tabLayoutDetailsList.get(position).getDescription();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((LinearLayout) object);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
itemView = mLayoutInflater.inflate(R.layout.active_job_card_list_view_pager_adapter, container, false);
GetActiveJobCardList(position);
container.addView(itemView);
return itemView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((LinearLayout) object);
}
}

Android - ViewPager flipping just Layouts instead of Fragments

Is there a simple way on Android how to flip between different layouts without the need of using fragments. My views are static (nothing really happens there) but for localization purposes we won't be using images so I would go for layout solution.
I would be grateful for a good example showing this technique.
EDIT:
Here is fully working code based on the answer below:
public class LayoutPagerAdapter : PagerAdapter
{
Context m_context;
readonly int[] m_slideLayoutResourceIds;
public LayoutPagerAdapter(Context context, int[] slideLayoutResourceIds)
{
m_context = context;
m_slideLayoutResourceIds = slideLayoutResourceIds;
}
public override Java.Lang.Object InstantiateItem(ViewGroup container, int position)
{
var inflater = LayoutInflater.From(m_context);
var view = inflater.Inflate(m_slideLayoutResourceIds[position], container, false);
container.AddView(view);
return view;
}
public override void DestroyItem(View container, int position, Java.Lang.Object objectValue)
{
base.DestroyItem(container, position, objectValue);
}
#region implemented abstract members of PagerAdapter
public override bool IsViewFromObject(View view, Java.Lang.Object objectValue)
{
return view == objectValue;
}
public override int Count
{
get
{
return m_slideLayoutResourceIds.Length;
}
}
#endregion
}
You can create your own simple adapter for that:
public static class ViewPagerAdapter extends PagerAdapter {
private Context mContext;
public ViewPagerAdapter(Context context) {
mContext = context;
}
#Override
public View instantiateItem(ViewGroup container, int position) {
View view = LayoutInflater.from(mContext).inflate(R.layout.your_layout, container, false);
return view;
}
#Override
public int getCount() {
return 5;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
}

How do I access my Views when using ViewPager/PagerAdapter?

Similar question Access ViewPager views from onCreate?
I created a ViewPager where different layout can moves around. One layout has a button. My question is if a user click on this button, he will move another page. How to achieve it. Here is the viewpager adapter class:
public class SwipeAdapter extends PagerAdapter {
private LayoutInflater mInflater;
private static int[] mLayouts = { R.layout.view_layout1,
R.layout.view_layout2, R.layout.view_layout3, R.layout.view_layout4 };
SwipeAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
ViewGroup pageView= (ViewGroup) mInflater.inflate(mLayouts[position],
container, false);
container.addView(pageView);
getItemPosition(pageView);
return pageView;
}
/**
* #return the mCurrentposition
*/
#Override
public int getCount() {
return mLayouts.length;
}
#Override
public boolean isViewFromObject(View view, Object obj) {
return view == obj;
}
}

Categories

Resources