javaandroidandroid-viewpagerandroid-pageradapter

Correctly implementing PagerAdapter in Android


I have problems with implementation of my custom PagerAdapter and using it with a ViewPager. This sample PagerAdapter has 10 items, every item is a button with it's index as text. When I run my program, I see a button with text '1' insted of '0'. And when I swipe to other items I get only blank views. When I swipe backwards sometimes I see a button with some number, but it disappears (maybe it is destroying and I remove it from the container), and sometimes I see a button with a number, but the number changes after the swipe (I think I create a new Button and I add it to the container, and for some reasons the viewpager shows this new button).

How can I fix this implementation? I haven't seen difference in examples.

My PagerAdapter implementation:

public class MyPagerAdapter extends PagerAdapter {

    @Override
    public int getCount() {
        return 10;
    }

    @Override
    public boolean isViewFromObject(View view, Object o) {
        return o.getClass()==view.getClass();
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        Button button = new Button(container.getContext());
        ViewGroup.LayoutParams params = new ActionBar.LayoutParams(-1,-1);
        button.setLayoutParams(params);
        button.setText(String.valueOf(position));
        container.addView(button);
        return button;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((Button)object);
    }
}

And my Activity:

public class MainActivity extends ActionBarActivity {

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

        ViewPager pager = (ViewPager) findViewById(R.id.pager);
        pager.setAdapter(new MyPagerAdapter());
    }
}

Solution

  • Here is complete code:

    xml layout:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        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"
        android:orientation="vertical"
        tools:context="com.example.androidviewpagerapp.MainActivity" >
    
        <android.support.v4.view.ViewPager
            android:id="@+id/pager"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    
    </LinearLayout>
    

    MyPagerAdapter class:

    import android.support.v4.view.PagerAdapter;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Button;
    import android.widget.Toast;
    
    public class MyPagerAdapter extends PagerAdapter {
    
        @Override
        public int getCount() {
            return 10;
        }
    
        @Override
        public boolean isViewFromObject(View view, Object o) {
            return o==view;
        }
    
        @Override
        public Object instantiateItem(final ViewGroup container, int position) {
            Button button = new Button(container.getContext());
            ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            button.setLayoutParams(params);
            button.setText(String.valueOf(position));
    
            final int page = position;
            button.setOnClickListener(new View.OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    Toast.makeText(container.getContext(), "You clicked: " + page + ". page.", Toast.LENGTH_SHORT).show();
                }
            });
    
            container.addView(button);
            return button;
        }
    
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((Button)object);
        }
    }
    

    MainActivity:

    import android.support.v4.view.ViewPager;
    import android.app.Activity;
    import android.os.Bundle;
    
    public class MainActivity extends Activity {
        ViewPager viewPager;
        MyPagerAdapter myPagerAdapter;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            viewPager = (ViewPager)findViewById(R.id.pager);
            myPagerAdapter = new MyPagerAdapter();
            viewPager.setAdapter(myPagerAdapter);
        }
    }
    

    You will see that Buttons are full screen. To avoid that you need to create some layout (like LinearLayout) and add button to that layout.

    Example:

    import android.support.v4.view.PagerAdapter;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Button;
    import android.widget.LinearLayout;
    import android.widget.Toast;
    
    public class MyPagerAdapter extends PagerAdapter {
    
        @Override
        public int getCount() {
            return 10;
        }
    
        @Override
        public boolean isViewFromObject(View view, Object o) {
            return o==view;
        }
    
        @Override
        public Object instantiateItem(final ViewGroup container, int position) {
            Button button = new Button(container.getContext());
            ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            button.setLayoutParams(params);
            button.setText(String.valueOf(position));
    
            LinearLayout layout = new LinearLayout(container.getContext());
            layout.setOrientation(LinearLayout.VERTICAL);
            ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
    
            //add buton to layout
            layout.addView(button);
    
            final int page = position;
            button.setOnClickListener(new View.OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    Toast.makeText(container.getContext(), "You clicked: " + page + ". page.", Toast.LENGTH_SHORT).show();
                }
            });
            //to container add layout instead of button
            container.addView(layout);
            //return layout instead of button
            return layout;
        }
    
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            //cast to LinearLayout
            container.removeView((LinearLayout)object);
        }
    }