I have a regular ViewPager with an adapter:
public class MyDialogFragment extends DialogFragment {
private ViewPager viewPager;
private MyViewPagerAdapter myViewPagerAdapter;
private City city;
public static MyDialogFragment newInstance() {
MyDialogFragment fragment = new MyDialogFragment();
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_layout, container, false);
viewPager = (ViewPager) v.findViewById(R.id.viewPager);
city = Parcels.unwrap(getArguments().getParcelable("city"));
myViewPagerAdapter = new MyViewPagerAdapter(getContext());
viewPager.setAdapter(myViewPagerAdapter);
viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// Page changed
}
});
return v;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public class MyViewPagerAdapter extends PagerAdapter {
private Context context;
private LayoutInflater layoutInflater;
public MyViewPagerAdapter(Context context) {
this.context = context;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
layoutInflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = layoutInflater.inflate(R.layout.city_layout, container, false);
ImageView imageView = (ImageView) view.findViewById(R.id.cityImage);
Glide.with(context)
.load(city.getImage())
.into(imageView);
}
container.addView(view);
return view;
}
#Override
public int getCount() {
return city.size();
}
#Override
public boolean isViewFromObject(View view, Object obj) {
return view == ((View) obj);
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
}
As you can see, I have a page change listener set on my ViewPager. But I need to be able to notify the adapter when the page has changed so that I can modify the adapter's ImageView. How can I do this?
Add a method to your adapter class
public class MyViewPagerAdapter extends PagerAdapter {
...
public void pageChanged(int position) {
// Do something
}
...
}
After that in your OnPageChangeListener use that method
#Override
public void onPageSelected(int position) {
myViewPagerAdapter.pageChanged(position);
}
One approach is to create a data structure in your adapter to map the pager view to its position. A SparseArray is most efficient:
private SparseArray<View> pageMap = new SparseArray<>();
Then in the adapter's instantiateItem() method, add the view to the SparseArray:
public Object instantiateItem(ViewGroup container, int position) {
...
pageMap.put(position, view);
...
}
Now in your OnPageChangeListener you can do the following:
#Override
public void onPageSelected(int position) {
View view = adapter.getView(pos);
if (view != null) {
ImageView iv = (ImageView) view.findViewById(R.id.your_image_view);
// You now have the image view
}
}
Make sure you remove views from the SparseArray in the adapter's destroyItem() method:
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
pageMap.remove(position);
...
}
You can use the constructor with imagelist to pass and that automatically called on next page..In your code will be modified like :::
ArrayList imageList=new ArrayList<>();
imageList.add("ImagePath here");
myViewPagerAdapter = new MyViewPagerAdapter(getContext(),imageList);
viewPager.setAdapter(myViewPagerAdapter);
Then your adapter will be like ::
public class MyViewPagerAdapter extends PagerAdapter {
private Context context;
private ArrayList<String> imageList
private LayoutInflater layoutInflater;
public MyViewPagerAdapter(Context context,ArrayList<String> imageList) {
this.context = context;
this.imageList = imageList;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
layoutInflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = layoutInflater.inflate(R.layout.city_layout, container, false);
ImageView imageView = (ImageView) view.findViewById(R.id.cityImage);
Glide.with(context)
.load(imageList.get(position)) // This will be changes like
.into(imageView);
}
container.addView(view);
return view;
}
#Override
public int getCount() {
return city.size();
}
#Override
public boolean isViewFromObject(View view, Object obj) {
return view == ((View) obj);
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
That done ..
After this, there are some suggestion that
- please use arraylist while using the viewpager ..
Now you just taking the parceble object from bundle..
you can do the same for the arraylist,
just receive the arraylist from the same bundle by passing the whole arraylist at once.
so you dont need to find the page change event..viewpager will automatically handle that..
Here's How to send & receiving the parceable arraylist
// while sending the list
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("citylist", new ArrayList<City>());
// while receiving the list
ArrayList<City> citylist = getIntent().getParcelableArrayListExtra("citylist");
After this just get the all image and add in the imagelist array
for (int i = 0; i < citylist.size(); i++) {
imageList.add(citylist.get(i).getImage());
}
And pass this imageList in
myViewPagerAdapter = new MyViewPagerAdapter(getContext(),imageList);
viewPager.setAdapter(myViewPagerAdapter);
Tell me if needed more assitance.
Related
I have struggled a lot with my ViewPagerAdapter for remove/disable pages. But nothing happens. Is there any ways to remove pages from a ViewPagerAdapter? Here is my code-
As you can see, I have three positions there. I just want to remove/disable position 1(paragraph 1).
public class ViewPagerAdapter2 extends PagerAdapter
{
private Context context;
private LayoutInflater layoutInflater;
String strings[] = {
"paragraph 0",
"paragraph 1",
"paragraph 2"
};
public ViewPagerAdapter2 (Context context) {
this.context = context;
}
#Override
public int getCount()
{
// TODO: Implement this method
return strings.length;
}
#Override
public boolean isViewFromObject(View view, Object object)
{
// TODO: Implement this method
return view == object;
}
#Override
public Object instantiateItem(ViewGroup container, int position)
{
layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = layoutInflater.inflate(R.layout.view_pager_lyrics,null);
final TextView textView = view.findViewById(R.id.view_pager_lyricsTextView);
textView.setText(Html.fromHtml("<!DOCTYPE html><html><head></head><body><div style='text-align: center'><p>"+strings[position]+"</p></div></body></html>"));
return view;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object)
{
ViewPager vp = (ViewPager) container;
View view = (View) object;
vp.removeView(view);
}
}
I am trying to load images from sd card in view pager . I have got the arrayList of uri . How to change my code to open these images instead of drawables.
my mainAvtivity class
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_pager);
mCustomPageAdapter = new CustomPageAdapter(this);
viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setAdapter(mCustomPageAdapter);
}
public class CustomPageAdapter extends PagerAdapter {
Context mContext;
LayoutInflater mLayoutInflater;
public CustomPageAdapter(Context context) {
mContext = context;
mLayoutInflater=(LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return resourceIDs.length;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((LinearLayout) object);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
View itemView = mLayoutInflater.inflate(R.layout.pager_item,container, false);
ImageView imageView = (ImageView)itemView.findViewById(R.id.imageView);
imageView.setImageResource(resourceIDs[position]);
container.addView(itemView);
return itemView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((LinearLayout) object);
}
}
}
Lets say you have ArrayList<Uri> uriList. Now change the code like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_pager);
mCustomPageAdapter = new CustomPageAdapter(this);
viewPager = (ViewPager) findViewById(R.id.pager);
viewPager.setAdapter(mCustomPageAdapter);
}
public class CustomPageAdapter extends PagerAdapter {
Context mContext;
LayoutInflater mLayoutInflater;
public CustomPageAdapter(Context context) {
mContext = context;
mLayoutInflater=(LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return uriList.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((LinearLayout) object);
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
View itemView = mLayoutInflater.inflate(R.layout.pager_item,container, false);
ImageView imageView = (ImageView)itemView.findViewById(R.id.imageView);
imageView.setImageURI((uriList.get(position));
container.addView(itemView);
return itemView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((LinearLayout) object);
}
}
}
I am using viewpager with Pager adapter and passing an arraylist in the adapter. The arraylist has size "0" in the start but once it is filled, I am calling viewpager.notifydatasetchanged().After calling notifydatasetchanged the method CharSequence getPageTitle(int position) is not called and titles are not updated dynamically.
My adapter code:
public class MyViewPagerAdapter extends PagerAdapter {
private ArrayList<String> arrayList;
private Activity activity;
public ViewPagerAdapter(Activity activity, ArrayList<String> arrayList) {
this.activity = activity;
this.arrayList = arrayList;
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
#Override
public int getCount() {
return arrayList.size();
}
#Override
public boolean isViewFromObject(#NonNull View view, Object o) {
return o == view;
}
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position) {
// Inflate a new layout from our resources
View view = activity.getLayoutInflater().inflate(R.layout.pager_item,
container, false);
// Add the newly created View to the ViewPager
container.addView(view);
// Retrieve a TextView from the inflated View, and update it's text
TextView tvWeatherDescription = view.findViewById(R.id.tv);
// Return the View
return view;
}
#Override
public CharSequence getPageTitle(int position) {
return arrayList.get(position);
}
#Override
public void destroyItem(#NonNull ViewGroup container, int position, #NonNull Object object) {
container.removeView((View) object);
}
}
My Activity code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayList<String> arrayList = new ArrayList<String>
ViewPager viewpager = findviewbyId(R.id.viewpager);
MyViewPagerAdapter adapter = new MyViewPagerAdapter(MainActivity.this, arraylist);
viewpager.setAdapter(adapter);
SlidingTabLayout slidingTabLayout = findViewById(R.id.sliding_tabs);
slidingTabLayout.setViewPager(viewpager);
}
Once the size of arraylist is changed I am calling it like this:
arraylist.add("Item1")
adapter.notifydatasetchanged();
but the title value is not changing.Is there any way that method CharSequence getPageTitle(int position) is called after notifydatasetchanged?
I have a pageradapter that i am using to display a slideshow of images but it crashes when i set a lower off screen limit.
Here is my code
public class ProjectPicturesAdapter extends PagerAdapter {
private List<String> pictures;
private LayoutInflater inflater;
private final RequestManager glide;
public ProjectPicturesAdapter(RequestManager glide, LayoutInflater inflater, List<String> pictures) {
this.pictures = pictures;
this.glide = glide;
this.inflater = inflater;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
View image = inflater.inflate(R.layout.slider_image, container, false);
ImageView myImage = (ImageView) image.findViewById(R.id.image);
glide.load(pictures.get(position))
.centerCrop()
.crossFade()
.placeholder(R.drawable.project_placeholder)
.into(myImage);
container.addView(myImage);
return myImage;
}
#Override
public void destroyItem(ViewGroup container, int position, Object view) {
container.removeView((View) view);
}
#Override
public int getCount() {
return pictures.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view.equals(object);
}
}
The way i am initializing the adapter is this
ProjectPicturesAdapter picturesAdapter = new
ProjectPicturesAdapter(Glide.with(this), LayoutInflater.from(this),
images);
ViewPager pager = (ViewPager) findViewById(R.id.viewPager);
pager.setAdapter(picturesAdapter);
pager.setOffscreenPageLimit(1);
If there are more than 2 images then it crashes,i could always increase the off screen limit but what happens if there are 20 pictures,i cannot keep the offscreen limit as 20.
My crash log is gives an error saying The specified child already has a parent. You must call removeView() on the child's parent first.
Update ProjectPicturesAdapter as below:
public class ProjectPicturesAdapter extends PagerAdapter {
private List<String> pictures;
private LayoutInflater inflater;
private final RequestManager glide;
public ProjectPicturesAdapter(RequestManager glide, LayoutInflater inflater, List<String> pictures) {
this.pictures = pictures;
this.glide = glide;
this.inflater = inflater;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
ViewGroup view = (ViewGroup) inflater.inflate(R.layout.slider_image, container, false);
ImageView myImage = (ImageView) view.findViewById(R.id.image);
glide.load(pictures.get(position))
.centerCrop()
.crossFade()
.placeholder(R.drawable.project_placeholder)
.into(myImage);
container.addView(view);
return view;
}
#Override
public void destroyItem(ViewGroup container, int position, Object view) {
container.removeView((View) view);
}
#Override
public int getCount() {
return pictures.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
}
If your aim is to show the carousel?
Just use this library and your problem will be solved https://github.com/sayyam/carouselview
The problem is caused by this:
#Override
public void destroyItem(ViewGroup container, int position, Object view)
{
container.removeView((View) view);
}
I recommend to use FragmentStatePagerAdapter instead of PagerAdapter.
public static class MyAdapter extends FragmentStatePagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return NUM_ITEMS;
}
#Override
public Fragment getItem(int position) {
return ArrayListFragment.newInstance(position);
}
}
mAdapter = new MyAdapter(getFragmentManager());
mPager = (ViewPager)findViewById(R.id.pager);
mPager.setAdapter(mAdapter);
i'm trying to put ViewPager into ListView
here the code of ListView AdapterClass:
public class AdapterPager extends BaseAdapter {
.....
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
view = lInflater.inflate(R.layout.component_pager, parent, false);
new ViewHolder(view, itemData.get(position));
}
return view;
}
View Holder:
private class ViewHolder {
ViewPager pager;
PagerAdapter pagerAdapter;
public ViewHolder(View view, ModelItem model){
pager = (ViewPager) view.findViewById(R.id.pager);
pager.setId(model.getId()); /// uniq ID
pagerAdapter = new MyFragmentPagerAdapter(((FragmentActivity)view.getContext()).getSupportFragmentManager());
pager.setAdapter(pagerAdapter);
}
then, Pager Adapter:
static final int PAGE_COUNT = 2;
private class MyFragmentPagerAdapter extends FragmentPagerAdapter {
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return FragmentComponentPager.newInstance(position, mModel);
}
#Override
public float getPageWidth(int position) {
float f_width = 1f;
return f_width;
}
#Override
public int getCount() {
return PAGE_COUNT;
}
}
and, the last, Pager Fragment:
public class FragmentComponentPager extends Fragment {
static final String ARGUMENT_PAGE_NUMBER = "arg_page_number";
static final String ARGUMENT_NAME = "arg_name";
int pageNumber;
public static FragmentComponentPager newInstance(int page, ModelItem data) {
FragmentComponentPager pageFragment = new FragmentComponentPager();
Bundle arguments = new Bundle();
arguments.putInt(ARGUMENT_PAGE_NUMBER, page);
if (data != null){
arguments.putString(ARGUMENT_NAME, data.getName());
}
pageFragment.setArguments(arguments);
return pageFragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
pageNumber = getArguments().getInt(ARGUMENT_PAGE_NUMBER);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.component_list, null);
TextView tvTitle = (TextView) view.findViewById(R.id.tvTitle);
tvTitle.setText(getArguments().getString(ARGUMENT_NAME));
return view;
}
}
when i run it ListView shows all items that i've added, but all of them, except the last one, with empty ViewPager.
and, if i removed pager.setId(model.getId()); the first item shows view pager, and the others empty.
guess that smth wrong with FragmentManager, but have no idea how deal with it :(
In your ViewHolder you need to call getChildFragmentManager instead of getSupportFragmentManager.