Android开发之自定义HorizontalScrollView视图实现仿ViewPager效果

开发过程中,需要达到 HorizontalScrollView和ViewPager的效果,于是直接重写了HorizontalScrollView来达到实现ViewPager的效果。

实际效果图如下:

(1)自定义HorizontalScrollView类:AppHorizontalScrollView实现:

package com.czm.ui.view;

import java.util.ArrayList;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.HorizontalScrollView;

/***
 * 应用详情页截图 自定义HorizontalScrollView视图  ( 仿ViewPager效果)
 * @author caizhiming
 *
 */
public class AppHorizontalScrollView extends HorizontalScrollView {

    /**
     * 数据定义
     */
    private int subChildCount = 0;
    private ViewGroup firstChild = null;
    private int downX = 0;
    private int currentPage = 0;
    private ArrayList<Integer> viewList = new ArrayList<Integer>();

    /**
     * 构造方法
     * @author caizhiming
     */
    public AppHorizontalScrollView(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

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

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

    private void init() {
        setHorizontalScrollBarEnabled(false);//设置原有的滚动无效
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        getChildInfo();
    }

    /**
     * 获取子视图信息
     * @author caizhiming
     */
    public void getChildInfo() {

        firstChild = (ViewGroup) getChildAt(0);
        if (firstChild != null) {
            subChildCount = firstChild.getChildCount();
            for (int i = 0; i < subChildCount; i++) {
                if (((View) firstChild.getChildAt(i)).getWidth() > 0) {
                    viewList.add(((View) firstChild.getChildAt(i)).getLeft());
                }
            }
        }

    }

    /**
     * 触摸监听时间
     * @author caizhiming
     */
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            downX = (int) ev.getX();
            break;
        case MotionEvent.ACTION_MOVE:
            break;
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_CANCEL: {
            if (Math.abs((ev.getX() - downX)) > getWidth() / 4) {
                if (ev.getX() - downX > 0) {
                    smoothScrollToPrePage();
                } else {
                    smoothScrollToNextPage();
                }
            } else {
                smoothScrollToCurrent();
            }
            return true;
        }
        }
        return super.onTouchEvent(ev);
    }

    /**
     * 滑动到当前页
     * @author caizhiming
     */
    private void smoothScrollToCurrent() {
        smoothScrollTo(viewList.get(currentPage)-10, 0);
    }

    /**
     * 滑动到下一页
     * @author caizhiming
     */
    private void smoothScrollToNextPage() {
        if (currentPage < subChildCount - 1) {
            currentPage++;
            smoothScrollTo(viewList.get(currentPage)-10, 0);
        }
    }
    /**
     * 滑动到上一页
     * @author caizhiming
     */
    private void smoothScrollToPrePage() {
        if (currentPage > 0) {
            currentPage--;
            smoothScrollTo(viewList.get(currentPage)-10, 0);
        }
    }

    /**
     * 滑动到下一页
     * @author caizhiming
     */
    public void nextPage() {
        smoothScrollToNextPage();
    }

    /**
     * 滑动到上一页
     * @author caizhiming
     */
    public void prePage() {
        smoothScrollToPrePage();
    }

    /**
     * 跳转到指定的页面
     *
     * @param page
     * @author caizhiming
     */
    public boolean gotoPage(int page) {
        if (page > 0 && page < subChildCount - 1) {
            smoothScrollTo(viewList.get(page), 0);
            currentPage = page;
            return true;
        }
        return false;
    }

}

(2)UI配置文件xml中使用方法如下:

<com.czm.ui.view.AppHorizontalScrollView
            android:id="@+id/horizontalScrollView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:visibility="gone"
            android:scrollbars="none" >

            <LinearLayout
                android:id="@+id/llCoverList"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:padding="10dp"
                android:background="#DDDDDD"
                android:orientation="horizontal" >

            </LinearLayout>
        </com.czm.ui.view.AppHorizontalScrollView>

Android开发之自定义HorizontalScrollView视图实现仿ViewPager效果,布布扣,bubuko.com

时间: 2024-10-03 05:41:30

Android开发之自定义HorizontalScrollView视图实现仿ViewPager效果的相关文章

Android开发之自定义View-可动画展开收缩View的实现

