Android 实现滚动图片

本文介绍如何在Android中实现滚动广告效果。通过创建一个伪无限的list,并在头部和尾部添加元素来实现无缝滚动。具体实现包括在列表最后一项后添加第一项,在第一项前添加最后一项,当滑动到附加元素时切换到实际的第一或最后一项。文中附带了简单的UI布局文件和代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这两天有朋友在询问滚动广告怎么实现,然后我对项目中的滚动功能代码进行研究,因为之前向前辈讨论过这种无限滚动的原理。

1.设置一个伪无限的list,将当前图标显示在中间然后进行无线滚动。

2.在头部和尾部加上图标,也就是说在最后一个后面加上第一个对象,在第一个之前加上之前的最后的一个对象,当滑到加上去的对象的时候就强制设置成第一个或者最后一个对象。

自己写了一个小demo,然后代码贴一下吧。

public class MainActivity extends Activity implements ViewPager.OnPageChangeListener{

    private List<ImageView> mViewList;
    private PageAdapter mAdapter;
    private CustomViewPager pageView;
    private LinearLayout _llPoints;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_list_header);
        pageView= (CustomViewPager)findViewById(R.id.vp_main_list_head);
        _llPoints = (LinearLayout) findViewById(R.id.ll_main_head_points);

        //数据展示
        mViewList=new ArrayList<ImageView>();
        int[] image=new int[]{R.drawable.android_guide_step_4,R.drawable.android_guide_step_1,R.drawable.android_guide_step_2,R.drawable.android_guide_step_3,R.drawable.android_guide_step_4,R.drawable.android_guide_step_1};
        for(int i=0;i<image.length;i++){
            ImageView imageView=new ImageView(this);
            imageView.setBackgroundResource(image[i]);
            mViewList.add(imageView);
        }
        mAdapter=new PageAdapter(mViewList,this);
        pageView.setAdapter(mAdapter);

        pageView.addOnPageChangeListener(this);
        Log.e("-------", mViewList.size() + "");
        setPoints(true);
    }

    private void setPoints(boolean isNew) {
        if (isNew){
            _llPoints.removeAllViews();
        }
        if (_llPoints.getChildCount() == 0) {
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(Util.dp2px(this,5), Util.dp2px(this,5));
            for (int i = 0; i < mViewList.size() - 2; i++) {//添加viewpager下方的点
                params.leftMargin = Util.dp2px(this,5);
                ImageView imageView = new ImageView(this);
                if (mViewList.size() - 3 == i) {
                    imageView.setImageResource(R.drawable.point_selected);
                } else {
                    imageView.setImageResource(R.drawable.point);
                }
                _llPoints.addView(imageView, params);
            }
        }
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(int position) {
        for (int i = 0; i < _llPoints.getChildCount(); i++) {
            ImageView imageView = (ImageView) _llPoints.getChildAt(i);
            imageView.setImageResource(R.drawable.point);
        }
        if (mViewList.size() != 0 && _llPoints.getChildCount() != 0) {
            int index = 0;
            index = pageView.getCurrentItem() % (mViewList.size() - 2) - 1;
            Log.e("----",""+pageView.getCurrentItem());
            if (index < 0) {
                index = mViewList.size() - 3;
            }
            ImageView imageView = (ImageView) _llPoints.getChildAt(index);
            if (imageView != null) {
                imageView.setImageResource(R.drawable.point_selected);
            }
        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {
        if (state == ViewPager.SCROLL_STATE_IDLE && pageView.getCurrentItem() == mViewList.size() - 1) {
            pageView.setCurrentItem(1, false);
        } else if (state == ViewPager.SCROLL_STATE_IDLE && pageView.getCurrentItem() == 0) {
            pageView.setCurrentItem(mViewList.size()-2, false);
        }
    }
}

界面UI布局文件

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

    <RelativeLayout
        android:id="@+id/rl_main_list_head"
        android:layout_width="match_parent"
        android:layout_height="240dp">
        <com.example.administrator.textpagescoll.CustomViewPager
            android:id="@+id/vp_main_list_head"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>


        <LinearLayout
            android:id="@+id/ll_main_head_points"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:orientation="horizontal"
            android:layout_marginBottom="10dp"/>

    </RelativeLayout>

</LinearLayout>
其他的一些代码。

public class CustomViewPager extends android.support.v4.view.ViewPager {

    public boolean _isScrolling;
    private HashMap<Integer, View> mChildrenViews = new LinkedHashMap<Integer, View>();
    private static final float SCALE_MAX = 0.5f;
    private final int ANIMATION_DURATION = 2000 + 1200;
    private Context _context;
    private Runnable _runnable;
    private Click _click;
    private boolean viewpagersroll = false;
    private float xDown;// 记录手指按下时的横坐标。
    private float xMove;// 记录手指移动时的横坐标。
    private float yDown;// 记录手指按下时的纵坐标。
    private float yMove;// 记录手指移动时的纵坐标。

    public CustomViewPager(Context context) {
        super(context);
        _context = context;
        init();
    }


    public CustomViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        _context = context;
        init();
    }

    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            int i = getCurrentItem() + 1;
//            SwitchLogger.e("tag", "自动翻页: " + i );
            CustomViewPagerScroller viewPagerScroller = new CustomViewPagerScroller(_context, new CustomViewPagerInterpolator());
            viewPagerScroller.initViewPagerScroll(CustomViewPager.this, 1200);
            setCurrentItem(i, true);
            handler.postDelayed(_runnable, ANIMATION_DURATION);
        }
    };

    public void setObjectForPosition(View view, int position) {
        mChildrenViews.put(position, view);
    }


    private void init() {
        _runnable = new Runnable() {
            @Override
            public void run() {
                handler.obtainMessage().sendToTarget();
            }
        };
        handler.postDelayed(_runnable, ANIMATION_DURATION);
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        Message msg;
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                handler.removeCallbacksAndMessages(null);
                if(!_isScrolling){
                    CustomViewPagerScroller viewPagerScroller = new CustomViewPagerScroller(_context, new CustomViewPagerInterpolator());
                    viewPagerScroller.initViewPagerScroll(CustomViewPager.this, 250);
                }
                break;
            case MotionEvent.ACTION_UP:
                handler.removeCallbacksAndMessages(null);
                handler.postDelayed(_runnable, ANIMATION_DURATION);
                break;
            case MotionEvent.ACTION_MOVE:
                handler.removeCallbacksAndMessages(null);
                break;
            case MotionEvent.ACTION_CANCEL:
                handler.removeCallbacksAndMessages(null);
                handler.postDelayed(_runnable, ANIMATION_DURATION);
                break;
            default:
                break;
        }
        return super.onTouchEvent(ev);
    }

    public interface Click {
        void onClick(int position);
    }

    public void setClick(Click click) {
        this._click = click;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                break;
        }
        return true;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            // 记录按下时的位置
            xDown = ev.getRawX();
            yDown = ev.getRawY();
        } else if (ev.getAction() == MotionEvent.ACTION_MOVE) {
            xMove = ev.getRawX();
            yMove = ev.getRawY();

            if (viewpagersroll) {
                // viewpager自己处理滑动效果
                getParent().requestDisallowInterceptTouchEvent(true);
                return super.dispatchTouchEvent(ev);
            }

            // 这里的动作判断是Viewpager滑动,ListView不滑动
            if (Math.abs(yMove - yDown) < 20 && Math.abs(xMove - xDown) > 20) {
                viewpagersroll = true;
            } else {
                // 由父容器listview来处理滑动效果
                return false;
            }

        } else if (ev.getAction() == MotionEvent.ACTION_UP) {
            viewpagersroll = false;
        }
        return super.dispatchTouchEvent(ev);
    }
}

