<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## 一、簡介 **1.特點:**可以左右滑動的控件,需要PagerAdapter配合使用,由v4包提供 類全名: android.support.v4.view.ViewPager **2.作用**:ViewPager作用主要是能使界面左右滑動。比如最常用的使用是做一個引導界面;多張圖片的預覽或自動變換的圖片展示(如淘寶首頁面上的廣告);viewpager還可以結合fragment作為主界面框架(如微信主界面)。。。 **3.viewpager中的幾個重要的方法** 1)setAdapter()設置ViewPager的適配器。 2)setOnPageChangeListener()設置頁面改變事件監聽器 3)setCurrentItem(int position) 顯示第幾頁 4)setCurrentItem(int position,boolean smoothScroll) 顯示第幾頁,是否執行滾動動畫 5)setOffscreenPageLimit(int limit) 設置脫離屏幕的頁面限制--最多同時加載的頁面數,limit默認是1 -?這個方法解釋一下:默認情況下,viewpager在顯示頁面時,會加載當前顯示頁和它左右的頁面,這也是為什么移動頁面時可以顯示下一頁面一部分。如果想設置其他數,viewpager會加載對應值的頁面,比如設置2,則當前顯示頁和它左兩頁和右兩頁都會加載。 ## 二、相關類介紹 **1.viewpager相關的幾個重要的類** **1.1OnPageChangeListener:** –onPageScrollStateChanged(int state) 頁面滾動發生或停止時 –onPageScrolled(int position, float offset, int offsetPixes) 滾動時 –onPageSelected(int position) 頁面位置確定時 **1.2 PagerAdapter** –作用:主要配合ViewPager顯示相關的View –用法: 1)創建類,并繼承PagerAdatper 2) 必須實現的方法 –getCount() 獲取View的數量 –instantiateItem(ViewGroup, int poistion) 實例化指定位置的View對象 –destroyItem(ViewGroup, int poistion, Object) 刪除指定位置的View –isViewFromObject(View, Object) 判斷當前的View是否為Object **1.3FragmentPagerAdaper** –作用:與PagerAdapter的功能相同,不過顯示的View改為Fragment –FragmentStatePagerAdapter: 如果需要處理有很多頁,并且數據動態性較大、占用內存較多的情況,應該使用FragmentStatePagerAdapter 保存當前界面,以及下一個界面和上一個界面(如果有),最多保存3個,其他會被銷毀掉。 –FragmentPagerAdaper和FragmentStatePagerAdapter的區別: FragmentPagerAdaper銷毀的只是視圖,數據沒有銷毀,FragmentStatePagerAdapter則是全部銷毀。拿fragment生命周期來說,使用FragmentPagerAdaper,當滑動頁面時,被銷毀的fragment會執行到onDestyoyView()但沒有執行onDestroy()。而使用FragmentStatePagerAdapter時,會執行onDestroy()方法。后面實例會看到。 ## 三、使用 **1.使用步驟:** 1) 在布局文件中使用標簽 ~~~ <android.support.v4.view.ViewPager/> ~~~ 2) 代碼中增加顯示的頁面 3) 在Activity里實例化ViewPager組件,并設置它的Adapter 需要注意的是:根據不同的場景,選擇不同的適配器父類,不結合fragment使用時使用繼承PagerAdapter的適配器,結合Fragment使用時,根據需求,可以選擇父類為FragmentPagerAdapter和FragmentStatePagerAdapter,這兩個的區別在后面前面已經講過了。 **2.案例一:用viewpager做一個歡迎界面** 先看效果圖: ![這里寫圖片描述](https://box.kancloud.cn/2016-04-20_5717152a6d732.jpg "") **1) 布局文件** ~~~ <FrameLayout 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="${relativePackage}.${activityClass}" > <!-- 其顯示的頁面需要通過PagerAdapter適配器增加或移除 --> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="match_parent" /> <!-- 導航布局 ,小點點 --> <LinearLayout android:id="@+id/ll_dots" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:layout_marginBottom="10dp" android:gravity="center" android:orientation="horizontal" android:padding="10dp" > </LinearLayout> </FrameLayout> ~~~ **2) 然后看看幾個主要的方法體:** **第一個是自定義的適配器**,各種方法都有注釋。 ~~~ // 聲明PageAdapter子類,用于管理viewpager中顯示的控件 class WelComePageAdapter extends PagerAdapter { @Override public int getCount() { // TODO 返回頁面的數量 return views.size(); } @Override public Object instantiateItem(ViewGroup container, int position) { // TODO 獲取指定位置的View(UI),并增加到ViewPager中,同時作為當前頁面的數據返回 Log.i("--", "instantiateItem--" + position); View view = views.get(position); container.addView(view); return view; } @Override public void destroyItem(ViewGroup container, int position, Object object) { // TODO 當前位置與VIewPager中顯示頁面的位置的間隔超出一頁面,需要將當前位置的頁面移除 Log.i("--", "destroyItem--" + position); container.removeView(views.get(position)); } @Override public boolean isViewFromObject(View view, Object obj) { // TODO 判斷當前顯示的頁面的UI和數據對象是否一致 return view == obj; } } ~~~ **第二個是viewpager滑動監聽事件**,這里自定義一個類看著清楚點,繼承OnPageChangeListener,然后事項相應的方法,特別注意onPageScrolled和onPageSelected這兩個方法,onPageScrolled在滑動時會一直回調,根據回調的三個參數,在這里可以進行相應的操作,比如微信那個,當你滑動時,相鄰兩個標簽會有顏色的漸變,就在這里處理的。onPageSelected方法在滑動一個頁面停止后回調。 ~~~ class WelcomPageChangeListner implements OnPageChangeListener { @Override public void onPageScrollStateChanged(int state) { Log.i("--", "onPageScrollStateChanged" + state); // TODO 頁面滾動狀態發生變化事件:開始滾動、停止滾動、正在設置頁面 // ViewPager.SCROLL_STATE_DRAGGING 開始滾動 // ViewPager.SCROLL_STATE_IDLE 停止滾動 // ViewPager.SCROLL_STATE_SETTLING 正在設置頁面,即將要停止,并且設置當前顯示的頁面 // setDot(position); // switch (state) { // case ViewPager.SCROLL_STATE_DRAGGING: // Log.i("--", "-SCROLL_STATE_DRAGGING-"); // break; // case ViewPager.SCROLL_STATE_IDLE: // Log.i("--", "-SCROLL_STATE_IDLE-"); // break; // case ViewPager.SCROLL_STATE_SETTLING: // Log.i("--", "-SCROLL_STATE_SETTLING-"); // break; // } } ~~~ ~~~ /** * 第一個參數:滾動頁面開始的位置 <br> * 第二個參數:兩個頁面之間滾動的偏移量,范圍:0-1<br> * 第三個頁面:兩個頁面之間的滾動的像素偏移量<br> */ @Override public void onPageScrolled(int position, float offset, int offsetPixwls) { // TODO 從當前頁面位置開始滾動事件 // Log.i("--", "-onPageScrolled-" + position + ",[" + offset + "]," // + "[" + offsetPixwls + "]"); } @Override public void onPageSelected(int position) { // TODO 指定位置的頁面被選擇 setDot(position); } } ~~~ **第三個是動態改變導航欄小點點的背景圖。** ~~~ /** * 選擇指定位置的導航圖片為選擇圖片,之前選擇的導航圖片重置為未選擇圖片 * * @param position */ private void setDot(int position) { ImageView imageView = null; // 遍歷導航布局張所有的子控件,判斷子控件的位置是否未選擇位置,若是則設置為選擇圖片 for (int i = 0; i < LlDot.getChildCount(); i++) { imageView = (ImageView) LlDot.getChildAt(i);// 獲取布局中指定位置的子控件 if (i == position) { imageView.setImageResource(R.drawable.page_now); } else { imageView.setImageResource(R.drawable.page); } } } ~~~ 其他還有小點點的點擊事件,具體看源代碼。 **3.案例二:viewpager和view結合做一個主界面** 效果圖: ![這里寫圖片描述](https://box.kancloud.cn/2016-04-23_571af4d4d8d7f.jpg "") 1)布局:最上面的導航欄是一個HorizonalScrollView,里面有一個LinearLayout(因為HorizonalScrollView里只能有一個子視圖),然后在LinearLayout定義你想要的導航模塊,TextView即可。 ~~~ <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="${relativePackage}.${activityClass}" > <HorizontalScrollView android:id="@+id/hScrollView" android:layout_width="match_parent" android:layout_height="50dp" android:layout_marginBottom="2dp" android:scrollbars="none" > <LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:orientation="vertical" > <!-- 頂部模塊的布局 --> <LinearLayout android:id="@+id/navLayout" android:layout_width="wrap_content" android:layout_height="45dp" android:orientation="horizontal" > <TextView android:id="@+id/tv_model1" android:layout_width="150dp" android:layout_height="match_parent" android:gravity="center" android:text="第一" android:textColor="#000" android:textSize="20sp" /> <TextView android:id="@+id/tv_model2" android:layout_width="150dp" android:layout_height="match_parent" android:gravity="center" android:text="第二" android:textColor="#000" android:textSize="20sp" /> <TextView android:id="@+id/tv_model3" android:layout_width="150dp" android:layout_height="match_parent" android:gravity="center" android:text="第三" android:textColor="#000" android:textSize="20sp" /> <TextView android:id="@+id/tv_model4" android:layout_width="150dp" android:layout_height="match_parent" android:gravity="center" android:text="第四" android:textColor="#000" android:textSize="20sp" /> <TextView android:id="@+id/tv_model5" android:layout_width="150dp" android:layout_height="match_parent" android:gravity="center" android:text="第五" android:textColor="#000" android:textSize="20sp" /> </LinearLayout> <!-- 指示器控件 --> <View android:id="@+id/view_nav" android:layout_width="150dp" android:layout_height="4dp" android:background="#0cf" /> <!-- 基準線 --> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="#0cf" /> </LinearLayout> </HorizontalScrollView> <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_below="@id/hScrollView" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout> ~~~ **還需要幾個fragment頁,這里只展示一個,其他類似:** ~~~ <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center" android:background="#80f0"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="第一個頁面" android:textSize="30sp" /> </RelativeLayout> ~~~ **2)代碼中需要做的事情有:** 2).1 指示器的移動,也就是模塊下那個粗線條的移動,viewpager本身就是可滑動的控件,這里需要指示器隨著手指的滑動進行滑動 2).2選擇導航模塊的位置,將水平滾動到當前模塊位置的中心點, 2).3模塊點擊事件,點擊模塊,顯示相應的page 那么來一步步實現上面的工作: 2.1指示器的移動 要求是指示器隨著手指的滑動,起始也就是動態的改變指示器的leftMargin ~~~ /** * 指示器移動 * @param position * @param offset */ private void navIndicateMove(int position, float offset){ int leftMargin = (int) (indicateParams.width * (position + offset)); indicateParams.leftMargin = leftMargin; navIndicate.setLayoutParams(indicateParams); } ~~~ 2.2選擇導航模塊的位置,將水平滾動到當前模塊位置的中心點 因為整個導航模塊都在一個HorizonalScrollView中,HorizonalScrollView中有兩個方法可以指定的移動位置,一個是**hScrollView.scrollTo(x, y);//非平滑移動** **hScrollView.smoothScrollTo(x, y);//平滑移動** 所以根據選擇的模塊得到移動值即可。 ~~~ /** * 選擇導航模塊的位置,將水平滾動到當前模塊位置的中心點 * * @param position */ private void selectNav(int position) { TextView modelTv = (TextView) navLayout.getChildAt(position); int left = modelTv.getLeft();// 獲取當前控件的左邊位置 // 怎么放到中間? // int scWidth = (getResources().getDisplayMetrics().widthPixels / 2); int offset = left - (getResources().getDisplayMetrics().widthPixels / 2) + modelTv.getWidth() / 2; hScrollView.smoothScrollTo(offset, 0);// 水平滾動到指定位置 //設置被選中的模塊 for(int i = 0; i < navLayout.getChildCount(); i++){ modelTv = (TextView) navLayout.getChildAt(i); if(i == position){ modelTv.setTextColor(Color.argb(100, 255, 0, 0)); }else{ modelTv.setTextColor(Color.argb(255, 0, 0, 0)); } } } ~~~ **3.模塊點擊事件,點擊模塊,顯示相應的page** 給每個模塊添加點擊事件,然后點擊一個模塊,只用調用viewPager的 viewPager.setCurrentItem(item);//非平滑滑動 viewPager.setCurrentItem(item, smoothScroll);//平滑滑動 ~~~ /** * 模塊點擊事件 */ private void modelTvClickEvent() { for(int i = 0; i < navLayout.getChildCount(); i++){ final TextView tv = (TextView) navLayout.getChildAt(i); tv.setTag(i); tv.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { int position = (Integer)tv.getTag(); // selectNav(position); // navIndicateMove(position, 0); viewPager.setCurrentItem(position, true); } }); } } ~~~ **這樣,viewpager結合導航欄都可以同步滑動了。** **4.案例三:viewpager和fragment結合做一個主界面** 效果圖: ![這里寫圖片描述](https://box.kancloud.cn/2016-04-23_571af4d52e586.jpg "") 結合fragment使用和結合view使用很相似,只是繼承的適配器不同。 上面繼承PagerAdapter,這里繼承FragmentPagerAdapter或者FragmentStatePagerAdapter。 1)定義一個ListFragment 2)自定義適配器 3)初始化數據源 ListFragment的使用前面有一篇講過,這里就不附代碼了。 來看看自定義適配器:很簡單就完事 ~~~ class InfoFragmentAdapter extends FragmentStatePagerAdapter{ public InfoFragmentAdapter(FragmentManager fm){ super(fm); } @Override public int getCount() { return fragments.size(); } @Override public Fragment getItem(int position) { //返回指定位置的碎片 return fragments.get(position); } } ~~~ **最后可以借這個案例看一看FragmentPagerAdapter和FragmentStatePagerAdapter區別:** ViewPager:默認創建自己和左右兩頁,當某個頁面與顯示的頁面間放大點隔大于1,則銷毀UI界面(注意,只是UI,里面的數據則不會銷毀) FragmentPagerAdapter:管理fragment時銷毀的是UI界面,(fragment生命周期只會執行到onDestroyView) FragmentStatePagerAdapter:管理fragment時,完全銷毀(fragment生命周期會執行onDestroy) 只用把自定義適配器類的父類改一改,然后看fragment各生命周期 打印的日志即可看到區別,這里不做演示了。 現在,結合案例二和案例三就可以做一個現在很流行的主界面了。 [ 源碼下載](http://download.csdn.net/detail/u011102153/9120819)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看