ViewPager +無限輪播+滑動速度修改+指示小點


養成習慣,做過代碼記錄總結。

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>

 
















 

 

                  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM