what I am trying to do is close the image adapter at the click of a button placed in the third view.
I am setting the views following this tutorial and it works fine: https://www.journaldev.com/10096/android-viewpager-example-tutorial
Now what I am trying to do is close the adapter with a botton in the last view. I get an error that says that points the button: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
I think this is because the button is not on the main layout but on the view layout. so how can I acces it correctly to hide/close the adapter
this is the main
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView3 = findViewById(R.id.textView3);
textView3.setVisibility(View.INVISIBLE);
btnClose=findViewById(R.id.btnClose);
viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPager.setAdapter(new CustomPagerAdapter(this));
viewPager.setPageTransformer(true, new ZoomOutPageTransformer());
btnClose.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
viewPager.setVisibility(View.INVISIBLE);
textView3.setVisibility(View.VISIBLE);
}
});
}
This is the adapter
public class CustomPagerAdapter extends PagerAdapter {
private Context mContext;
public CustomPagerAdapter(Context context) {
mContext = context;
}
#Override
public Object instantiateItem(ViewGroup collection, int position) {
ModelObject modelObject = ModelObject.values()[position];
LayoutInflater inflater = LayoutInflater.from(mContext);
ViewGroup layout = (ViewGroup) inflater.inflate(modelObject.getLayoutResId(), collection, false);
collection.addView(layout);
return layout;
}
#Override
public void destroyItem(ViewGroup collection, int position, Object view) {
collection.removeView((View) view);
}
#Override
public int getCount() {
return ModelObject.values().length;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
#Override
public CharSequence getPageTitle(int position) {
ModelObject customPagerEnum = ModelObject.values()[position];
return mContext.getString(customPagerEnum.getTitleResId());
}
}
This is the model object class
public enum ModelObject {
RED(R.string.red, R.layout.view_red),
BLUE(R.string.blue, R.layout.view_blue),
GREEN(R.string.green, R.layout.view_green);
private int mTitleResId;
private int mLayoutResId;
ModelObject(int titleResId, int layoutResId) {
mTitleResId = titleResId;
mLayoutResId = layoutResId;
}
public int getTitleResId() {
return mTitleResId;
}
public int getLayoutResId() {
return mLayoutResId;
}
}
Just to know how it works I want to hide the adapter and show a textview. Again I think the problem is the button being on another layout, so how can I call it?
Implement your listener in main class & pass it to viewpager. Attach the listener on demand, only the review view.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView3 = findViewById(R.id.textView3);
textView3.setVisibility(View.INVISIBLE);
viewPager = (ViewPager) findViewById(R.id.viewpager);
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View arg0) {
viewPager.setVisibility(View.INVISIBLE);
textView3.setVisibility(View.VISIBLE);
}
}
viewPager.setAdapter(new CustomPagerAdapter(this), listener);
viewPager.setPageTransformer(true, new ZoomOutPageTransformer());
}
public class CustomPagerAdapter extends PagerAdapter {
private Context mContext;
private View.OnClickListener mListener;
public CustomPagerAdapter(Context context, View.OnClickListener listener) {
mContext = context;
mListener = listener;
}
#Override
public Object instantiateItem(ViewGroup collection, int position) {
ModelObject modelObject = ModelObject.values()[position];
LayoutInflater inflater = LayoutInflater.from(mContext);
ViewGroup layout = (ViewGroup) inflater.inflate(modelObject.getLayoutResId(), collection, false);
collection.addView(layout);
if (position == 2) {
View btnClose = layout.findViewById(R.id.btnClose);
btnClose.setOnClickListener(mListener);
}
return layout;
}
#Override
public void destroyItem(ViewGroup collection, int position, Object view) {
collection.removeView((View) view);
}
#Override
public int getCount() {
return ModelObject.values().length;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
#Override
public CharSequence getPageTitle(int position) {
ModelObject customPagerEnum = ModelObject.values()[position];
return mContext.getString(customPagerEnum.getTitleResId());
}
}
Related
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);
}
}
}
public class IMResponseActivity extendsAppCompatActivity implements
ViewPager.OnClickListener {
private static ViewPager viewPager_response;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
setContentView(R.layout.activity_imresponse);
setUI();
setViewPager();
} catch (Exception e) {
e.printStackTrace();
}
}
setViewPager() {
for (int i = 0; i < IMAGES.length; i++)
ImagesArray.add(IMAGES[i]);
viewPager_response = (ViewPager) findViewById(R.id.pager_response);
CircleIndicator indicator = (CircleIndicator) findViewById(R.id.indicator);
viewPager_response.setAdapter(new CommonSlideImageAdapter1(IMResponseActivity.this, ImagesArray));
}
public void onClick(View v) {
switch (v.getId()) {
/* case R.id.pager_response:
fragment = new ItemDetailFragment();
//Fragment fragment = new SingleProductFragment();
//Fragment fragment = new ProfileFragment();
// toolbar.setVisibility(View.GONE);
container.setVisibility(View.VISIBLE);
imresponse_layout.setVisibility(View.INVISIBLE);
ft.add(R.id.container_response_details, fragment);
ft.addToBackStack(null);
ft.commit();
break;*/
}
}
// here is my Adapter Code
public class CommonSlideImageAdapter1 extends PagerAdapter {
private ArrayList<Integer> IMAGES;
private LayoutInflater inflater;
private Context context;
public CommonSlideImageAdapter1(Context context, ArrayList<Integer> IMAGES) {
this.context = context;
this.IMAGES=IMAGES;
inflater = LayoutInflater.from(context);
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
#Override
public int getCount() {
return IMAGES.size();
}
#Override
public Object instantiateItem(ViewGroup view, final int position) {
View imageLayout = inflater.inflate(R.layout.common_slideimage_layout1, view, false);
assert imageLayout != null;
final ImageView imageView = (ImageView) imageLayout
.findViewById(R.id.image);
imageView.setImageResource(IMAGES.get(position));
imageView.setClickable(true);
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
view.addView(imageLayout, 0);
return imageLayout;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view.equals(object);
}
#Override
public void restoreState(Parcelable state, ClassLoader loader) {
}
#Override
public Parcelable saveState() {
return null;
}
}
Their is no direct way to implement onItemClick listener and onClickListener in viewpager because it contains different fragments and fragments have their own listeners etc.
so the
first solution for this is implement click listener in fragment
Second solution is to implement your own click listener by extending viewpager class.
to do this there is great solution available
ViewPager OnItemClickListener
hope this will help you.
I currently am using this code to try and open a new activity from an activity that's part of a pager adapter that's swiping between 3 activities.
public class CustomPagerAdapter extends PagerAdapter implements OnClickListener {
private Context mContext;
public CustomPagerAdapter(Context context){
mContext = context;
}
#Override
public Object instantiateItem(ViewGroup collection, int position) {
ModelObject modelObject = ModelObject.values()[position];
LayoutInflater inflater = LayoutInflater.from(mContext);
ViewGroup layout = (ViewGroup)
inflater.inflate(modelObject.getLayoutResId(), collection, false);
collection.addView(layout);
return layout;
}
#Override
public void destroyItem(ViewGroup collection, int position, Object view) {
collection.removeView((View) view);
}
#Override
public int getCount() {
return ModelObject.values().length;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
#Override
public CharSequence getPageTitle(int position) {
ModelObject customPagerEnum = ModelObject.values()[position];
return mContext.getString(customPagerEnum.getTitleResId());
}
public void onClick(View view) {
//start new activity
Intent i = new Intent(mContext, SubjectActivity.class);
mContext.startActivity(i);
}
}
The code itself isn't throwing any errors, but when I run the app it stops the moment I click on the button. It wasn't having problems before I attempted to implement the onClick function so I am certain the problem is with how I have written that, but I can't figure out where. What is the issue with this method of opening a new activity?
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 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.