養成習慣,做過代碼記錄總結。
ViewPager 使用記錄
1. ViewPage 位於V4包。
2.主要用來做banner輪播。
3.原理:適配器重用提高效率,與listview等一個原理。
下面記錄實現代碼。
一:
在布局里使用ViewPager
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" tools:context="com.example.testviewpage_1.MainActivity" > <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" /> </RelativeLayout>
二:需要一個適配器 :PageAdapter ;
PagerAdapter pagerAdapter = new PagerAdapter() { @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1; } @Override public int getCount() { return viewList.size(); } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView(viewList.get(position)); } @Override public Object instantiateItem(ViewGroup container, int position) { container.addView(viewList.get(position)); return viewList.get(position); } };
三:給apapter 加點數據(View)。
private ViewPager viewPager;
private List<View> viewList;
viewList = new ArrayList<>(); ImageView iv = new ImageView(getActivity()); Glide.with(getContext()).load("http://www.shjinheng.com/uploadfile/2016/1130/20161130023058307.jpg").into(iv); viewList.add(iv); iv = new ImageView(getActivity()); Glide.with(getContext()).load(urls[1]).into(iv); viewList.add(iv); iv = new ImageView(getActivity()); Glide.with(getContext()).load(urls[2]).into(iv); viewList.add(iv);
關鍵內容:
對adapter的里解
Base class providing the adapter to populate pages inside of a ViewPager. You will most likely want to use a more specific implementation of this, such as FragmentPagerAdapter orFragmentStatePagerAdapter. When you implement a PagerAdapter, you must override the following methods at minimum: instantiateItem(ViewGroup, int) destroyItem(ViewGroup, int, Object) getCount() isViewFromObject(View, Object) PagerAdapter is more general than the adapters used for AdapterViews. Instead of providing a View recycling mechanism directly ViewPager uses callbacks to indicate the steps taken during an update. A PagerAdapter may implement a form of View recycling if desired or use a more sophisticated method of managing page Views such as Fragment transactions where each page is represented by its own Fragment. ViewPager associates each page with a key Object instead of working with Views directly. This key is used to track and uniquely identify a given page independent of its position in the adapter. A call to the PagerAdapter method startUpdate(ViewGroup) indicates that the contents of the ViewPager are about to change. One or more calls to instantiateItem(ViewGroup, int) and/ordestroyItem(ViewGroup, int, Object) will follow, and the end of an update will be signaled by a call to finishUpdate(ViewGroup). By the time finishUpdate returns the views associated with the key objects returned by instantiateItem should be added to the parent ViewGroup passed to these methods and the views associated with the keys passed to destroyItem should be removed. The method isViewFromObject(View, Object) identifies whether a page View is associated with a given key object. A very simple PagerAdapter may choose to use the page Views themselves as key objects, returning them from instantiateItem(ViewGroup, int) after creation and adding them to the parent ViewGroup. A matching destroyItem(ViewGroup, int, Object) implementation would remove the View from the parent ViewGroup and isViewFromObject(View, Object) could be implemented as return view == object;. PagerAdapter supports data set changes. Data set changes must occur on the main thread and must end with a call to notifyDataSetChanged() similar to AdapterView adapters derived fromBaseAdapter. A data set change may involve pages being added, removed, or changing position. The ViewPager will keep the current page active provided the adapter implements the methodgetItemPosition(Object).
isViewFromObject(View, Object)
功能:該函數用來判斷instantiateItem(ViewGroup, int)函數所返回來的Key與一個頁面視圖是否是代表的同一個視圖(即它倆是否是對應的,對應的表示同一個View)
返回值:如果對應的是同一個View,返回True,否則返回False。
instantiateItem (ViewGroup container, int position)
給對應位置一個View
實現循環
有兩種辦法,一種是把getcount改成
Integer.MAX_VALUE
在dinstantiateItem 方法中 對position取%
然后就是各種坑,這種方法不太好用。
第二種方法是多加兩個view 取實際的最后一個放在第一個,實際第一個放在最后一個。
如果是三個數據,那最終viewlist應該是2,0,1,2,0
在onPageSelected方法中當頁轉到第5頁時,調用setCurrentItem方法將當前頁設置到1,相反是0的時候設置到2;
看代碼
多插入兩條內容。
viewList = new ArrayList<>(); ImageView iv = new ImageView(getActivity()); Glide.with(getContext()).load(urls[2]).into(iv); viewList.add(iv);//多加的 iv = new ImageView(getActivity()); Glide.with(getContext()).load(urls[0]).into(iv); viewList.add(iv); iv = new ImageView(getActivity()); Glide.with(getContext()).load(urls[1]).into(iv); viewList.add(iv); iv = new ImageView(getActivity()); Glide.with(getContext()).load(urls[2]).into(iv); viewList.add(iv); iv = new ImageView(getActivity()); Glide.with(getContext()).load(urls[0]).into(iv); viewList.add(iv);//多加的
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(final int position) { mHandler.postDelayed(new Runnable() { @Override public void run() { if (position == viewList.size() - 1) { viewPager.setCurrentItem(1, false);//不要動畫 } else if (position == 0) { viewPager.setCurrentItem(viewList.size() - 2, false);//不要動畫 } } }, 200);//延后執行,改善視覺效果。 } @Override public void onPageScrollStateChanged(int state) { } });
當然要從第二個開始展示
viewPager.setCurrentItem(1);
接下來搞定自動輪播:
handler 來實現。
Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); viewPager.setCurrentItem((viewPager.getCurrentItem() + 1) % viewList.size()); mHandler.sendEmptyMessageDelayed(1, 1000); } };
修改滑動速度.
默認的速度太快,viewpager也沒有給出修改辦法,還限制了最長不超過600毫秒。
滑動最終還是由scroller完成,我們通過反射來修改viewpager自帶scroller ;
package com.lechang.utils; import android.content.Context; import android.support.v4.view.ViewPager; import android.view.animation.Interpolator; import android.widget.Scroller; import java.lang.reflect.Field; /** * hongtao */ public class MyScroller extends Scroller { private int mDuration = 1500; // default time is 1500ms public MyScroller(Context context) { super(context); } public MyScroller(Context context, Interpolator interpolator) { super(context, interpolator); } @Override public void startScroll(int startX, int startY, int dx, int dy, int duration) { super.startScroll(startX, startY, dx, dy, mDuration); } @Override public void startScroll(int startX, int startY, int dx, int dy) { super.startScroll(startX, startY, dx, dy, mDuration); } /** * set animation time * * @param time */ public void setmDuration(int time) { mDuration = time; } /** * get current animation time * * @return */ public int getmDuration() { return mDuration; } public void acttchToViewPager(ViewPager viewPager) { try { Field mField = ViewPager.class.getDeclaredField("mScroller"); mField.setAccessible(true); mField.set(viewPager, this); } catch (Exception e) { e.printStackTrace(); } } }
//修改滑動速度
MyScroller myScroller = new MyScroller(getContext());
myScroller.setmDuration(2000);
myScroller.attacToViewPager(viewPager);
到此完美實現。
給出完整的類:
package com.lechang.fragment; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.LinearLayout; import com.bumptech.glide.Glide; import com.lechang.R; import com.lechang.utils.MyScroller; import java.util.ArrayList; import java.util.List; /** * @author hongtao */ public class QualityFragment extends BaseFragment { public QualityFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_quality, container, false); init(view); return view; } LinearLayout ll_point; String urls[] = {"https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=150174610,1151432426&fm=27&gp=0.jpg", "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1705520648,1030222030&fm=27&gp=0.jpg", "https://f10.baidu.com/it/u=2987595138,4271236850&fm=72"}; public void setPoint(int index) { if (index == viewList.size() - 1) { index = 1; } else if (index == 0) { index = viewList.size() - 2; } for (int i = 0; i < viewList.size() - 1; i++) { if (i == (index - 1)) { ll_point.getChildAt(i).setBackgroundResource(R.drawable.point_fucsed); } else { ll_point.getChildAt(i).setBackgroundResource(R.drawable.point_unfucsed); } } } public void initPoint() { for (int i = viewList.size() - 2; i < ll_point.getChildCount(); i++) { ll_point.getChildAt(i).setVisibility(View.GONE); } } public void init(View rootView) { ll_point = (LinearLayout) rootView.findViewById(R.id.ll_point); viewList = new ArrayList<>(); ImageView iv = new ImageView(getActivity()); Glide.with(getContext()).load(urls[2]).into(iv); viewList.add(iv); iv = new ImageView(getActivity()); Glide.with(getContext()).load(urls[0]).into(iv); viewList.add(iv); iv = new ImageView(getActivity()); Glide.with(getContext()).load(urls[1]).into(iv); viewList.add(iv); iv = new ImageView(getActivity()); Glide.with(getContext()).load(urls[2]).into(iv); viewList.add(iv); iv = new ImageView(getActivity()); Glide.with(getContext()).load(urls[0]).into(iv); viewList.add(iv); viewPager = (ViewPager) rootView.findViewById(R.id.viewpager); viewPager.setAdapter(pagerAdapter); viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(final int position) { mHandler.postDelayed(new Runnable() { @Override public void run() { if (position == viewList.size() - 1) { viewPager.setCurrentItem(1, false);//不要動畫 } else if (position == 0) { viewPager.setCurrentItem(viewList.size() - 2, false);//不要動畫 } } }, INTERVAL_TIME);//延后執行,改善視覺效果。 setPoint(position); } @Override public void onPageScrollStateChanged(int state) { } }); viewPager.setCurrentItem(1); initPoint(); //修改滑動速度 MyScroller myScroller = new MyScroller(getContext()); myScroller.setmDuration(2000); myScroller.attachToViewPager(viewPager); mHandler.sendEmptyMessageDelayed(1, INTERVAL_TIME); } public static final int INTERVAL_TIME = 3000; Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); viewPager.setCurrentItem((viewPager.getCurrentItem() + 1) % viewList.size()); mHandler.sendEmptyMessageDelayed(1, INTERVAL_TIME); } }; private ViewPager viewPager; private List<View> viewList; PagerAdapter pagerAdapter = new PagerAdapter() { @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1; } @Override public int getCount() { return viewList.size(); } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView(viewList.get(position)); } @Override public Object instantiateItem(ViewGroup container, int position) { container.addView(viewList.get(position)); return viewList.get(position); } }; }
配置
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.lechang.fragment.QualityFragment"> <RelativeLayout android:layout_width="match_parent" android:layout_height="150dp"> <android.support.v4.view.ViewPager android:id="@+id/viewpager" android:layout_width="match_parent" android:layout_height="150dp" android:background="#444" /> <LinearLayout android:id="@+id/ll_point" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true"> <View android:layout_width="5dp" android:layout_height="5dp" android:layout_margin="5dp" android:background="@drawable/point_fucsed" /> <View android:layout_width="5dp" android:layout_height="5dp" android:layout_margin="5dp" android:background="@drawable/point_unfucsed" /> <View android:layout_width="5dp" android:layout_height="5dp" android:layout_margin="5dp" android:background="@drawable/point_unfucsed" /> <View android:layout_width="5dp" android:layout_height="5dp" android:layout_margin="5dp" android:background="@drawable/point_unfucsed" /> <View android:layout_width="5dp" android:layout_height="5dp" android:layout_margin="5dp" android:background="@drawable/point_unfucsed" /> </LinearLayout> </RelativeLayout> </FrameLayout>
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" android:useLevel="false"> <solid android:color="#055" /> <stroke android:width="1dp" android:color="@color/white" /> <size android:width="5dp" android:height="5dp" /> </shape>
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval" android:useLevel="false"> <solid android:color="#f00" /> <stroke android:width="1dp" android:color="@color/white" /> <size android:width="5dp" android:height="5dp" /> </shape>