HorizontalScrollView 实现 ViewPager 可滑动翻页的tab

来源:互联网 发布:淘宝店铺页尾怎么设置 编辑:程序博客网 时间:2024/05/01 22:23

ViewPager 有很好的翻页效果,长用于图片浏览。今天产品设计了一个 奇葩的需求 ,翻页里边放tab ,并保留点击后的效果。
先看看要实现的效果, 一个两个页面的翻页效果。
这里写图片描述

实现好的效果
这里写图片描述
常用的ViewPager当然可以实现 ,但是 ViewPager 有个弊端,就是有缓存 ,使用起来也是比较麻烦。于是就想到了 scrollView。

想法: HorizontalScrollView,我们改写它的滑动事件。检测 滑动方向和距离。 当设定一个滑动距离,超过这个距离就表示翻页,没有这表示不翻页。翻页距离为一个屏幕宽度。

重点方法:

   @Override    public boolean onTouchEvent(MotionEvent ev) {        int action = ev.getAction();        switch (action) {            case MotionEvent.ACTION_UP:                int scrollX = getBaseScrollX();                //左滑,大于指定距离,移到下一页                if (scrollX > mScrollX) {                    baseSmoothScrollTo(mScreenWidth);                    mBaseScrollX += mScreenWidth;                    positionSun++;                    listener.OnClickmoveItem(positionSun);                    // listener.OnClickmoveItem(1);                }                //左滑,不到指定距离,返回原位                else if (scrollX > 0) {                     baseSmoothScrollTo(0);                }                //右滑,不到指定距离,返回原位                else if (scrollX > -mScrollX) {                    baseSmoothScrollTo(0);                }                //右滑,大于指定距离,移到下一页                else {                    baseSmoothScrollTo(-mScreenWidth);                    mBaseScrollX -= mScreenWidth;                    positionSun--;                    // listener.OnClickmoveItem(0);                    listener.OnClickmoveItem(positionSun);                }                return true;        }        return super.onTouchEvent(ev);    }

完整代码代码

import android.content.Context;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.view.MotionEvent;import android.view.View;import android.widget.HorizontalScrollView;import android.widget.LinearLayout;/** * 滑动翻页效果 */public class PageView extends HorizontalScrollView {    private int mBaseScrollX;//滑动基线。也就是点击并滑动之前的x值,以此值计算相对滑动距离。    private int mScreenWidth;    private int mScreenHeight;    private LinearLayout mContainer;    private boolean flag;    private int mPageCount;//页面数量    private int positionSun = 0;  //  记录当前位置    private int mScrollX = 100;//滑动多长距离翻页    public PageView(Context context, AttributeSet attrs) {        super(context, attrs);        DisplayMetrics dm = context.getApplicationContext().getResources()                .getDisplayMetrics();        mScreenWidth = dm.widthPixels;        mScreenHeight = dm.heightPixels;    }    /**     * 添加一个页面到最后。     *     * @param page     */    public void addPage(View page) {        addPage(page, -1);    }    /**     * 添加一个页面。     *     * @param page     */    public void addPage(View page, int index) {        if (!flag) {            mContainer = (LinearLayout) getChildAt(0);            flag = true;        }        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(mScreenWidth, mScreenHeight);        if (index == -1) {            mContainer.addView(page, params);        } else {            mContainer.addView(page, index, params);        }        mPageCount++;    }    /**     * 移除一个页面。     *     * @param index     */    public void removePage(int index) {        if (mPageCount < 1) {            return;        }        if (index < 0 || index > mPageCount - 1) {            return;        }        mContainer.removeViewAt(index);        mPageCount--;    }    /**     * 设置移动距离触发滑动 默认为100     *     * @param distance 水平移动的距离     */    public void setHorizontalMovingDistance(int distance) {        if (distance != 0) {            mScrollX = distance;        }    }    /**     * 移除所有的页面     */    public void removeAllPages() {        if (mPageCount > 0) {            mContainer.removeAllViews();        }    }    /**     * 获取页面数量     *     * @return     */    public int getPageCount() {        return mPageCount;    }    /**     * 获取相对滑动位置。由右向左滑动,返回正值;由左向右滑动,返回负值。     *     * @return     */    private int getBaseScrollX() {        return getScrollX() - mBaseScrollX;    }    /**     * 使相对于基线移动x距离。     *     * @param x x为正值时右移;为负值时左移。     */    private void baseSmoothScrollTo(int x) {        smoothScrollTo(x + mBaseScrollX, 0);    }    @Override    public boolean onTouchEvent(MotionEvent ev) {        int action = ev.getAction();        switch (action) {            case MotionEvent.ACTION_UP:                int scrollX = getBaseScrollX();                //左滑,大于指定距离,移到下一页                if (scrollX > mScrollX) {                    baseSmoothScrollTo(mScreenWidth);                    mBaseScrollX += mScreenWidth;                    positionSun++;                    listener.OnClickmoveItem(positionSun);                    // listener.OnClickmoveItem(1);                }                //左滑,不到指定距离,返回原位                else if (scrollX > 0) {                     baseSmoothScrollTo(0);                }                //右滑,不到指定距离,返回原位                else if (scrollX > -mScrollX) {                    baseSmoothScrollTo(0);                }                //右滑,大于指定距离,移到下一页                else {                    baseSmoothScrollTo(-mScreenWidth);                    mBaseScrollX -= mScreenWidth;                    positionSun--;                    // listener.OnClickmoveItem(0);                    listener.OnClickmoveItem(positionSun);                }                return true;        }        return super.onTouchEvent(ev);    }    private OnClickMove listener;    public interface OnClickMove {    // 滑动的当前位置        void OnClickmoveItem(int position);    }     // 滑动监听    public void setMoveListener(OnClickMove listener) {        this.listener = listener;    }}

使用

//注意 里边* 必需嵌套一个子控件* ,scrollView里边只有一子空间

            <com.yude.demo.views.view.PageView                android:id="@+id/pageview"                android:layout_width="wrap_content"                android:layout_height="90dp"                android:background="@color/_ffffff_bg"                android:scrollbars="none">                <LinearLayout                    android:layout_width="wrap_content"                    android:layout_height="fill_parent"                    android:orientation="horizontal">                </LinearLayout>            </com.yude.views.views.view.PageView>

activity 或 Fragment

 mPageView = (PageView) rootView.findViewById(R.id.pageview);        //这里就是个普通的xml布局文件 作为第一页第二页的布局        LinearLayout view = (LinearLayout) inflater.inflate(R.layout.fragment_page1, null);        mPageView.addPage(view);        LinearLayout view2 = (LinearLayout) inflater.inflate(R.layout.fragment_page2, null);        mPageView.addPage(view2);        mPageView. setHorizontalMovingDistance(100); //设置移动距离触发滑动        mPageView.setMoveListener(new PageView.OnClickMove() {            @Override            public void OnClickmoveItem(int position) {             //设置原点视图更改 这里只有两页                 Log.d("OnClickmoveItem", "当前位置" + position);                if (position == 0) {                    view_0.setImageResource(dowImage[0]);                    view_1.setImageResource(dowImage[1]);                } else {                    view_0.setImageResource(dowImage[1]);                    view_1.setImageResource(dowImage[0]);                }            }        });

实现起来还是比较简单 , 可以更具自己需要调整 。

阅读全文
0 0
原创粉丝点击