1. 程式人生 > >豎直方向+自動滾動+無限滾動+禁止手動滾動的ViewPager

豎直方向+自動滾動+無限滾動+禁止手動滾動的ViewPager

這是一款可以豎直方向可以自動滑動,並且無限滾動的ViewPager,同時,禁止手動滑動。

一、先上效果圖

二、重寫的ViewPager

/**
 * Created by can on 2018/6/15.
 * 豎直方向+自動滾動+無限滾動+可禁止手動滾動的ViewPager
 */

public class VerticalViewPager extends ViewPager {

    private int scroll_duration = 2000; //滑動時長
    private int switch_duration = 1000; //切換時長

    private PagerAdapter adapter;//介面卡

    public VerticalViewPager(Context context) {
        super(context);
        init();
    }

    public VerticalViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public void setMyAdapter(PagerAdapter adapter){
        if(adapter!=null){
            this.adapter = adapter;
            handler.sendEmptyMessage(1);
        }
    }

    //設定切換的時間
    public void setSwitchDuration(int duration){
        this.switch_duration = duration;
    }

    //設定滾動的時間
    public void setScrollDuration(int duration){
        this.scroll_duration = duration;
    }

    //主執行緒處理滾動佈局切換
    private Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what){
                case 1:
                    setAdapter(adapter);
                    handler.removeMessages(2);
                    handler.sendEmptyMessageDelayed(2,scroll_duration);
                    break;
                case 2:
                    handler.removeMessages(2);
                    setCurrentItem(getCurrentIndex());
                    handler.sendEmptyMessageDelayed(2,scroll_duration);
                    break;
            }
            return false;
        }
    });

    //獲取當前下標
    private int getCurrentIndex(){
        return getCurrentItem()+1>=getAdapter().getCount()?0:getCurrentItem()+1;
    }

    private void init() {
        // 設定pageTransformer為豎直滾動
        setPageTransformer(true, new VerticalPageTransformer());
        // 設定滾動模式
        setOverScrollMode(OVER_SCROLL_NEVER);
        setScrollDuration();
    }

    /**
     * 設定滾動時間
     */
    private void setScrollDuration() {
        try {
            // 通過class檔案獲取mScroller屬性
            Field mField = ViewPager.class.getDeclaredField("mScroller");
            mField.setAccessible(true);
            FixedSpeedScroller mScroller = new FixedSpeedScroller(this.getContext(),new AccelerateInterpolator());
            mField.set(this, mScroller);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 切換viewpager時,設定它的時長
     */
    public class FixedSpeedScroller extends Scroller {
        public FixedSpeedScroller(Context context) {
            super(context);
            // TODO Auto-generated constructor stub
        }

        public FixedSpeedScroller(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, switch_duration);
        }

        @Override
        public void startScroll(int startX, int startY, int dx, int dy) {
            super.startScroll(startX, startY, dx, dy, switch_duration);
        }
    }

    //設定滾動為豎直方向的滾動
    private class VerticalPageTransformer implements ViewPager.PageTransformer {
        @Override
        public void transformPage(View view, float position) {
            if (position < -1) {
                view.setAlpha(0);
            } else if (position <= 1) {
                view.setAlpha(1);
                // 抵消預設滑動
                view.setTranslationX(view.getWidth() * -position);
                //設定Y位置從頂部滑入
                float yPosition = position * view.getHeight();
                view.setTranslationY(yPosition);
            } else {
                view.setAlpha(0);
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        //不攔截觸控事件,由上層處理
        return false;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        //不攔截分發事件,由子控制元件分發處理
        return false;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        //分發事件,必須要,否則子view收不到事件
        return super.dispatchTouchEvent(ev);
    }


}

三、重寫的PagerAdapter

/**
 * Created by can on 2018/6/15.
 * 介面卡
 */

public class VerticalScrollPagerAdapter extends PagerAdapter {

    private Context context;//上下文
    private List<String> list;//資料集合
    private View[] views ;//view陣列

    public VerticalScrollPagerAdapter(Context context, List<String> list, View[] views){
        this.context = context;
        this.list = list;
        this.views = views;
    }

    @Override
    public int getCount() {
        //設定總數
        if(list.size()>0)
            return Integer.MAX_VALUE;
        else
            return 0;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view==object;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        //當前實際下標
        int index = position%list.size();
        container.removeView(views[index]);
    }

    @Override
    public Object instantiateItem(final ViewGroup container, final int position) {
        //當前實際下標
        final int index = position%list.size();
        View view = views[index];
        if(view!=null&&view.getParent()!=null){
            return view;
        }else{
            View view_item = LayoutInflater.from(context).inflate(R.layout.item_vertical_textview,null);
            TextView tv =  view_item.findViewById(R.id.tv_item);
            tv.setText(list.get(index));
            views[index] = tv;
            ViewGroup parent = (ViewGroup) tv.getParent();
            if (parent != null) {
                //防止佈局出錯
                parent.removeAllViews();
            }
            container.addView(views[index]);
            return tv;
        }
    }
}

item_vertical_textview.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center_vertical">

    <TextView
        android:id="@+id/tv_item"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:gravity="center_vertical"
        android:textColor="#666666"
        android:textSize="13sp"
        android:singleLine="true"
        android:ellipsize="end"
        />

</LinearLayout>

四、如何使用:

/**
 * Created by can on 2018/6/15.
 * 豎直ViewPager
 */
public class VerticalViewPagerActivity extends BaseActivity {

    @BindView(id = R.id.vertical_viewpager)
    private VerticalViewPager verticalViewPager;
@Override
public int getLayoutId() {
        return R.layout.activity_vertical_viewpager;
}

    @Override
public void initData(Bundle bundle) {
        BaseRequestBean bean = new BaseRequestBean();
bean.setRequest_url("http://www.wanandroid.com/");
bean.setObservable(manager!=null?((DataManager)manager).getHomeArticleList(0):null);
requestData(bean);
}

    @Override
public void onSuccess(ResponseBody success) {
        HomeArticleListBean bean = GsonUtils.parseResponseBody(success,HomeArticleListBean.class);
        if(bean!=null&&bean.getData()!=null&&bean.getData().getDatas()!=null){
            List<HomeArticleListBean.DataBean.DatasBean> list = bean.getData().getDatas();
List<String> string_list = new ArrayList<>();
            for(int i =0;i<list.size();i++){
                string_list.add(list.get(i).getTitle());
}
            string_list = initList(string_list);
View[]views = new View[list.size()];
VerticalScrollPagerAdapter adapter = new VerticalScrollPagerAdapter(this,string_list,views);
            verticalViewPager.setMyAdapter(adapter);}

    }

    //集合數量不能小於4
private List<String> initList(List<String> list) {
        if(list.size()>0&&list.size()<4){
            list.addAll(list);
initList(list);
}
        return list;
}
}

設定介面卡的時候將相關資料設定好就ok了

五、專案地址: