Search code examples
androidlistviewandroid-fragmentsandroid-viewpager

Android : Single Fragment Swipe on ViewPager to load next or previous record


I have a ListView which contains product details. On Item click of listview I open new activity with particular product detail. I wanted to convert activity to ViewPager so that I can swipe to load next and previous records in same fragment. Fragment structure will be same for all records. I don't know from where should I start. Can you give me overview idea how to achieve this. Here is my model class.

Product.java

public class Product implements Serializable{

    public int id;
    public String Name;
    public String description;
    public String longDescription;
    public String amount;
    public String image;
}

Here is my FragmentPagerAdapter class

ProductPagerAdapter.java

public class ProductPagerAdapter extends FragmentPagerAdapter {

    private Context context;
    private ArrayList<Product> list;

    public ProductPagerAdapter(FragmentManager fm, Context context, ArrayList<Product> list) {
        super(fm);
        this.context = context;
        this.list = list;
    }

    @Override
    public Fragment getItem(int position) {
        return ProductFragment.newInstance(position);
    }

    @Override
    public int getCount() {
        return list.size();
    }
}

And this is my Fragment

ProductFragment.java

public class ProductFragment extends Fragment {

    public ProductFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment

        View v = inflater.inflate(R.layout.fragment_product, container, false);

        //findViewById...

        return v;
    }

    public static Fragment newInstance(int id) {
        Bundle args = new Bundle();
        args.putInt("Id", id);
        ProductFragment fragment = new ProductFragment();
        fragment.setArguments(args);
        return fragment;
    }
}

And now on list item Click I am opening new activity. And I am sending Product object to it.

lv_itemRateList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                Intent intent = new Intent(getActivity(), DetailsActivity.class);
                Product r = new Product();
                r = rateListArrayList.get(i);
                intent.putExtra("product",r);
                startActivity(intent);
            }
        });

My DetailsActivity contains my viewpager. Now can someone tell me how to do this?


Solution

  • 1-) Need a custom adapter for ViewPager.

    I assumed that all the pages will have the same content, so all of them have the same layout so ProductPagerAdapter extends the PagerAdapter.

    public class ProductPagerAdapter extends PagerAdapter
    {
         //variables
         private Context context;
         private ArrayList<Product> list;
         private Product product
    
         //views
        TextView  txtName ;
    
        public ProductPagerAdapter(Context context, List<Product> list) 
        {
            this.context = context;
            this.list = list;
        }
    
        @Override
        public int getCount()
        {
            return  list.size();
        }
    
        @Override
        public boolean isViewFromObject(View view, Object object)
        {
            return view == ( object);
        }
    
        @Override
        public Object instantiateItem(ViewGroup container, int position) 
        {
            product = list.get(position);
    
            inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View itemView = inflater.inflate(R.layout.fragment_product, container,false);
    
            txtName = (TextView) itemView.findViewById(R.id.txtName);
            txtName.setText(product.Name)
    
            ((ViewPager) container).addView(itemView);
    
            return itemView;
        }
    
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) 
        {
            ((ViewPager) container).removeView((LinearLayout) object); 
        }
    }
    

    2-) Adapter is ready. Now let's prepare the activity that will show the details. First initialize ViewPager and ProductPagerAdapter. Then show the details of the item which is selected by clicking on the previous activity.

    public class DetailsActivity extends Activity
    {
            @Override
            protected void onCreate(Bundle savedInstanceState)
            {
                ...
    
                //getting product object
                Intent intent = getIntent();
                Product product = (Product) getIntent().getSerializableExtra("product");
    
                //get selected item id
                int selectedItemID = 0;
                for(int i = 0 ; i < list.size() ; i++) 
                {
                   if(list.get(i).id == product.id)
                   {
                    selectedItemID = i;
                    break;
                   }
                }
    
                //Init ViewPager and adapter
                ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
    
                ProductPagerAdapter detailAdapter = new ProductPagerAdapter(DetailActivity.this, list);
    
                // Binds the Adapter to the ViewPager
                viewPager.setAdapter(detailAdapter);
                viewPager.setCurrentItem(selectedItemID); // set selection
                viewPager.setPageTransformer(true, new ForegroundToBackgroundTransformer()); //custom transformer
    
                ...
            }
    }
    

    3-) We've done what we have to do so far. So it will work like this. But what I would like to point out is that there are a few things to make the ViewPager better.

    Performance : Use Parcelable instead of Serializable. Parcelable takes more time to implement but it will perform 10 times faster and use less resources. Please check this SO answer

    Animation : You may want to need animations for transforming ViewPager. I suggest you to use ViewPagerTransforms

    Indicators : If you want to use the paging indicator, I recommend ViewPagerIndicator.

    For more on ViewPager