I followed this tutorial to make an image slider with images url but the slider is empty.
Here is my adapter's code:
public class ViewPagerAdapterUrl extends PagerAdapter {
private Context context;
private LayoutInflater layoutInflater;
private ArrayList<String> photosUrl= new ArrayList<>();
public ViewPagerAdapterUrl(Context context, ArrayList<String> photosUrl){
this.context = context;
this.photosUrl = photosUrl;
}
#Override
public int getCount() {
return photosUrl.size();
}
#Override
public boolean isViewFromObject(#NonNull View view, #NonNull Object object) {
return view == object;
}
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position) {
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = layoutInflater.inflate(R.layout.viewpager_layout, null);
ImageView imageView = (ImageView)view.findViewById(R.id.imageView);
Picasso.get().load(photosUrl.get(position)).into(imageView);
container.addView(imageView);
return imageView;
}
#Override
public void destroyItem(#NonNull ViewGroup container, int position, #NonNull Object object) {
container.removeView((View)object);
}
}
Here is the activity where i want to show the adapter:
public class UrlActivity extends AppCompatActivity {
private Advertisement adv;
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_url);
viewPager = (ViewPager)findViewById(R.id.viewPager);
//adv is a custom object that contain an arraylist<String> of url.
adv = (Advertisement)getIntent().getSerializableExtra("adv");
ViewPagerAdapterUrl viewPagerAdapterUrl = new ViewPagerAdapterUrl(this, adv.getPhotosUrl());
viewPager.setAdapter(viewPagerAdapterUrl);
}
}
EDIT
I found this in debug but it isn't show like an error:
method int android.support.v7.widget.DropDownListView.lookForSelectablePosition(int, boolean) would have incorrectly overridden the package-private method in android.widget.ListView
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);
}
}
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 3 years ago.
Attempt to invoke virtual method 'void androidx.viewpager.widget.ViewPager.setAdapter(androidx.viewpager.widget.PagerAdapter)' on a null object reference
I'm trying to implement sliding tab layout using android material design. But it gives me NullPointerException. Here is my code so far:
public class HomeFragment extends Fragment {
private HomeViewModel homeViewModel;
private List<Slide> listSlides;
private ViewPager slidePager;
private TabLayout indicator;
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
homeViewModel =
ViewModelProviders.of(this).get(HomeViewModel.class);
View root = inflater.inflate(R.layout.fragment_home, container, false);
listSlides = new ArrayList<>();
listSlides.add(new Slide(R.drawable.a, "slide title"));
listSlides.add(new Slide(R.drawable.b, "slide title"));
final SliderPagerAdapter adapter = new SliderPagerAdapter(getContext(), listSlides);
homeViewModel.getText().observe(this, new Observer<String>() {
#Override
public void onChanged(#Nullable String s) {
slidePager.setAdapter(adapter);
}
});
return root;
}
}
public class SliderPagerAdapter extends PagerAdapter {
private Context mText;
private List<Slide> mList;
public SliderPagerAdapter(Context mText, List<Slide> mList) {
this.mText = mText;
this.mList = mList;
}
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position) {
LayoutInflater inflater = (LayoutInflater) mText.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View slideLayout = inflater.inflate(R.layout.slider_item,null);
ImageView slideImg = slideLayout.findViewById(R.id.slide_img);
TextView slideText= slideLayout.findViewById(R.id.slide_title);
slideImg.setImageResource(mList.get(position).getImage());
slideText.setText(mList.get(position).getTitle());
container.addView(slideLayout);
return slideLayout;
}
#Override
public int getCount() {
return mList.size();
}
#Override
public boolean isViewFromObject(#NonNull View view, #NonNull Object object) {
return view == object;
}
#Override
public void destroyItem(#NonNull ViewGroup container, int position, #NonNull Object object) {
container.removeView((View) object);
}
}
You didn't instantiate the slidePagerso when you try to setAdapter, it is in fact a null object. You should call a findViewById on the ViewPager.
I am developing a simple gallery app .
I have 2 problems :
First problem :
When I touch a specific image in my GridView to show in the fullscreen activity (viewpager activity) it always shows the first image in the GridView gallery!!! not the one I touched!!!
But ViewPager work correctly .
Second problem:
I want to zoom in the ViewPager activity
I tried a library (chrisbanes:phtoview) but it has some issues with ViewPager
Summary :
I want my gallery app to work normal. GridView gallery (you can swipe and pinch to zoom images)
MainActivity.java
public class MainActivity extends AppCompatActivity {
private ViewPager slider;
private SliderAdapter sliderAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
slider=findViewById(R.id.slider);
sliderAdapter=new SliderAdapter(this);
slider.setAdapter(sliderAdapter);
}
private class SliderAdapter extends PagerAdapter{
private Context context;
private LayoutInflater inflater;
public SliderAdapter(Context context) {
this.context = context;
}
int[] list_img={R.drawable.ferari,R.drawable.ferrari,R.drawable.ferrarilogoo,R.drawable.yellowferrariiii,R.drawable.models,R.drawable.applogo,R.drawable.carfront,R.drawable.california,R.drawable.laferrari
};
#Override
public int getCount() {
return list_img.length;
}
#Override
public boolean isViewFromObject(#NonNull View view, #NonNull Object object) {
return view==object;
}
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, final int position) {
inflater=(LayoutInflater)context.getSystemService(LAYOUT_INFLATER_SERVICE);
View view=inflater.inflate(R.layout.item_slider,container,false);
ImageView imageView=view.findViewById(R.id.img_item);
imageView.setImageResource(list_img[position]);
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent=new Intent(context,Fullscreen.class);
intent.putExtra("Ferrari",position);
startActivity(intent);
}
});
container.addView(view);
return view;
}
#Override
public void destroyItem(#NonNull ViewGroup container, int position, #NonNull Object object) {
container.removeView((ImageView)object);
}
}
}
ImageAdapter.java
public class ImageAdapter extends BaseAdapter {
private Context mContext;
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return null;
}
public long getItemId(int position) {
return 0;
}
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
// if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new ViewGroup.LayoutParams(230, 250));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(3, 3, 3, 3);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
// references to our images
public Integer[] mThumbIds = {
R.drawable.ferari, R.drawable.models,
R.drawable.ferrarihd,
R.drawable.ferrari,
R.drawable.yellowferrariiii,
R.drawable.models,
R.drawable.home,
R.drawable.carfront,
R.drawable.villa,
R.drawable.derrarii,
R.drawable.laferrari,
R.drawable.realestate,
R.drawable.carfront,R.drawable.california,R.drawable.laferrari
};
}
FullscreenviewActivity.java
public class FullScreenViewActivity extends AppCompatActivity {
private ViewPager slider;
private SliderAdapter sliderAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_full_screen_view);
slider=findViewById(R.id.slider);
sliderAdapter=new SliderAdapter(this);
slider.setAdapter(sliderAdapter);
slider.setPageTransformer(false, new ViewPager.PageTransformer() {
#Override
public void transformPage(View page, float position) {
// do transformation here
final float normalizedposition = Math.abs(Math.abs(position) - 1);
page.setScaleX(normalizedposition / 2 + 0.5f);
page.setScaleY(normalizedposition / 2 + 0.5f);
//or
// page.setRotationY(position * -30);
}
});
// get intent data
Intent i = getIntent();
// Selected image id
int position = i.getExtras().getInt("id");
ImageAdapter gridViewAdapter = new ImageAdapter(this);
gridViewAdapter.getItemId(position);
}
private class SliderAdapter extends PagerAdapter {
private Context context;
private LayoutInflater inflater;
public SliderAdapter(Context context) {
this.context = context;
}
int[] mThumbIds={ R.drawable.ferari, R.drawable.models,
R.drawable.ferrarihd,
R.drawable.ferrari,
R.drawable.yellowferrariiii,
R.drawable.models,
R.drawable.home,
R.drawable.carfront,
R.drawable.villa,
R.drawable.derrarii,
R.drawable.laferrari,
R.drawable.realestate,
R.drawable.carfront,R.drawable.california,R.drawable.laferrari
};
#Override
public CharSequence getPageTitle (int position) {
return "Ferrari Cars";
}
#Override
public int getCount() {
return mThumbIds.length;
}
#Override
public boolean isViewFromObject(#NonNull View view, #NonNull Object object) {
return view==object;
}
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, final int position) {
inflater=(LayoutInflater)context.getSystemService(LAYOUT_INFLATER_SERVICE);
View view=inflater.inflate(R.layout.item_slider,container,false);
ImageView imageView=view.findViewById(R.id.img_item);
imageView.setImageResource(mThumbIds[position]);
container.addView(view);
return view;
}
#Override
public void destroyItem(#NonNull ViewGroup container, int position, #NonNull Object object) {
container.removeView((ImageView)object);
}
}
}
Firstly you have the position of image in FullScreenActivity so only do one thing to scroll that image
slider.setCurrentItem(pos);
After
int position = i.getExtras().getInt("id");
And use TouchImageView for zoom
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.