English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Drawing Cool Guide Interface in Android

First, let's take a look at the interface we are going to develop (three images, when you slide to the last one, a 'Start Experience' button will appear, and the small red dot below will follow the sliding):


First, let's take a look at the layout file:

 <?xml version="1.0" encoding="utf-8"?>
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:id="@"+id/activity_guide"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context="com.coderwei.a71_zhbj.activity.GuideActivity">
   <android.support.v4.view.ViewPager
     android:id="@"+id/vp_guide"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     />
   <Button
     android:layout_centerHorizontal="true"
    android:layout_alignParentBottom="true"
    android:layout_marginBottom="70dp"
    android:padding="10dp"
    android:id="@"+id/start_btn"
    android:textColor="#f1eaea"
   android:background="#e71616"
   android:text="Start Experience"
   android:visibility="invisible"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content" />
  <RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
    android:layout_marginBottom="30dp">
   <LinearLayout
     android:id="@"+id/ll_container"
     android:layout_width="wrap_content"
    android:layout_height="wrap_content">
   </LinearLayout>
  <ImageView
    android:id="@"+id/iv_red"
   android:src="@drawable/shap_red"
   android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
 </RelativeLayout>
 </RelativeLayout>

Then it's the code:

public class GuideActivity extends Activity {
   private ViewPager mViewPager;
   private int[] mImageIds = new int[]{R.drawable.guide_1,R.drawable.guide_2,R.drawable.guide_3};
   private ArrayList<ImageView> mImageViewList;
   private LinearLayout llContainer;
   private ImageView ivRedPoint;
   private int mPaintDis;
   private Button start_btn;
  @Override
 protected void onCreate(Bundle savedInstanceState) {
   uper.onCreate(savedInstanceState);
   requestWindowFeature(Window.FEATURE_NO_TITLE);
   setContentView(R.layout.activity_guide);
   mViewPager = (ViewPager)findViewById(R.id.vp_guide);
   llContainer = (LinearLayout) findViewById(R.id.ll_container);
   ivRedPoint = (ImageView) findViewById(R.id.iv_red);
   start_btn = (Button) findViewById(R.id.start_btn);
   initData();
   GuideAdapter adapter = new GuideAdapter();
   mViewPager.setAdapter(adapter);
   //Listen for whether the layout has been completed and whether the position of the layout has been determined
    ivRedPoint.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
      @Override
      public void onGlobalLayout() {
       //Avoid repeated callback    Considering compatibility, the outdated method has been used
        ivRedPoint.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        //After the layout is completed, get the distance between the first small gray point and the second one's left margin
        mPaintDis =  llContainer.getChildAt(1).getLeft()-llContainer.getChildAt(0).getLeft();
        System.out.println("Distance:");+mPaintDis);
      }
   });
  //ViewPager sliding Pager listener
  mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
     //Callback during scrolling
     @Override
     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
     //When sliding to the second Pager, the positionOffset percentage will become 0, and position will become1Therefore, position needs to be added later*mPaintDis
     int letfMargin = (int)(mPaintDis*positionOffset)+position*mPaintDis;
     //Set the left margin of the control in the parent layout
      RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)ivRedPoint.getLayoutParams();
     params.leftMargin = letfMargin;
     ivRedPoint.setLayoutParams(params);
     }
     @Override
      public void onPageSelected(int position) {
        System.out.println("position:");+position);
        if (position == mImageViewList.size())-1{
         start_btn.setVisibility(View.VISIBLE);
       }
     }
     @Override
      public void onPageScrollStateChanged(int state) {
       System.out.println("state:");+state);
      }
    });
  }
  private void initData(){
    mImageViewList = new ArrayList<>();
    for (int i=0; i<mImageIds.length; i++{
      //Create ImageView and put mImgaeViewIds in it
      ImageView view = new ImageView(this);
      view.setBackgroundResource(mImageIds[i]);
      //Add to the ImageView collection
      mImageViewList.add(view);
     //Small circle A small gray dot is an ImageView
     ImageView pointView = new ImageView(this);
      pointView.setImageResource(R.drawable.shape);
      //Initialize layout parameters, initialize the layout parameters of the parent control, initialize whose layout parameters
     LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
     if (i>0){
       //When the number of small circles added exceeds one, set the left margin of the current small circle to10dp;
        params.leftMargin=10;
      }
     //Set the width and height of the small gray dot to wrap the content
      pointView.setLayoutParams(params);
      //Add the small gray dot to the LinearLayout
      llContainer.addView(pointView);
    }
   }
 class GuideAdapter extends PagerAdapter{
    //Number of items
    @Override
    public int getCount() {
       return mImageViewList.size();
    }
    @Override
     public boolean isViewFromObject(View view, Object object) {
       return view == object;
    }
    //Initialize item layout
     @Override
     public Object instantiateItem(ViewGroup container, int position) {
       ImageView view = mImageViewList.get(position);
      container.addView(view);
      return view;
    }
    //Destroy item
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
      container.removeView((View)object);
    }
  }
 } 