public static int dp2px(Context context, float dpValue) {
    if (context == null){
        return 0;
    }
    final float scale = context.getResources().getDisplayMetrics().density;
    return (int) (dpValue * scale + 0.5f);
}

public class PageAdapter extends PagerAdapter {
    private Context mContext;
    private List<ImageView> mList;

    public PageAdapter(List<ImageView> list,Context context){
        this.mList=list;
        this.mContext=context;
    }

    @Override
    public Object instantiateItem(ViewGroup container,int position) {  //这个方法用来实例化页卡
        container.addView(mList.get(position));
        return mList.get(position);
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((View)object);
    }


    @Override
    public int getCount() {
        if (mList != null) {
            return mList.size();
        } else {
            return 0;
        }
    }
    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }
}

public class CustomViewPagerScroller extends Scroller {
    private int mScrollDuration = 1200;
    public CustomViewPagerScroller(Context context) {
        super(context);
    }

    public CustomViewPagerScroller(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, mScrollDuration);
    }

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



    public void initViewPagerScroll(android.support.v4.view.ViewPager viewPager,int duration) {
        try {
            mScrollDuration = duration;
            Field mScroller = ViewPager.class.getDeclaredField("mScroller");
            mScroller.setAccessible(true);
            mScroller.set(viewPager, this);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

}
public class CustomViewPagerInterpolator extends AccelerateDecelerateInterpolator {
    @Override
    public float getInterpolation(float input) {
        float first = (float) (0.6/Math.atan(0.4));
        float second = (float) (0.4/Math.atan(0.6));
        float secondFinal = first*(5.0f/3.0f-input*5.0f/3.0f)+(input-0.4f)*5.0f/3.0f*second;
        float scroll = (float) (input<0.4?Math.atan(input-0.4)*first+0.6:(Math.atan(input-0.4)*secondFinal+0.6));
        return scroll>1?1:scroll;
    }
}

一些代码是借鉴前辈写好的,然后自己读懂了,就在这里用上了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值