轮播图中带粘性效果的小点

来源:互联网 发布:实时数据库软件有哪些 编辑:程序博客网 时间:2024/06/08 12:33

轮播图中我们经常会看到带有粘性效果的小点,先看效果图:


我们看顶部轮播图左右滑动时,其联动的小点也跟着一起滑动,但是这里的小点改变时会有粘性的效果。今天我们就看下这个效果。

小点的实现是通过自定义实现的,看下代码:

public class MaterialIndicator extends View implements ViewPager.OnPageChangeListener {    private static final String TAG = MaterialIndicator.class.getSimpleName();    private static final int UNDEFINED_PADDING = -1;    private final Interpolator interpolator = new FastOutSlowInInterpolator();    private final Paint indicatorPaint;    private final Paint selectedIndicatorPaint;    private final float indicatorRadius;    private final float indicatorPadding;    private final RectF selectorRect;    private int count;    private int selectedPage = 0;    private float deselectedAlpha = 0.2f;    private float offset;    public MaterialIndicator(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public MaterialIndicator(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        selectedIndicatorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);//被选中的指示点  //是使位图抗锯齿的标志        indicatorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);//指示点        indicatorPaint.setColor(Color.BLACK);//指示点的颜色        indicatorPaint.setAlpha((int) (deselectedAlpha * 255)); //指示点设置透明度        selectorRect = new RectF();        if (isInEditMode()) {            count = 3;        }        //获得我们所定义的自定义样式属性        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MaterialIndicator, 0, R.style.MaterialIndicator);        try {            //获取指示点半径            indicatorRadius = typedArray.getDimension(R.styleable.MaterialIndicator_mi_indicatorRadius, 0);            //获取指示点间距            indicatorPadding = typedArray.getDimension(R.styleable.MaterialIndicator_mi_indicatorPadding, UNDEFINED_PADDING);            //获取颜色,并赋值给被选中的            selectedIndicatorPaint.setColor(typedArray.getColor(R.styleable.MaterialIndicator_mi_indicatorColor, 0));        } finally {            typedArray.recycle();        }    }    @Override    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {        selectedPage = position;        offset = positionOffset;        invalidate();    }    @Override    public void onPageSelected(int position) {        selectedPage = position;        offset = 0;        invalidate();    }    @Override    public void onPageScrollStateChanged(int state) {    }    public void setAdapter(PagerAdapter adapter) {        this.count = adapter.getCount();        requestLayout();        invalidate();    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int width = getMeasuredWidth();        if (getLayoutParams().width == ViewPager.LayoutParams.WRAP_CONTENT) {            width = getSuggestedMinimumWidth();        }        setMeasuredDimension(width, getSuggestedMinimumHeight());    }    @Override    protected int getSuggestedMinimumWidth() {        return (int) (indicatorDiameter() * count + getInternalPadding());    }    private float getInternalPadding() {        if (indicatorPadding == UNDEFINED_PADDING || indicatorPadding == 0 || count == 0) {            return 0;        }        return indicatorPadding * (count - 1);    }    @Override    protected int getSuggestedMinimumHeight() {        return getPaddingTop() + getPaddingBottom() + (int) indicatorDiameter();    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        float gap = getGapBetweenIndicators();        for (int i = 0; i < count; i++) {            float position = indicatorStartX(gap, i);            canvas.drawCircle(position + indicatorRadius, midY(), indicatorRadius, indicatorPaint);        }        float extenderStart = indicatorStartX(gap, selectedPage) + Math.max(gap * (interpolatedOffset() - 0.5f) * 2, 0);        float extenderEnd = indicatorStartX(gap, selectedPage) + indicatorDiameter() + Math.min(gap * interpolatedOffset() * 2, gap);        selectorRect.set(extenderStart, midY() - indicatorRadius, extenderEnd, midY() + indicatorRadius);        canvas.drawRoundRect(selectorRect, indicatorRadius, indicatorRadius, selectedIndicatorPaint);    }    private float getGapBetweenIndicators() {        if (indicatorPadding == UNDEFINED_PADDING) {            return (getWidth() - indicatorDiameter()) / (count + 1);        } else {            return indicatorPadding;        }    }    private float indicatorStartX(float gap, int page) {        return ViewCompat.getPaddingStart(this) + gap * page + indicatorRadius;    }    private float interpolatedOffset() {        return interpolator.getInterpolation(offset);    }    private float indicatorDiameter() {        return indicatorRadius * 2;    }    private float midY() {        return getHeight() / 2f;    }}
主类:

public class MainActivity extends AppCompatActivity {    private ViewPager viewPager;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        viewPager = (ViewPager) findViewById(R.id.viewPager);        viewPager.setFocusable(true);        viewPager.setFocusableInTouchMode(true);        viewPager.requestFocus();        MaterialIndicator indicator = (MaterialIndicator) findViewById(R.id.indicator);        ViewPager viewPager = (ViewPager) findViewById(R.id.viewPager);        viewPager.setAdapter(new MyPagerAdapter());        viewPager.addOnPageChangeListener(indicator);        indicator.setAdapter(viewPager.getAdapter());    }    /**     * viewpager适配器     */    private class MyPagerAdapter extends PagerAdapter {        public int[] drawables = {R.drawable.banner1, R.drawable.banner2, R.drawable.banner3, R.drawable.banner4};        @Override        public int getCount() {            return 4;        }        @Override        public boolean isViewFromObject(View view, Object object) {            return object == view;        }        @Override        public Object instantiateItem(ViewGroup container, int position) {            ImageView view = new ImageView(container.getContext());            view.setImageResource(drawables[position]);            view.setScaleType(ImageView.ScaleType.FIT_XY);            container.addView(view);            return view;        }        @Override        public void destroyItem(ViewGroup container, int position, Object object) {            container.removeView(((View) object));        }    }}
activity_main.xml:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.zyqu.zz.viewpagerpoint.MainActivity">    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="vertical">        <android.support.v4.view.ViewPager            android:id="@+id/viewPager"            android:layout_width="match_parent"            android:layout_height="200dp" />        <com.zyqu.zz.viewpagerpoint.MaterialIndicator            android:id="@+id/indicator"            style="@style/MaterialIndicator.Demo"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center_horizontal"            android:paddingBottom="16dp"            android:paddingLeft="16dp"            android:paddingRight="16dp"            android:paddingTop="16dp" />    </LinearLayout></RelativeLayout>
styleable.xml:

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="MaterialIndicator">        <attr name="mi_indicatorRadius" format="dimension|reference" /> <!--半径-->        <attr name="mi_indicatorPadding" format="dimension|reference" /><!--间距-->        <attr name="mi_indicatorColor" format="color|reference" /><!--颜色-->    </declare-styleable></resources>
style.xml:

<resources>    <!-- Base application theme. -->    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">        <!-- Customize your theme here. -->        <!--<item name="colorPrimary">@color/colorPrimary</item>-->        <!--<item name="colorPrimaryDark">@color/colorPrimaryDark</item>-->        <!--<item name="colorAccent">@color/colorAccent</item>-->        <item name="android:windowActionBar">false</item>        <item name="windowActionBar">false</item>        <item name="windowNoTitle">true</item>    </style>    <style name="MaterialIndicator.Demo">        <item name="mi_indicatorColor">?android:attr/colorAccent</item>        <item name="mi_indicatorPadding">32dp</item> <!--指示点间距-->        <item name="mi_indicatorRadius">4dp</item><!--半径-->    </style>    <style name="MaterialIndicator">        <item name="mi_indicatorRadius">4dp</item><!--半径-->        <item name="mi_indicatorColor">#009688</item>  <!--指示点被选中的颜色-->    </style></resources>

csdn源码:http://download.csdn.net/detail/lijinweii/9871531

原创粉丝点击