有时候需要点击一个view可以动画展开和收缩折叠一个View这样的效果,这样就可以直接自定义View来实现. 本例中,采用继承FrameLayout来实现自定义的ExpandView.下面将详细介绍各个部分来实现该类以及如何使用该自定义视图. 效果图如下: 未展开效果: 正在向上折叠收缩中的效果: 已经展开效果: 自定义展开类:ExpandView的实现: package com.czm.customview; import android.content.Context; import and

Android开发之自定义Dialog二次打开报错问题解决

之前自定义了一个AlertDialog对话框,第一次点击时正常,但第二次调用时会出现错误:java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. 关于这个错误纠结了我好久,在网上百度了也不少,但感觉解决效果都达不到自己想要的效果.网上的解释说是一个子视图指定了多个父视图.由此可以推断出,在第二

Android开发之自定义TabHost文字及背景(源代码分享)

使用TabHost 可以在一个屏幕间进行不同版面的切换,而系统自带的tabhost界面较为朴素,我们应该如何进行自定义修改优化呢 MainActivity的源代码 package com.dream.ledong; import android.app.TabActivity; import android.content.Intent; import android.graphics.Color; import android.os.Bundle; import android.view.Gr

Android开发:自定义GridView/ListView数据源

http://mobile.51cto.com/android-259861.htm 在开发中,我们常常会遇到比较复杂的GridView/ListView的布局,重新实现BaseAdapter不但能帮助我们实现我们想要的布局效果,并且在绑定大数据量时也不会感觉有卡壳现象.记得以前用一个ListView直接去绑定手机内的联系人Cursor(一百多号人),滑动的时候就会有卡的感觉.今天决定写个Demo是因为在项目中可能会要实现这样的一个效果:一个GridView中绑定4个ImageButton,有些

Android开发之自定义Spinner样式的效果实现(源代码实现)

android系统自带的Spinner样式是远远满足不了我们实际开发过程中对Spinner UI风格的要求,因此我们肯定需要为了切合整个应用的风格,修改我们的Spinner样式.系统给我们提供了两种常见的修改方式,一个是用XML方式静态,另一个就是Java代码动态来修改啦,我们这篇文章呢主要就是介绍如何动态修改Spinner的样式.我的实现方法呢,是自己构造一个SpinnerAdapter,继承来自ArrayAdapter,重写getDropDownView(),getView()这两个方法就好

Eclipse rcp 开发 : 自定义导航视图CNF(3)为导航视图增加隐藏文件功能

org.eclipse.ui.navigator.navigatorContent 右键新增commonFilter id:  唯一 name :名称 如:*.xml resources description:描述, 如:Hides *.xml resources 在该属性下载增加属性:其中的value为通配xml  <filterExpression>             <and>                <adapt                     

Android UI之自定义——最简单的仿QQ音乐歌词颜色渐变

Android UI之自定义--最简单的仿QQ音乐歌词颜色渐变 记得刚开始做android的时候,就发现QQ音乐歌词颜色渐变的效果,就在网上搜索过,但是就是没有找到满意的.今天突然用QQ音乐听歌的时候,看到歌词颜色渐变,决定来分析看看,没想到实现原来如此简单.这篇只是将最简单的歌词颜色渐变功能,不包括歌词滚动等效果. 首先来看下QQ音乐歌词界面 实现步骤 从界面上可以看出,是通过不同颜色的文本叠加所形成的视觉效果.那么android文本一般使用TextView实现,那就来试试用TextView在

Android开发之自定义圆角矩形图片ImageView的实现

android中的ImageView只能显示矩形的图片,这样一来不能满足我们其他的需求,比如要显示圆角矩形的图片,这个时候,我们就需要自定义ImageView了,其原理就是首先获取到图片的Bitmap,然后进行裁剪对应的圆角矩形的bitmap,然后在onDraw()进行绘制圆角矩形图片输出. 效果图如下: 自定义的圆形的ImageView类的实现代码如下: package com.xc.xcskin.view; import android.content.Context; import and

Android开发之自定义圆形的ImageView的实现

android中的ImageView只能显示矩形的图片,这样一来不能满足我们其他的需求,比如要显示圆形的图片,这个时候,我们就需要自定义ImageView了,其原理就是首先获取到图片的Bitmap,然后进行裁剪圆形的bitmap,然后在onDraw()进行绘制圆形图片输出. 效果图如下: 自定义的圆形的ImageView类的实现代码如下: package com.xc.xcskin.view; import android.content.Context; import android.grap