Android 實現滾動圖片

這兩天有朋友在詢問滾動廣告怎麼實現,然後我對項目中的滾動功能代碼進行研究,因爲之前向前輩討論過這種無限滾動的原理。

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;
    }
}

一些代碼是借鑑前輩寫好的,然後自己讀懂了,就在這裏用上了。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章