1. 程式人生 > >一個簡單的Android引導介面

一個簡單的Android引導介面

先看一下我們要開發的介面(三張圖片,滑到最後一個會出現開始體驗的Button,下面的小紅點會跟著一起滑動):


首先看一下佈局檔案:

複製程式碼
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:tools="http://schemas.android.com/tools"
 4     android:id="@+id/activity_guide"
 5     android:layout_width
="match_parent" 6 android:layout_height="match_parent" 7 tools:context="com.coderwei.a71_zhbj.activity.GuideActivity"> 8 9 <android.support.v4.view.ViewPager 10 android:id="@+id/vp_guide" 11 android:layout_width="match_parent" 12 android:layout_height="match_parent"
13 /> 14 <Button 15 android:layout_centerHorizontal="true" 16 android:layout_alignParentBottom="true" 17 android:layout_marginBottom="70dp" 18 android:padding="10dp" 19 android:id="@+id/start_btn" 20 android:textColor="#f1eaea" 21 android:background
="#e71616" 22 android:text="開始體驗" 23 android:visibility="invisible" 24 android:layout_width="wrap_content" 25 android:layout_height="wrap_content" /> 26 27 <RelativeLayout 28 android:layout_width="wrap_content" 29 android:layout_height="wrap_content" 30 android:layout_alignParentBottom="true" 31 android:layout_centerHorizontal="true" 32 android:layout_marginBottom="30dp"> 33 34 <LinearLayout 35 android:id="@+id/ll_container" 36 android:layout_width="wrap_content" 37 android:layout_height="wrap_content"> 38 39 </LinearLayout> 40 <ImageView 41 android:id="@+id/iv_red" 42 android:src="@drawable/shap_red" 43 android:layout_width="wrap_content" 44 android:layout_height="wrap_content" /> 45 46 </RelativeLayout> 47 48 </RelativeLayout>
複製程式碼

然後就是程式碼了:

複製程式碼
  1 public class GuideActivity extends Activity {
  2 
  3     private ViewPager mViewPager;
  4     private int[] mImageIds = new int[]{R.drawable.guide_1,R.drawable.guide_2,R.drawable.guide_3};
  5     private ArrayList<ImageView> mImageViewList;
  6     private LinearLayout llContainer;
  7     private ImageView ivRedPoint;
  8     private int mPaintDis;
  9     private Button start_btn;
 10 
 11     @Override
 12     protected void onCreate(Bundle savedInstanceState) {
 13         super.onCreate(savedInstanceState);
 14         requestWindowFeature(Window.FEATURE_NO_TITLE);
 15         setContentView(R.layout.activity_guide);
 16         mViewPager = (ViewPager)findViewById(R.id.vp_guide);
 17         llContainer = (LinearLayout) findViewById(R.id.ll_container);
 18         ivRedPoint = (ImageView) findViewById(R.id.iv_red);
 19         start_btn = (Button) findViewById(R.id.start_btn);
 20         initData();
 21         GuideAdapter adapter = new GuideAdapter();
 22         mViewPager.setAdapter(adapter);
 23 
 24         //監聽佈局是否已經完成  佈局的位置是否已經確定
 25         ivRedPoint.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
 26             @Override
 27             public void onGlobalLayout() {
 28                 //避免重複回撥        出於相容性考慮,使用了過時的方法
 29                 ivRedPoint.getViewTreeObserver().removeGlobalOnLayoutListener(this);
 30                 //佈局完成了就獲取第一個小灰點和第二個之間left的距離
 31                 mPaintDis =   llContainer.getChildAt(1).getLeft()-llContainer.getChildAt(0).getLeft();
 32                 System.out.println("距離:"+mPaintDis);
 33             }
 34         });
 35 
 36 
 37         //ViewPager滑動Pager監聽
 38         mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
 39             //滑動過程中的回撥
 40             @Override
 41             public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
 42                 //當滑到第二個Pager的時候,positionOffset百分比會變成0,position會變成1,所以後面要加上position*mPaintDis
 43                 int letfMargin = (int)(mPaintDis*positionOffset)+position*mPaintDis;
 44                 //在父佈局控制元件中設定他的leftMargin邊距
 45                 RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)ivRedPoint.getLayoutParams();
 46                 params.leftMargin = letfMargin;
 47                 ivRedPoint.setLayoutParams(params);
 48             }
 49 
 50 
 51             @Override
 52             public void onPageSelected(int position) {
 53                 System.out.println("position:"+position);
 54                 if (position==mImageViewList.size()-1){
 55                     start_btn.setVisibility(View.VISIBLE);
 56                 }
 57 
 58             }
 59 
 60             @Override
 61             public void onPageScrollStateChanged(int state) {
 62                 System.out.println("state:"+state);
 63             }
 64         });
 65     }
 66 
 67     private void initData(){
 68         mImageViewList = new ArrayList<>();
 69         for (int i=0; i<mImageIds.length; i++){
 70             //建立ImageView把mImgaeViewIds放進去
 71             ImageView view = new ImageView(this);
 72             view.setBackgroundResource(mImageIds[i]);
 73             //新增到ImageView的集合中
 74             mImageViewList.add(view);
 75 
 76 
 77             //小圓點    一個小灰點是一個ImageView
 78             ImageView pointView = new ImageView(this);
 79             pointView.setImageResource(R.drawable.shape);
 80             //初始化佈局引數,父控制元件是誰,就初始化誰的佈局引數
 81             LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
 82             if (i>0){
 83                 //當新增的小圓點的個數超過一個的時候就設定當前小圓點的左邊距為10dp;
 84                 params.leftMargin=10;
 85             }
 86             //設定小灰點的寬高包裹內容
 87             pointView.setLayoutParams(params);
 88             //將小灰點新增到LinearLayout中
 89             llContainer.addView(pointView);
 90         }
 91     }
 92 
 93 
 94     class GuideAdapter extends PagerAdapter{
 95 
 96         //item的個數
 97         @Override
 98         public int getCount() {
 99             return mImageViewList.size();
100         }
101 
102         @Override
103         public boolean isViewFromObject(View view, Object object) {
104             return view == object;
105         }
106 
107         //初始化item佈局
108         @Override
109         public Object instantiateItem(ViewGroup container, int position) {
110             ImageView view = mImageViewList.get(position);
111             container.addView(view);
112             return view;
113         }
114 
115         //銷燬item
116         @Override
117         public void destroyItem(ViewGroup container, int position, Object object) {
118             container.removeView((View)object);
119         }
120     }
121 }
複製程式碼

