編輯:關於Android編程
我們來講個老生常談的話題,估計大家都用過的—>ViewPager,用它來做新手導航頁面,雖然這次也是講這個,但是和以往的用法可能有些不同,大家都看到標題進來的,應該知道的是:動態加載指示器。
什麼叫動態加載呢,是不是感覺很高大上呢,其實呢就是動態的去加載指示器的數量的,而不是在布局文件中寫死。希望看了這篇文章大家對ViewPager有新的認識。

看到這個效果大家應該都很不屑吧,今天講這個就是為了讓大家有新的認識。好了,好好聽,開始了。
這個動態加載就是為了動態的加載下面的灰色圓點指示器和紅色圓點指示器,大家有沒有注意到當我滑動的時候(即切換頁面的時候)紅色圓點會跟著移動。沒錯。
第一步:
在布局文件中添加ViewPager,並添加灰色圓點和紅色圓點的布局,先來想想都用什麼布局呢,首先三個灰色圓點可以用線性布局,一個紅色圓點可以采用相對布局(原因:其實紅色圓點就是覆蓋在灰色圓點上)
<RelativeLayout
android:id="@+id/rl"
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"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</LinearLayout>
</RelativeLayout>
第二步:
在onCreate方法中聲明ViewPager和灰色圓點和紅色圓點布局的示例(原因:因為我們需要動態加載圓點),並為ViewPager添加適配器和監聽器。
//ViwePager
private ViewPager viewPager;
//存放三個灰色圓點的線性布局
private LinearLayout ll;
//用來存放紅色圓點和灰色圓點的相對布局
private RelativeLayout rl;
//初始化組件
private void initView() {
viewPager = (ViewPager) findViewById(R.id.viewPager);
imageViews = new ArrayList<ImageView>();
ll = (LinearLayout) findViewById(R.id.ll);
rl = (RelativeLayout) findViewById(R.id.rl);
btn = (Button) findViewById(R.id.btn);
//為ViewPager添加適配器
viewPager.setAdapter(new MyAdapter());
viewPager.setOnPageChangeListener();
第三步:
將三個圖片加到ViewPager的適配器中。
注:為了在滑動的時候不重復創建圖片實例,所以我們可以先將需要加載的資源的放在一個集合中,當每次滑動需要加載的時候就從集合中取出即可,這樣節省了系統資源。
//導航頁資源
private int[] images = new int[]{
R.drawable.guide_1,
R.drawable.guide_2,
R.drawable.guide_3,
};
//用來存放導航圖片實例(保證唯一性,滑動的時候不重復創建)
private List<ImageView> imageViews;
//初始化導航頁面
for (int i = 0; i < images.length; i++) {
ImageView iv = new ImageView(MainActivity.this);
iv.setImageResource(images[i]);
imageViews.add(iv);
}
//PagerAdapter有四個方法
class MyAdapter extends PagerAdapter {
//返回導航頁的個數
@Override
public int getCount() {
return images.length;
}
//判斷是否由對象生成
@Override
public boolean isViewFromObject(View view,Object object) {
return view == object;
}
//加載頁面
//ViewGroup:父控件指ViewPager
//position:當前子控件在父控件中的位置
@Override
public Object instantiateItem(ViewGroup container, int position) {
ImageView iv = imageViews.get(position);
container.addView(iv);
return iv;
}
//移除頁面
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
第四步:
重要的部分來了,這一步是動態的將灰色圓點和紅色圓點添加進來,並讓紅色圓點隨著滑動也跟著一起滑動。
首先動態的添加灰色圓點和紅色圓點:
for (int i = 0; i < images.length; i++) {
ImageView iv = new ImageView(MainActivity.this);
iv.setImageResource(images[i]);
imageViews.add(iv);
//動態加載灰色圓點
ImageView gray_Iv = new ImageView(this);
gray_Iv.setImageResource(R.drawable.grar_circle);
LinearLayout.LayoutParams layoutParams =
new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
//從第二個開始有邊距
if (i > 0) {
layoutParams.leftMargin = 20; //注意單位是px
}
gray_Iv.setLayoutParams(layoutParams);
ll.addView(gray_Iv);
}
//添加紅色圓點
red_Iv = new ImageView(this);
red_Iv.setImageResource(R.drawable.red_circle);
rl.addView(red_Iv);
注:灰色圓點是從第二個開始有左邊距的,為組件動態的設置邊距的話使用布局的LayoutParams(衣服),記住三個灰色圓點使用的是哪個布局就采用那種布局的LayoutParams來進行設置。
下面就是讓紅色圓點隨著ViewPager滑動也跟著一起滑動:
//任何一個組件都可以得到視圖樹
red_Iv.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
//視圖完成繪制的時候調用
@Override
public void onGlobalLayout() {
left = ll.getChildAt(1).getLeft() - ll.getChildAt(0).getLeft();
System.out.println(left);
//移除視圖樹的監聽
red_Iv.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
//導航頁滑動的時候調用
//positionOffset:滑動的百分比([0,1})
@Override
public void onPageScrolled(int position, float positionOffset, int arg2) {
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) red_Iv.getLayoutParams();
layoutParams.leftMargin = (int) (left * positionOffset + position * left);
red_Iv.setLayoutParams(layoutParams);
}
注:這裡需要明白一個概念–>視圖樹,為什麼要明白這個呢,因為我們是動態的將灰色圓點添加進去,不知道這個視圖什麼才能繪制好,所以需要監聽到整個視圖的繪制狀態,任何一個組件都可以拿到視圖樹,對視圖樹的繪制進行監聽。這樣就可以得到灰色圓點之間的距離,大家又會問一開始添加灰色圓點的時候不是設置了左邊距嗎???是的,但是這個單位是px,而現在是dp不能直接設置。
灰色圓點之間的距離:

left = ll.getChildAt(1).getLeft() - ll.getChildAt(0).getLeft();
public void onPageScrolled(int position, float positionOffset, int arg2)中參數positionOffset指滑動的百分比(范圍[0-1))
現在就可以知道紅色圓點需要滑動多少了。
//導航頁滑動的時候調用
//positionOffset:滑動的百分比([0,1))
@Override
public void onPageScrolled(int position, float positionOffset, int arg2) {
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) red_Iv.getLayoutParams();
layoutParams.leftMargin = (int) (left * positionOffset + position * left);
red_Iv.setLayoutParams(layoutParams);
}
第五步:
新手導航頁,一般移動到最後一頁的時候會有個按鈕跳到主界面。這個只需要在導航頁被選擇的時候設置一下即可
//導航頁被選擇的時候調用
@Override
public void onPageSelected(int position) {
//滑動到最後一頁,顯示按鈕
if (position == images.length - 1) {
btn.setVisibility(View.VISIBLE);
//不是最後一頁,不顯示按鈕
}else {
btn.setVisibility(View.GONE);
}
}
核心代碼:
布局文件:
<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"
tools:context="com.example.viewpager.MainActivity" >
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</android.support.v4.view.ViewPager>
<RelativeLayout
android:id="@+id/rl"
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"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</LinearLayout>
</RelativeLayout>
<Button
android:layout_width="wrap_content"
android:id="@+id/btn"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="50dp"
android:layout_height="wrap_content"
android:text="體驗"
android:visibility="gone"
/>
</RelativeLayout>
MainActivity.java
public class MainActivity extends Activity {
//ViwePager
private ViewPager viewPager;
private Button btn;
//導航頁資源
private int[] images = new int[]{
R.drawable.guide_1,
R.drawable.guide_2,
R.drawable.guide_3,
};
//圓點與圓點之間的邊距
private int left;
//用來存放導航圖片實例(保證唯一性,滑動的時候不重復創建)
private List<ImageView> imageViews;
//存放三個灰色圓點的線性布局
private LinearLayout ll;
//用來存放紅色圓點和灰色圓點的相對布局
private RelativeLayout rl;
//紅色圓點ImageView
private ImageView red_Iv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
//初始化導航頁面和灰色圓點
for (int i = 0; i < images.length; i++) {
ImageView iv = new ImageView(MainActivity.this);
iv.setImageResource(images[i]);
imageViews.add(iv);
//動態加載灰色圓點
ImageView gray_Iv = new ImageView(this);
gray_Iv.setImageResource(R.drawable.grar_circle);
LinearLayout.LayoutParams layoutParams =
new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
//從第二個開始有邊距
if (i > 0) {
layoutParams.leftMargin = 20; //注意單位是px
}
gray_Iv.setLayoutParams(layoutParams);
ll.addView(gray_Iv);
}
red_Iv = new ImageView(this);
red_Iv.setImageResource(R.drawable.red_circle);
rl.addView(red_Iv);
//任何一個組件都可以得到視圖樹
red_Iv.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
//視圖完成繪制的時候調用
@Override
public void onGlobalLayout() {
left = ll.getChildAt(1).getLeft() - ll.getChildAt(0).getLeft();
System.out.println(left);
//移除視圖樹的監聽
red_Iv.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
//為ViewPager添加適配器
viewPager.setAdapter(new MyAdapter());
viewPager.setOnPageChangeListener(new OnPageChangeListener() {
//導航頁被選擇的時候調用
@Override
public void onPageSelected(int position) {
if (position == images.length - 1) {
btn.setVisibility(View.VISIBLE);
}else {
btn.setVisibility(View.GONE);
}
}
//導航頁滑動的時候調用
//positionOffset:滑動的百分比([0,1})
@Override
public void onPageScrolled(int position, float positionOffset, int arg2) {
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) red_Iv.getLayoutParams();
layoutParams.leftMargin = (int) (left * positionOffset + position * left);
red_Iv.setLayoutParams(layoutParams);
}
//導航頁滑動的狀態改變的時候調用
@Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
//初始化組件
private void initView() {
viewPager = (ViewPager) findViewById(R.id.viewPager);
imageViews = new ArrayList<ImageView>();
ll = (LinearLayout) findViewById(R.id.ll);
rl = (RelativeLayout) findViewById(R.id.rl);
btn = (Button) findViewById(R.id.btn);
}
//PagerAdapter有四個方法
class MyAdapter extends PagerAdapter {
//返回導航頁的個數
@Override
public int getCount() {
return images.length;
}
//判斷是否由對象生成
@Override
public boolean isViewFromObject(View view,Object object) {
return view == object;
}
//加載頁面
//ViewGroup:父控件指ViewPager
//position:當前子控件在父控件中的位置
@Override
public Object instantiateItem(ViewGroup container, int position) {
ImageView iv = imageViews.get(position);
container.addView(iv);
return iv;
}
//移除頁面
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
}
大家趕緊試試吧。會有不同的認識。
以上就是本文的全部內容,希望對大家學習Android軟件編程有所幫助。
OpenCV實現圖像阈值化
效果圖源碼KqwOpenCVBlurDemo阈值化是一種將我們想要在圖像中分析的區域分割出來的方法。我們把每個像素值都與一個預設的阈值做比較,再根據比較的結果調整像素值。
Fresco簡單的使用—SimpleDraweeView
百學須先立志—學前須知:在我們平時加載圖片(不管是下載還是加載本地圖片…..)的時候,我們經常會遇到這樣一個需求,那就是當圖片正在加載時應該呈現
Android數據存儲(三)----- SQLite數據庫存儲
SQLite是Android系統內置的數據庫,是一種輕量級的關系型數據庫,它運算速度快,占用資源少,非常適合在移動設備上使用。同時,它不僅支持標准的SQL語法,還遵循了
Android 對話框 Dialog使用實例講解
對話框 Dialog什麼是對話框對話框是在當前的頁面之上彈出的小窗口, 用於顯示一些重要的提示信息, 提示用戶的輸入,確認信息,或顯示某種狀態.如 : 顯示進度條對話框,