Small gray dot:

<?xml version="1.0" encoding="utf-8"?>
<shape
   android:shape="oval"
   xmlns:android="http://schemas.android.com/apk/res/android">
   <!--Small gray dot-->
   <solid android:color="#cccccc"/>
   <size android:width="10dp" android:height="10dp"/>
</shape>

Red dot:

<?xml version="1.0" encoding="utf-8"?>
 <shape
   android:shape="oval"
   xmlns:android="http://schemas.android.com/apk/res/android">
   <solid android:color="#f00"/>
   <size android:width="10dp" android:height="10dp"/>
 </shape>

ViewPage is very simple, which has been introduced in detail in the previous post, so there is no need to elaborate here, mainly the small red dot moves with the Pager.

There are actually three small gray dots above, and then there is a small red dot above the small gray dots. By calculating the distance between the first small gray dot and the second small gray dot, we can set the ViewPager's sliding listener and let the red dot move with the pager (the padding of the parent control changes).

When calculating the distance between the small gray dots, it is important to wait until the layout position is determined before you can get the distance between the small gray dots (the process of generating the interface is measure->layout(determine position)->draw(the process after the activity's onCreate method is executed)),so you need to set the layout listener:

ivRedPoint.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()

Then, calculate the distance between the small gray dots:

mPaintDis =1).getLeft()-llContainer.getChildAt(0).getLeft();

It should be noted that this piece of code is:
int letfMargin = (int)(mPaintDis*positionOffset)+position*mPaintDis;

positionOffset is the current sliding percentage. When entering the second page, the value is 0,
position represents the current page number, starting from 0, which means when I slide to the second page, mPaintDis*0+1*mPaintDis;

PS: Summary of ideas:

  1The page is composed of ViewPager + Button + RelativeLayout(LinearLayout + composed of TextViews,
  2LinearLayout contains the gray dots, and the number of gray dots is determined by the number of ViewPager items. Therefore, when adding gray dots to LinearLayout, it is done at the same time as adding image resources to the ViewPager collection.
  3Then the red dot is a TextView, and due to the relative layout, the initial position of the red dot will coincide with the first point of the gray dot.
  4Then listen to the ViewPager's sliding event, and move the red dot's position by calculating the margin difference between the left of the first and second gray dots to the left of the LinearLayout. However, the determination of the position must be that the layout position has been determined, so we need to listen to whether the layout has been determined, and then calculate the position difference after it is determined.

That's all for this article. I hope it will be helpful to everyone's learning and that everyone will support the Yelling Tutorial more.

Declaration: The content of this article is from the Internet, and the copyright belongs to the original author. The content is contributed and uploaded by Internet users spontaneously. This website does not own the copyright, has not been manually edited, and does not assume any relevant legal liability. If you find any content suspected of copyright infringement, please send an email to notice#w3Please send an email to codebox.com (replace # with @ when sending an email) to report any violations, and provide relevant evidence. Once verified, this site will immediately delete the content suspected of infringement.

You May Also Like