Android图片管理工具 弹窗 保活 音乐播放器 自定义View 计步器 项目框架

android 画廊效果(中间大两边小)的无限轮播banner

2019-03-22  本文已影响0人  醉挽清风_666

android 画廊效果(中间大两边小)的无限轮播banner

ps: 项目要求做一个中间大两边小的轮播图,百度了一圈有了些灵感,分享一下心得,国际惯例先上效果图
banner.gif

废话不多说,直接上关键代码:

/**
 * Created by tf on 2018/12/21.
 */

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.WindowManager;
import android.view.animation.Interpolator;
import android.widget.Scroller;
import android.widget.TextView;

import com.hexin.cardservice.R;

import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

public class LoopViewPager extends ViewPager {

    OnPageChangeListener mOuterPageChangeListener;
    private LoopPagerAdapterWrapper mAdapter;

    private MyHandler mHandler;
    private final static int HANDLE_LOOP_MSG = 101;
    private AtomicBoolean isAutoLoop = new AtomicBoolean();

    public void setTxtPoints(List<TextView> txtPoints) {
        this.txtPoints = txtPoints;
    }

    private List<TextView> txtPoints;

    public void changePoints(int pos) {
        if (txtPoints != null) {
            for (int i = 0; i < txtPoints.size(); i++) {
                if (pos == i) {
                    txtPoints.get(i).setBackgroundResource(R.mipmap.home_yuan_sel);
                } else {
                    txtPoints.get(i).setBackgroundResource(R.mipmap.home_yuan);
                }
            }
        }
    }

    @Override
    public void setAdapter(PagerAdapter adapter) {
        mAdapter = new LoopPagerAdapterWrapper(adapter);
        super.setAdapter(mAdapter);
        isAutoLoop.set(false);
        setCurrentItem(0, false);
    }

    @Override
    public PagerAdapter getAdapter() {
        return mAdapter != null ? mAdapter.getRealAdapter() : mAdapter;
    }

    /**
     * 获取当前真实的item
     *
     * @return
     */
    public int getRealItem() {
        return mAdapter != null ? mAdapter.toRealPosition(super.getCurrentItem()) : 0;
    }

    public void setCurrentItem(int item, boolean smoothScroll) {
        int realItem = mAdapter.toInnerPosition(item);
        super.setCurrentItem(realItem, smoothScroll);
    }


    @Override
    public void setOnPageChangeListener(OnPageChangeListener listener) {
        mOuterPageChangeListener = listener;
    }

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

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

