ViewPager-IconPageIndicator导航栏效果(增加点击切换)

来源:互联网 发布:新疆移动4g网络什么时候开通 编辑:程序博客网 时间:2024/05/18 23:13

ViewPagerIndicator地址:https://github.com/JakeWharton/ViewPagerIndicator
最近在使用PageIndicator的时候,用到IconPageIndicator,看效果图,感觉可以把icon那里做成导航栏啊,就可以代替平常使用的RadioGroup,感觉编码会简洁很多。
先把IconPageIndicator运行起来看看,效果还可以,有个缺点,不能点击icon切换page,查看了IconPageIndicator的源码,发现没有添加这个点击事件,可能作者没有这样设计把。只要在notifyDataSetChanged()的循环里添加点击监听事件就好了。
首先想到的是直接继承IconPageIndicator,然后扩展这个方法,可是实践才发现,layout变量是私有的,子类无法访问,而且作者自定义的IcsLinearLayout是包访问权限,别的包也是访问不到。继承扩展这个功能是不行了。
再想到的就是通过反射来实现,尝试了很久,实现不了,也可能自己对反射掌握不是太好。
没办法,只能想到笨办法了,直接copy IconPageIndicator源码,新建一个类,修改其notifyDataSetChanged方法。

修改好的IconPageIndicator源码,需要先配好ViewPagerIndicator。

import android.content.Context;import android.support.v4.view.PagerAdapter;import android.support.v4.view.ViewPager;import android.util.AttributeSet;import android.view.Gravity;import android.view.View;import android.widget.HorizontalScrollView;import android.widget.ImageView;import android.widget.LinearLayout;import com.viewpagerindicator.IconPagerAdapter;import com.viewpagerindicator.PageIndicator;/** * Created by blanke on 15-11-4. */public class SuperIconPageIndicator extends HorizontalScrollView implements PageIndicator {    private final LinearLayout mIconsLayout;    private ViewPager mViewPager;    private ViewPager.OnPageChangeListener mListener;    private Runnable mIconSelector;    private int mSelectedIndex;    public SuperIconPageIndicator(Context context) {        this(context, null);    }    public SuperIconPageIndicator(Context context, AttributeSet attrs) {        super(context, attrs);        setHorizontalScrollBarEnabled(false);        mIconsLayout = new LinearLayout(context);        addView(mIconsLayout, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT, Gravity.CENTER));    }    private void animateToIcon(final int position) {        final View iconView = mIconsLayout.getChildAt(position);        if (mIconSelector != null) {            removeCallbacks(mIconSelector);        }        mIconSelector = new Runnable() {            public void run() {                final int scrollPos = iconView.getLeft() - (getWidth() - iconView.getWidth()) / 2;                smoothScrollTo(scrollPos, 0);                mIconSelector = null;            }        };        post(mIconSelector);    }    @Override    public void onAttachedToWindow() {        super.onAttachedToWindow();        if (mIconSelector != null) {            // Re-post the selector we saved            post(mIconSelector);        }    }    @Override    public void onDetachedFromWindow() {        super.onDetachedFromWindow();        if (mIconSelector != null) {            removeCallbacks(mIconSelector);        }    }    @Override    public void onPageScrollStateChanged(int arg0) {        if (mListener != null) {            mListener.onPageScrollStateChanged(arg0);        }    }    @Override    public void onPageScrolled(int arg0, float arg1, int arg2) {        if (mListener != null) {            mListener.onPageScrolled(arg0, arg1, arg2);        }    }    @Override    public void onPageSelected(int arg0) {        setCurrentItem(arg0);        if (mListener != null) {            mListener.onPageSelected(arg0);        }    }    @Override    public void setViewPager(ViewPager view) {        if (mViewPager == view) {            return;        }        if (mViewPager != null) {            mViewPager.setOnPageChangeListener(null);        }        PagerAdapter adapter = view.getAdapter();        if (adapter == null) {            throw new IllegalStateException("ViewPager does not have adapter instance.");        }        mViewPager = view;        view.setOnPageChangeListener(this);        notifyDataSetChanged();    }    public void notifyDataSetChanged() {        mIconsLayout.removeAllViews();        IconPagerAdapter iconAdapter = (IconPagerAdapter) mViewPager.getAdapter();        int count = iconAdapter.getCount();        for (int i = 0; i < count; i++) {            ImageView view = new ImageView(getContext(), null, R.attr.vpiIconPageIndicatorStyle);            view.setImageResource(iconAdapter.getIconResId(i));            mIconsLayout.addView(view);            final int j = i;//主要修改的这里            view.setOnClickListener(new OnClickListener() {                @Override                public void onClick(View v) {                    setCurrentItem(j);                }            });        }        if (mSelectedIndex > count) {            mSelectedIndex = count - 1;        }        setCurrentItem(mSelectedIndex);        requestLayout();    }    @Override    public void setViewPager(ViewPager view, int initialPosition) {        setViewPager(view);        setCurrentItem(initialPosition);    }    @Override    public void setCurrentItem(int item) {        if (mViewPager == null) {            throw new IllegalStateException("ViewPager has not been bound.");        }        mSelectedIndex = item;        mViewPager.setCurrentItem(item);        int tabCount = mIconsLayout.getChildCount();        for (int i = 0; i < tabCount; i++) {            View child = mIconsLayout.getChildAt(i);            boolean isSelected = (i == item);            child.setSelected(isSelected);            if (isSelected) {                animateToIcon(item);            }        }    }    @Override    public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {        mListener = listener;    }}

修改icon间距:
在style下,theme的style标签下增加vpiIconPageIndicatorStyle的item,并在style的同级增加标签style name=”Widget.IconPageIndicator”

<item name="vpiIconPageIndicatorStyle">@style/Widget.IconPageIndicator</item><style name="Widget.IconPageIndicator" parent="Widget">        <item name="android:padding">20dp</item></style>

增加icon的选择效果:
adapter需要实现IconPagerAdapter接口,自定义getIconResId方法,
下面的mIcons里面就是每个icon,数组里直接传selector的Id,selector里需要配置的是android:state_selected,源码里面可以看出来。

private int mIcons[] = {R.drawable.ic_1, R.drawable.ic_2, R.drawable.ic_3}; class HomeAdapter extends FragmentPagerAdapter implements IconPagerAdapter {        public HomeAdapter(FragmentManager fm) {            super(fm);        }        @Override        public Fragment getItem(int position) {            switch (position) {                case 0:                    return new Fragment1();                case 1:                    return new Fragment2();                case 3:                    return new Fragment2();            }            return new Fragment1();        }        @Override        public int getIconResId(int index) {            return mIcons[index];        }        @Override        public int getCount() {            return mIcons.length;        }    }
0 0