小灰點:

複製程式碼
1 <?xml version="1.0" encoding="utf-8"?>
2 <shape
3     android:shape="oval"
4     xmlns:android="http://schemas.android.com/apk/res/android">
5     <!--小灰點-->
6     <solid android:color="#cccccc"/>
7     <size android:width="10dp" android:height="10dp"/>
8 
9 </shape>
複製程式碼

小紅點:

複製程式碼
1 <?xml version="1.0" encoding="utf-8"?>
2 <shape
3     android:shape="oval"
4     xmlns:android="http://schemas.android.com/apk/res/android">
5 
6     <solid android:color="#f00"/>
7     <size android:width="10dp" android:height="10dp"/>
8 </shape>
複製程式碼

ViewPage都很簡單,上一個博文也詳細介紹了的,這裡就不細說了,主要是下面的小紅點跟著Pager一起走。

上面其實是三個小灰點,然後小灰點的上面有一個小紅點,通過計算出第一個小灰點與第二個小灰點之間的距離,我們就可以用設定ViewPager的滑動監聽,然後讓小紅點跟著pager一起動(改變的是父控制元件中的內邊距)。

計算小灰點之間的距離時需要注意的是,必須等到佈局位置確定下來的才能的到小灰點之間的距離(介面生成的過程 measure->layout(確定位置)->draw(activity的onCreate方法執行結束之後才會走此流程)),所以要設定layout的監聽:

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

然後的到小灰點之間的距離:
mPaintDis =   llContainer.getChildAt(1).getLeft()-llContainer.getChildAt(0).getLeft();

需要注意的是這句程式碼:
int letfMargin = (int)(mPaintDis*positionOffset)+position*mPaintDis;
positionOffset是當前滑動的百分比,當進入第二個page的時候,值為0,
position代表當前是第幾個page,從0開始,也就是說當我滑到第二個page的時候 mPaintDis*0+1*mPaintDis;

PS:思路總結:

  1、頁面由 ViewPager + Button + RelativeLayout(LinearLayout + TextView)組成,
  2、LinearLayout放的是小灰點,小灰點的個數由ViewPager的個數覺得,所以LinearLayout新增小灰點的時候是與VIewPager的圖片資源新增到集合是一起的。
  3、然後小紅點就是一個TextView因為相對佈局的原因,小紅點的初始位置會和小灰點的第一個點重合,
  4、然後監聽ViewPager的滑動事件,通過計算第一個和第二個小灰點的左邊到LinearLayout的左邊的邊距差,來移動小紅點的位置,但是確定位置的查體須  是佈局的位置已經確定,所以我們就要監聽佈局是否已經確定,等確定後再去計算位置差。