    private void init() {
        super.setOnPageChangeListener(onPageChangeListener);
        try {
            Field scrollerField = ViewPager.class.getDeclaredField("mScroller");
            scrollerField.setAccessible(true);
            Field interpolator = ViewPager.class.getDeclaredField("sInterpolator");
            interpolator.setAccessible(true);

            Scroller scroller = new Scroller(getContext(), (Interpolator) interpolator.get(null)) {
                @Override
                public void startScroll(int startX, int startY, int dx, int dy, int duration) {
                    //控制滑动速度
                    super.startScroll(startX, startY, dx, dy, (int) (1300 * (double) Math.abs(dx) / getWidth(getContext())));
                }
            };
            scrollerField.set(this, scroller);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void autoLoop(boolean isAuto) {
        if (mHandler == null) {
            mHandler = new MyHandler(getContext());
        }
        if (isAuto) {
            mHandler.sendEmptyMessageDelayed(HANDLE_LOOP_MSG, 3000);
        } else {
            mHandler.removeCallbacksAndMessages(null);
        }
        isAutoLoop.set(isAuto);
    }

    private OnPageChangeListener onPageChangeListener = new OnPageChangeListener() {
        private float mPreviousOffset = -1;
        private float mPreviousPosition = -1;

        @Override
        public void onPageSelected(int position) {

            int realPosition = mAdapter.toRealPosition(position);
            changePoints(realPosition);
            if (mPreviousPosition != realPosition) {
                mPreviousPosition = realPosition;
                if (mOuterPageChangeListener != null) {
                    mOuterPageChangeListener.onPageSelected(realPosition);
                }
            }
        }

        @Override
        public void onPageScrolled(int position, float positionOffset,
                                   int positionOffsetPixels) {
            int realPosition = position;
            if (mAdapter != null) {
                realPosition = mAdapter.toRealPosition(position);

                if (positionOffset == 0
                        && mPreviousOffset == 0
                        && (position == 0 || position == mAdapter.getCount() - 1)) {
                    setCurrentItem(realPosition, false);
                }
            }

            mPreviousOffset = positionOffset;
            if (mOuterPageChangeListener != null) {
                if (realPosition != mAdapter.getRealCount() - 1) {
                    mOuterPageChangeListener.onPageScrolled(realPosition,
                            positionOffset, positionOffsetPixels);
                } else {
                    if (positionOffset > .5) {
                        mOuterPageChangeListener.onPageScrolled(0, 0, 0);
                    } else {
                        mOuterPageChangeListener.onPageScrolled(realPosition,
                                0, 0);
                    }
                }
            }
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            switch (state) {
                case SCROLL_STATE_DRAGGING:
                    if (isAutoLoop.get()) {
                        mHandler.removeCallbacksAndMessages(null);
                    }
                    break;
                case SCROLL_STATE_IDLE:
                    if (isAutoLoop.get()) {
                        mHandler.sendEmptyMessageDelayed(HANDLE_LOOP_MSG, 3000);
                    }
                    break;
                case SCROLL_STATE_SETTLING:
                    break;
            }
            if (mOuterPageChangeListener != null) {
                mOuterPageChangeListener.onPageScrollStateChanged(state);
            }
        }
    };

//    @Override
//    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//
//        int height = 0;
//        for (int i = 0; i < getChildCount(); i++) {
//            View child = getChildAt(i);
//            child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
//            int h = child.getMeasuredHeight();
//            if (h > height)
//                height = h;
//        }
//        int width = 0;
//        for (int i = 0; i < getChildCount(); i++) {
//            View child = getChildAt(i);
//            child.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), heightMeasureSpec);
//            int h = child.getMeasuredWidth();
//            if (h > width)
//                width = h;
//        }
//
//        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
//        widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
//
//        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//    }

    private class MyHandler extends Handler {

        WeakReference<Context> mWeakReference;

        public MyHandler(Context context) {
            mWeakReference = new WeakReference<>(context);
        }

        @Override
        public void handleMessage(Message msg) {
            final Context context = mWeakReference.get();
            if (context == null) {
                return;
            }
            switch (msg.what) {
                case HANDLE_LOOP_MSG:
                    int curItem = getCurrentItem();
                    setCurrentItem(++curItem);
                    changePoints(curItem % txtPoints.size() );
                    break;
            }
        }
    }


    public int getWidth(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(outMetrics);
        return outMetrics.widthPixels;
    }
}

  package com.hexin.cardservice.ui.customView;

/**
 * Created by 15061 on 2018/12/21.
 */

import android.os.Parcelable;
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;

public class LoopPagerAdapterWrapper extends PagerAdapter {

    private PagerAdapter mAdapter;

    LoopPagerAdapterWrapper(PagerAdapter adapter) {
        this.mAdapter = adapter;
    }

    @Override
    public void notifyDataSetChanged() {
        super.notifyDataSetChanged();
    }

    public int toInnerPosition(int realPosition) {
        return realPosition + getCount() / 2  - getCount() % getRealCount();
    }

    int toRealPosition(int position) {
        return position % getRealCount();
    }

    @Override
    public int getCount() {
        return Integer.MAX_VALUE;
    }

    public int getRealCount() {
        return mAdapter.getCount();
    }

    public PagerAdapter getRealAdapter() {
        return mAdapter;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        int realPosition = position % getRealCount();
        return mAdapter.instantiateItem(container, realPosition);
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        int realPosition = position % getRealCount();
        mAdapter.destroyItem(container, realPosition, object);
    }

    @Override
    public void finishUpdate(ViewGroup container) {
        mAdapter.finishUpdate(container);
    }

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

    @Override
    public void restoreState(Parcelable bundle, ClassLoader classLoader) {
        mAdapter.restoreState(bundle, classLoader);
    }

    @Override
    public Parcelable saveState() {
        return mAdapter.saveState();
    }

    @Override
    public void startUpdate(ViewGroup container) {
        mAdapter.startUpdate(container);
    }

    @Override
    public void setPrimaryItem(ViewGroup container, int position, Object object) {
        mAdapter.setPrimaryItem(container, position, object);
    }
}

配置文件代码

<RelativeLayout
                android:id="@+id/relativelayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="15dp">

                <.LoopViewPager
                    android:id="@+id/myviewpager"
                    android:layout_width="match_parent"
                    android:layout_height="125dp" />
                <!-- 存放圆点 -->
                <LinearLayout
                    android:id="@+id/layout_dots"
                    android:layout_width="wrap_content"
                    android:layout_height="30dp"
                    android:layout_alignParentBottom="true"
                    android:layout_centerHorizontal="true"
                    android:gravity="center"
                    android:orientation="horizontal"/>
            </RelativeLayout>

MainActivity 应用

初始化ViewPager

private void initViewPager() {

        mViewpager = view.findViewById(R.id.myviewpager);
        //图片圆角处理
        for (int i = 0; i < mBannerArr.length; i++) {
            ImageView view1 = new ImageView(getContext());
            RoundedBitmapDrawable roundedBitmapDrawable = RoundedBitmapDrawableFactory.create(getResources(), BitmapFactory.decodeResource(getResources(), mBannerArr[i]));
            //view1.setImageResource(R.mipmap.pic);
            roundedBitmapDrawable.setCornerRadius(30);
            view1.setImageDrawable(roundedBitmapDrawable);
            mImageList.add(view1);
        }

        mViewpager.setClipChildren(false);
        DisplayMetrics dm = getResources().getDisplayMetrics();
        mViewpager.setPageMargin(-dm.widthPixels / 13);//设置viewpage之间的间距

        RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mViewpager.getLayoutParams();
        //高度根据图片进行适配(这里图片为750 *300)
        params.height = (int) (getResources().getDisplayMetrics().widthPixels * 330 / 750.0);
        params.width = getResources().getDisplayMetrics().widthPixels;
        mViewpager.setLayoutParams(params);
        mViewpager.setAdapter(new MyAdapter());
        mViewpager.setPageTransformer(true, new ViewPager.PageTransformer() {
            float scale = 0.85f;

            @Override
            public void transformPage(View page, float position) {
                if (position >= 0 && position <= 1) {
                    page.setScaleY(scale + (1 - scale) * (1 - position));
                } else if (position > -1 && position < 0) {
                    page.setScaleY(1 + (1 - scale) * position);
                } else {
                    page.setScaleY(scale);
                }
            }
        });
        mViewpager.autoLoop(true);
}

初始化指示器小圆点

/**
     * 初始化小圆点
     */
    private void initCircle() {
        mLayoutPoints = view.findViewById(R.id.layout_dots);
        mTxtPoints = new ArrayList<>();
        int d = DensityUtils.dp2px(mContext, 6);
        int m = 10;
        for (int i = 0; i < mImageList.size(); i++) {
            TextView txt = new TextView(getContext());
            if (i == 0) {
                txt.setBackgroundResource(R.mipmap.home_yuan_sel);
            } else {
                txt.setBackgroundResource(R.mipmap.home_yuan);
            }
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(d, d);
            params.setMargins(m, m, m, m);
            txt.setLayoutParams(params);
            mTxtPoints.add(txt);
            mLayoutPoints.addView(txt);
        }
        mViewpager.setTxtPoints(mTxtPoints);
    }

viewpager自定义适配器:

class MyAdapter extends PagerAdapter {

        @Override
        public int getCount() {
            return mImageList.size();
        }

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

        @Override
        public Object instantiateItem(ViewGroup container, final int position) {
            ImageView view = mImageList.get(position);
            ViewParent viewParent = view.getParent();
            if (viewParent == null) {
                container.addView(view);
            }

            view.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    log.d(TAG, "点击了第" + postion + "张图");
                }
            });
            return view;
        }

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

PS:这些就是轮播效果图了,希望对读者有帮助。。。

上一篇 下一篇

猜你喜欢

热点阅读