There are number of libraries available to create circular indicator for view pager. But i think you don't require that all heavy weight libraries. They all filled with so much congested and non used code in it. It may happen you may come across some odd issue with those libs. So to save your time and even with easy to understand code i have written this tutorial. Go through full tutorial and you find how easy it is.
I have created View pager for introduction of the application (Current trend of application start screen almost in all Google apps). But you can use it as per your requirement.
Steps
Step -1
Create activity (welcome screen) which holds pager to display images and give proper name to it. In this tutorial it is ViewPagerDemo Activity. now put below code inside into xml file (layout file).
activity_viewpager_demo.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:context="com.androprogrammer.tutorials.samples.ViewPagerDemo"> <android.support.v4.view.ViewPager android:id="@+id/pager_introduction" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:listitem="@layout/pager_item" /> <RelativeLayout android:id="@+id/viewPagerIndicator" android:layout_width="match_parent" android:layout_height="55dp" android:layout_alignParentBottom="true" android:layout_marginTop="5dp" android:gravity="center"> <LinearLayout android:id="@+id/viewPagerCountDots" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerHorizontal="true" android:gravity="center" android:orientation="horizontal" /> <ImageButton android:id="@+id/btn_next" android:layout_width="42dip" android:layout_height="42dip" android:layout_alignParentRight="true" android:layout_marginRight="15dip" android:background="@drawable/btn_round_semitransperant" android:src="@mipmap/ic_navigation_arrow_forward" /> <ImageButton android:id="@+id/btn_finish" android:layout_width="42dip" android:layout_height="42dip" android:layout_alignParentRight="true" android:layout_marginRight="15dip" android:background="@drawable/btn_round_semitransperant" android:contentDescription="Let's start" android:src="@mipmap/ic_navigation_check" android:visibility="gone" /> </RelativeLayout> </RelativeLayout>
Step - 2
Above code will show error but don't worry it is for drawable files. so below are drawable files put the code in appropriate file and your layout is set.
pager_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:fitsSystemWindows="true" android:layout_height="match_parent"> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" tools:src="@mipmap/abc1" android:id="@+id/img_pager_item" android:scaleType="fitXY" android:adjustViewBounds="true" android:clickable="false"/> </LinearLayout>
drawable/selecteditem_dot.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" android:useLevel="true" android:dither="true"> <size android:height="12dip" android:width="12dip"/> <solid android:color="@color/primary"/> </shape>
drawable/nonselecteditem_dot.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" android:useLevel="true" android:dither="true"> <size android:height="6dip" android:width="6dip"/> <solid android:color="@color/activity_bg"/> </shape>
Step - 3
For View pager, layout part is done. you can find sample images from here. now let's move to code part where i have created circular dots on the basis of data size. So if you have let say 10 images it will create 10 dots with first one as selected by default. put the code in to activity and make changes as per your project implementation.
ViewPagerDemo.java
package com.androprogrammer.tutorials.samples; import android.os.Bundle; import android.support.v4.view.ViewPager; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.view.Window; import android.view.WindowManager; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; import com.androprogrammer.tutorials.R; import com.androprogrammer.tutorials.activities.Baseactivity; import com.androprogrammer.tutorials.adapters.ViewPagerAdapter; public class ViewPagerDemo extends Baseactivity implements ViewPager.OnPageChangeListener, View.OnClickListener{ protected View view; private ImageButton btnNext, btnFinish; private ViewPager intro_images; private LinearLayout pager_indicator; private int dotsCount; private ImageView[] dots; private ViewPagerAdapter mAdapter; private int[] mImageResources = { R.mipmap.abc1, R.mipmap.abc2, R.mipmap.abc3, R.mipmap.abc4, R.mipmap.abc5 }; @Override protected void onCreate(Bundle savedInstanceState) { // To make activity full screen. requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); super.onCreate(savedInstanceState); setReference(); toolbar.setVisibility(View.GONE); } @Override public void setReference() { view = LayoutInflater.from(this).inflate(R.layout.activity_viewpager_demo,container); intro_images = (ViewPager) view.findViewById(R.id.pager_introduction); btnNext = (ImageButton) view.findViewById(R.id.btn_next); btnFinish = (ImageButton) view.findViewById(R.id.btn_finish); pager_indicator = (LinearLayout) view.findViewById(R.id.viewPagerCountDots); btnNext.setOnClickListener(this); btnFinish.setOnClickListener(this); mAdapter = new ViewPagerAdapter(ViewPagerDemo.this, mImageResources); intro_images.setAdapter(mAdapter); intro_images.setCurrentItem(0); intro_images.setOnPageChangeListener(this); setUiPageViewController(); } private void setUiPageViewController() { dotsCount = mAdapter.getCount(); dots = new ImageView[dotsCount]; for (int i = 0; i < dotsCount; i++) { dots[i] = new ImageView(this); dots[i].setImageDrawable(getResources().getDrawable(R.drawable.nonselecteditem_dot)); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT ); params.setMargins(4, 0, 4, 0); pager_indicator.addView(dots[i], params); } dots[0].setImageDrawable(getResources().getDrawable(R.drawable.selecteditem_dot)); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_next: intro_images.setCurrentItem((intro_images.getCurrentItem() < dotsCount) ? intro_images.getCurrentItem() + 1 : 0); break; case R.id.btn_finish: finish(); break; } } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { for (int i = 0; i < dotsCount; i++) { dots[i].setImageDrawable(getResources().getDrawable(R.drawable.nonselecteditem_dot)); } dots[position].setImageDrawable(getResources().getDrawable(R.drawable.selecteditem_dot)); if (position + 1 == dotsCount) { btnNext.setVisibility(View.GONE); btnFinish.setVisibility(View.VISIBLE); } else { btnNext.setVisibility(View.VISIBLE); btnFinish.setVisibility(View.GONE); } } @Override public void onPageScrollStateChanged(int state) { } }
This is code for view pager adapter.which fills all images into view pager and display like gallery.
adapters/ViewPagerAdapter.java
package com.androprogrammer.tutorials.adapters; import android.content.Context; import android.support.v4.view.PagerAdapter; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; import com.androprogrammer.tutorials.R; /** * Created by Wasim on 11-06-2015. */ public class ViewPagerAdapter extends PagerAdapter { private Context mContext; private int[] mResources; public ViewPagerAdapter(Context mContext, int[] mResources) { this.mContext = mContext; this.mResources = mResources; } @Override public int getCount() { return mResources.length; } @Override public boolean isViewFromObject(View view, Object object) { return view == ((LinearLayout) object); } @Override public Object instantiateItem(ViewGroup container, int position) { View itemView = LayoutInflater.from(mContext).inflate(R.layout.pager_item, container, false); ImageView imageView = (ImageView) itemView.findViewById(R.id.img_pager_item); imageView.setImageResource(mResources[position]); container.addView(itemView); return itemView; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((LinearLayout) object); } }
That's it from my side. now run the app and see the result. and at the end i am replacing next button with finish button. if you have any query please let me know in below comment box.
Keep coding...
Source code
Great article, thank you for sharing. I have one question, how would you structure the activity flow for first launch.
ReplyDeleteWould you set the WelcomeActivity as the launch activity in the manifest file and call launch the MainActivity if the this was already displayed.
Or would you keep the MainActivity as the launch activity and call the WelcomeActivity from the MainActivity if it is the first load.
Regards,
Thanks Garfield,
DeleteYes i set welcome screen as launcher activity then when user click on finish i redirect them to main activity.
and for second time i put one boolean in preference and one the basis of that next time i skip activity.
if user have already seen welcome screen then directly redirect them to main activity.
I hope it will be clear to you.
Thank you confirms the idea i had in mind. Do check the preference and call finish() before setContentView to prevent the loading of that that activity (or flash of the screen)?
DeleteThank you
Yes that's correct.
DeleteAwesome, thank you. I will let you know how it goes.
DeleteYa sure,
DeleteI glad to know.
Got it to work :)
ReplyDeleteI had to do a few simple things:
1. Add "setContentView(R.layout. activity_viewpager_demo);" in activity.
2. Use alternatives for the next and finish button background and source properties.
Again, thank you for awesome tutorial.
That's good tutorial, thank you for sharing. But I dont know, what is that Baseactivity ? Please help me, thanks
ReplyDeleteThank you bayu,
DeleteBase activity is my projects main activity where I have implemented some common functions and toolbar implementation. You can find it on github project repo.
What is container in ViewPagerDemo.java
ReplyDeleteview = LayoutInflater.from(this).inflate(R.layout.activity_main, container);
it gives me error
Hey nasir ,
DeleteCheck my project on github it will help you in understanding project structure. B'z container is part of it.
Where can i find it on git ?
ReplyDeletehttps://github.com/WasimMemon/Myapplications/blob/master/Tutorials/app/src/main/java/com/androprogrammer/tutorials/samples/ViewPagerDemo.java
DeleteCheck this out.
Thank you
DeleteThankyou Wasim memon
ReplyDeleteThanks Wasim, it was really helpful! Although setOnPageChangedListener is deprecated I used addPageChangedListener instead
ReplyDeletewhwre is the exact location of container error i will get to resolve plzz tell me wasim
ReplyDeleteCheck my project on github it will help you in understanding project structure. B'z container is part of it.
Deletehttps://github.com/WasimMemon/Myapplications/tree/master/Tutorials
hi,
ReplyDeletein your example, at time only one view is loaded? i mean in circlepageindicatory library, i saw at a time two views are loaded in memory
Hi Deepika,
DeleteAs you can see i have used view pager and it loads 1 view default at a time of initialization so i think it works same in this also. You can use ViewPager.setOffscreenPageLimit(1) to change if you want.
why do you create Baseactivity ?
ReplyDeleteIts my whole project setup for combining all tutorials in one app.
DeleteWhy you have problem with it ?
I don't understand what is "container". plz tell me how can i find it ??
ReplyDeleteYou can get full code from github and can see how it works and why it is used.
DeleteI am getting the linearLayout but dots are not visible, why?
ReplyDeleteHi, seems awesome stuff! but I can please get a stuff to supply this code line android:background="@drawable/btn_round_semitransperant"
ReplyDeleteRegards,
Gus
is Container a fragment ?? I didn't find it on github link
ReplyDeleteawesome tutorial, thank you
ReplyDeleteReally useful article. Thanks for sharing.
ReplyDeleteHello great tutorial, one question It works witn any SDK or in what version of sdk works?
ReplyDeletePlease check my full project on github.
Deletethank you
ReplyDelete