At first I thought it's easy, someone must have implemented it already, but after searching for it on Google, I got no luck, nobody has done and shared it on the Net, so I decided to make it myself.
I read some posts like:
So I implemented it as you can see in below video:
For more information, you guys can get the source code here: https://github.com/mrleolink/SimpleInfiniteCarousel. I tried to comment as much as possible in source code, so I hope you understand my idea.
I read some posts like:
So I implemented it as you can see in below video:
The main idea is:
- Use ViewPager as the main view with pages are Fragment, then use ViewPager.setPageMargin(int) to set margin as a negative number, so the next and previous pages of the selected page will be showed up.
- Override the layout which is the root view of Fragments to create scale animation.
- Make a little hack in FragmentPagerAdapter so we can fling infinitely to both directions of the ViewPager.
By the way, I don't think it's the best solution to implement the carousel pattern, so if you have any idea or there's something you don't understand about what I code, just drop me a line :)
How can I change the "black button" to image?
ReplyDeleteI want to add images each position of button.
Each page of the ViewPager is a fragment, and "black image" is a button in the layout of each fragment, you can change the Button in this:
ReplyDeletehttps://github.com/mrleolink/SimpleInfiniteCarousel/blob/master/res/layout/mf.xml
to ImageView or customize the layout as you want.
Thank you for your reply.
DeleteAs you replied, I changed it to imageview.
But, there are 4 positions that I want to put image for each position.
But I don't know how to change one by one.
If I add image on mf.xml, then all positions of the image are same.
I want..different image for each position..any suggestion please?
Oh, you have to look at:
Deletehttps://github.com/mrleolink/SimpleInfiniteCarousel/blob/master/src/net/leolink/android/simpleinfinitecarousel/MyFragment.java
For example, if you change TextView in this file:
https://github.com/mrleolink/SimpleInfiniteCarousel/blob/master/res/layout/mf.xml
to ImageView, then in MyFragment.java, you have to use "l.getViewById(your_image_view_id)" to get you ImageView and set image for it as your need. Notice that you can pass your parameters through Bundle as I push an integer "pos" into a Bundle in function "newInstance" then get it back in function "onCreateView".
Thank you for your reply again! really appreciate it!
DeleteAnd..I tried what you gave an advice..but..it's not working..I am a very beginner that..
I took one week to modify it....
I don't understand..why its not working.
If I use "l.getViewById(your_image_view_id)" then, it also appears one photo only..
but what i want is showing four different images for each position.
If you have some time, could you please modify it a bit for me?..
What I need is..as I told you before...just put four different photos instead of black button..
you can add images whatever you want..
and really appreciate that you replied me really fast! :)
DeleteThis comment has been removed by the author.
ReplyDeletei made it!! thank you for your help and advice.
ReplyDeletereally good example!! :)
May I ask how did you make it work?
DeleteOne more question!!!
ReplyDeleteI cannot use Toast message in Myoffers_Fragment.java class
Toast t = Toast.makeText(this, "System is active.", Toast.LENGTH_LONG).show();
"makeText" make error...any suggestion??
I'm glad you got it work.
DeleteAbout Toast, you can't use "this" as context for Toast inside a fragment, you have to use:
Toast t = Toast.makeText(this.getActivity(), "System is active.", Toast.LENGTH_LONG).show();
it's not working. error says "cannot convert from void to toast".
DeleteWhat I want is, showing toast message every time I pass the product with carousel view.
When I slide pos = 0 to pos =1, toast message "Product 1 is selected". like this..
But, in fragment class, i cant use toast ...i don't know why...could you give me some advice please?
Let me see the snippet that you used Toast or better show me your whole file Myoffers_Fragment.java.
Deletep/s: don't paste here, paste to www.pastebin.com then send me the link, it's easy for me to read
now working!! haha...sorry..it's weird..it was not working..but now..is working.
DeleteThanks!! Do you know how to code to open "Websocket" on client side(android) ??
As you see, I am a just beginner...so..need some help ! :p
Are you asking me to help you complete your project?
DeleteLOL, any pro was once a beginner, try to resolve it yourself, man. Google is your best friend, he is always there ;)
And I'm not a pro anyway, I only can help you within this tutorial's scope.
Good luck ;)
Hello!!! LeoLink!! I have a question with your example.
ReplyDeleteI put four products(from 0 to 3) and if I select product0, the toast message should pop up like
"Product 0 is selected." But, i don't know why, the "pos" appears incorrectly.
my code is..
ImageView product_photo = (ImageView) l.findViewById(R.id.myoffer_image);
switch(pos){
case 0:
product_photo.setImageResource(R.drawable.myoffers_0);
Toast.makeText(this.getActivity(), "Product" + pos + " is selected.", Toast.LENGTH_LONG).show();
break;
Toast message appears "product 3 is selected " for product 0, and
"product 2 is selected " for product 1, ...like this.
Can you please give me some advice?
Hello again.!! I have a question!!
ReplyDeleteI want to make a method if an image is selected.
So, I changed to ImageButton.
So, If product 0's image is clicked..an method should work..like this..
any suggestion please?
check if you placed break point in every case.
DeleteThis comment has been removed by the author.
ReplyDeleteWhen i use ViewPage Indicator .It showing PAGES*LOOPS number of page Indicator ..This is because of the Loop Hack that you used .Is there any other way to generate Loops in viewpager.
ReplyDeleteThanks
Hi LeoLink, I followed the example you provided, very interesting and instructive. I tried to place an action button that when pressed to send me to another activity, but I can not run, I'm using the position variable to send to a particular activity. Could you guide me briefly about it? Thanks for your efforts and your time.
ReplyDeleteWhere did you place your button, I think it should be placed in "mf.xml" (notice that each page of the ViewPager is a fragment!). And to make the button bahave as you expected, just create an intent and start a new activity when the button is pressed.
DeleteWhy couldnt your code run? Which exception was thrown?
Thank you for this example.This is very useful.
ReplyDeletecan i select one of item it not first page when i click i i want it become to first page
ReplyDeleteSorry, what do you mean?
DeleteBtw, I'm Vietnamese, so you just explain in Vietnamese if it's easier for you.
mƬnh muį»n hį»i nįŗæu mƬnh nhįŗ„n vĆ o mį»t page bįŗ„t kį»³ vĆ nĆ³ chuyį»n sang thĆ nh page giį»Æa thƬ lĆ m thįŗæ nĆ o? khi nĆ³ Äang lĆ page giį»Æa mƬnh muį»n hiį»n thƬ mį»t list icon į» bĆŖn dĘ°į»i nį»Æa :D
Deletebįŗ”n cĆ³ thį» cho mƬnh yahoo hoįŗ·c skype cį»§a bįŗ”n chį»© ?
Deleteok cįŗ£m Ę”n bįŗ”n mƬnh xong rį»i nhĆ© ^^
Deleteuh, sorry nhĆ©, dįŗ”o nĆ y bįŗn quĆ” ko cĆ³ time check blog :D
DeleteHi LeoLink,
ReplyDeleteThank your for your post, It's really useful.
I used it but my question is the value of page margin.
if i set it a minus value( for example -200) then in various resolutions it appears differently.
How can i set page margin to a right value?
Hi there, sorry for late reply!
DeleteAnd about your question, it should be like that because 200 in this case means 200px, it's a fixed value, but resolutions vary ?! That's why!
So the solution is you have to specify different margin values for different screen size. But how to do it exactly, you have to read this:
http://developer.android.com/guide/practices/screens_support.html
But in this case I GUESS you will have to deal with xml files, create same xml files with same name in different folders like res/values-xhdpi/dimens.xml, res/values-hdpi/dimens.xml... and specify same keys but with different values in those files...
Hope that helps ;)
Hi Leolink,
ReplyDeleteThank for this fabuluos code,
I need to know how to make the image in the center to be in TOP always.
just move your ViewPager to top by including this property "layout_gravity=top" to your ViewPager
DeleteHi great tutorial you have here..Im trying to add more than one carousel in the same page.is it possible?
ReplyDeleteYes, it is. Just add more ViewPagers then implement the same.
Deletehi, greate sample and clear tutorial. But i have a question. How can i set the first selection item in the left ? thanks
ReplyDeleteIn https://github.com/mrleolink/SimpleInfiniteCarousel/blob/master/src/net/leolink/android/simpleinfinitecarousel/MainActivity.java, change:
Deletepublic final static int FIRST_PAGE = PAGES * LOOPS / 2;
to
public final static int FIRST_PAGE = 0;
Hi, thanks for fast reply. But i want to ask again after i scrolled it the focus position is stay in the middle. Can i change it to the left position ? i already change the pages to 6 and loops to 1000
Deletewhat do you mean by "left position", you mean "left align"?
Deleteyeah, left position is the selected item is on the left not in the middle. how can i make it ?
Deletehmm, it's not simple as I can explain in a few lines of code, but basically, you need to remove this line:
Deletepager.setPageMargin(-200);
Then customize each fragment's layout (https://github.com/mrleolink/SimpleInfiniteCarousel/blob/master/res/layout/mf.xml) as left aligned.
i already find the solution :
Delete- add + 2 at FIRST_PAGE variable in MainActivity
- add -2 in if (position == MainActivity.FIRST_PAGE -2 ) in getItem method in MyPagerAdapter
Cool, Im glad you figured out it yourself, maybe I have misunderstood meaning :D
DeleteThis comment has been removed by the author.
ReplyDeleteHi LeoLink,
ReplyDeleteFirstly, I am thankful to you, great work. I am not getting the left side and right side images, i am getting only one center image.
Thx! Helped me a lot!
ReplyDeleteHello,
ReplyDeletehow can I add picture on pages?
Best regards,
Matej Klemen
Hi,
ReplyDeleteThanks so much, you saved my time.
I have only one question.
Have used pager.setPageMargin(-560); for 720 x 1280 in landscape orientation
but its giving me issues as this harcoded -560 is not working properly in other resolutions.
Could you please tell what would be the generic solution for this.
Waiting for your valuable response
560 in your pager.setPageMargin(-560); means 560PX, maybe you should use DP instead of PX, or calculate the page margin according to screen size?
Deletepager.setPageMargin(takes only value in PX) // so not point giving value in DP.
ReplyDeleteNot sure how shd I calculate page margin according to screen size.
dp -> px:
Deletepublic int dpToPx(int dp) {
DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
int px = Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
return px;
}
calculate screen size:
DisplayMetrics metrics=new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
float height=metrics.heightPixels/metrics.xdpi;
float width=metrics.widthPixels/metrics.ydpi;
Thanks for you work LeoLink, it works quite well.
ReplyDeleteHere's some code that'll help get the spaces between views consistent on all screen sizes and resolutions
DisplayMetrics dM = getResources().getDisplayMetrics();
int widthOfScreen = dM.widthPixels;
int widthOfView = 150; //in DP
int spaceBetweenViews = 20; // in DP
float offset = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, widthOfView+spaceBetweenViews, dM);
pager.setPageMargin((int) (-widthOfScreen+offset));
spacing changes with the device resolution :(
Deletethis code works perfectly, now space between pages are constant in all resolution.
DeleteAs @And Droid mentioned spacing changes with screen resolution with code suggested by kmg.
DeleteI could able to figure out general solution which fits all screen resolution. Here it is..
DisplayMetrics dM = getResources().getDisplayMetrics();
int widthOfScreen = dM.widthPixels;
int widthOfView = widthOfScreen/3; //for displaying maximum of three buttons, you can change this if you want more buttons
int spaceBetweenViews = 20; // in DP
float offset = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, widthOfView+spaceBetweenViews, dM);
//Calculate button width in mf.xml, which is 190 dp in pixels for the running device..
float scale = getBaseContext().getResources().getDisplayMetrics().density;
int px= (int) (190 * scale + 0.5f);
float pageMargin=widthOfScreen-offset;
//if pageMargin is less than button size make the page margin atleast to button size so that the previous,current and next buttons are displayed
if(pageMargin<px){
pageMargin=px;
}
pager.setPageMargin((int) (-pageMargin));
Hi,
ReplyDeleteThnks for code.
I have issues in your demo with fragment click,while I'd click on current item its Okay but in case of prev or next item click it will get current item click.
you mean when Fragment1 is being shown, and if you click on the portion of Fragment0 or Fragment2, only Fragment1 get onClick event?
DeleteHi,Thanks for reply
DeleteI am sry I mean when I click on both corners of fragment1 it will sometime get the click events of fragment0 & fragment2.
Now I change the Widht of fragments and also change the pagemargins as per my requirements
So is it the reason?
um, so I'm not sure then, but I'm curious why do you want to get onClick event when click on Fragment0 & Fragment2 while Fragment1 is being selected?
DeleteBecause of when you click on Fragment0(or Fragment2) while Fragment1 is being selected, the you will get Fragment0(or Fragment2) selected, so you may use ViewPager's events instead of onClick event, just my thought..
Hi, can you please make a sample of your carousel with sample images instead? Thank you so much, I really appreciate it.
ReplyDeleteYou just need to add an ImageView to the layout file of the Fragment, then set image for it based on position of the containing Fragment.
DeleteHi, This tutorial helped me a lot and i have successfully implemented this on one of my applications. Every thing goes well but i have one small question on this.
ReplyDeleteQ: Suppose when the user tap/click on any item, i have changed the selected item background with new image. But when i scroll the all items the selected item image is gone. Can you please tell me, is there any way to hold the selected item background as long as scroll does?
to achieve that, you have to change your adapter's data whenever an item gets clicked, then use adapter's notifyDataSetChanged() to apply the change on your ViewPager, dont change the clicked item's background directly when it's clicked.
DeleteHey, Thank you for your quick reply.
DeleteThis comment has been removed by the author.
ReplyDeleteHi, Thanks for this awesome Post! But I have a question. I would like to keep previous and next page item behind of current page selected. Currently I can do only the previous. Can you help me on that?
ReplyDeleteSorry I dont get what you mean, how about some pictures to express your idea?
DeleteMy question is to have pagers like that:
Deletehttp://i.stack.imgur.com/k9R4w.png
ohh, it isn't simple as it looks, you might try setPageMargin as a very big native value like setPageMargin(-300), but I'm not sure...
Deletepersonally, I think you will have to customize pretty much to achieve it, it looks like a cover flow, I tried to implement it by ViewPager before but it couldn't make it, but if you don't mind Gallery class which has become deprecated since API 16, you can give it a try.
Hi! Thank u so much for this gr8 tutorial. But I am facing some problems. I have used your viewpager in my fragment. If I go in my same fragment in 1st attempt carousel looks properly, but if I go in my another fragment and go back again on same fragment then carousel images are not shown and one more thing I observed in this scenario is after scrolling sometimes images will start showing. I tried hard to fix this issue but not able to resolved yet. Can you please give me any guidance on the same issue.
ReplyDeletemaybe you should try "setWillNotDraw(false)" in MyLinearLayout's constructors, or call MyLinearLayout's "invalidate()" in "onPageSelected" of the adapter.
DeleteThank u so much for such a quick reply. I tried both ways, but unfortunately not able to solve my issue. Is my problem coming because i have added carousel fragment within my fragment & during fragment switching time carousel images are not displaying, as i have multiple fragments in my project? Also i didn't understand why this images starts looking after few scrolling done.
DeleteMy another observation is viewpager layout looks properly in my scenario. But linear layout which holds carousel view is not at all displaying. I checked this by adding bg color in my both viewpager & carousel linear layout. Also first image which i seen after scrolling some time is changed as per setOffscreenPageLimit value accordingly. Kindly help if u got any idea.
DeleteAlso call is not going in onDraw(Canvas canvas) method of custom layout.
ReplyDeleteIs it possible to implement arch shaped carousel using this method
ReplyDeleteHello LeoLink, and very thanks for your tutorial. I would like to implement a function that allows change a variable (x) depending on the biggest image.
ReplyDeleteFor example: If image 1 is the biggest, x=34 and if image 2 is the biggest, x=89.
How could I do it?
Hello LeoLink, I've just tried your tutorial. But It just shows only one current page. The previous and the next page don't show up. Could you fix it? I don't change anything in your sample. I tested on Asus and LG phone.
ReplyDeletehi, this is not carousel effect at all because in carousel visible view comes always top and other left and right views are always backside of the main visible view.
ReplyDeleteyou can check this link for iOS and then you can understand my point of view that what i am saying about this tutorial.
http://www.theappguruz.com/tutorial/how-to-use-icarousel-view-controller-in-ios/
thanks to take note about this and if you find right answer please share with me because i am trying to develop open source library about viewpager animation layout in different ways and this is most important for me, so please share with me.
thanks
rahul mandaliya
(SkyPe: rahulmandaliya)
thank you..i will study ..i was stuck on this .
ReplyDeleteHey, I know this is really old, but how can I achieve that the active (middle) fragment is in front of the others?
ReplyDeleteThanks a lot!
Hi! I have a problem, I'm trying using your code but my aplication does not show the left and right element I onlycan see the center element, what's happening?
ReplyDeleteHey! For all of you having trouble with the center element not being the top most one: You can fix that by invoking View#bringToFront() on the main view within the current fragment. I improved this a bit by invoking bringToFront on the current fragment's view within onPageScrolled whenever positionOffset is < 0.5f and on the next fragment's view whenever positionOffset >= 0.5f.
ReplyDeleteFor those not seeing the elements to the left and the right: Be sure that your child fragments don't occupy the whole screen width, and if they do, that the area in which the side elements should be visible has a transparent background.
Thanks a lot, I tried bringToFront() before but couldn't get it to work. But doing like you suggested works!
DeleteThis comment has been removed by the author.
Deletehow i can implement this in titanium,appcelerator studio for android????
ReplyDeleteHi is possible to implemented a dynamic carousel so that i can add item and delete?
ReplyDeleteThx :)
Hi Mr.Leo Link
ReplyDeleteI use this example to let the viewpager be aother viewpager's tab,
it work but i have some problem,i need to let current view's text to change color, but i don't no how to do,please tell me how to do it.