引导页指示器

来源:互联网 发布:面向接口编程事例 编辑:程序博客网 时间:2024/06/10 07:10

在Android应用开发过程中,通常在应用第一次启动时,都会有一个引导页。通常都是使用ViewPager实现的左右滑动,在里面都会有一个几个原点表示的标签指示器。

在自己开发应用中,经常会用到这种情况。 在开源库中已经有相应的实现。但是,在使用这些东西时,不得不将不用的东西包含进来 导致APP 包太大,不总令人满意。

自己参考launcher 中的实现 自己做了一个可以通用的组件。

PageIndicator.java 

import android.animation.LayoutTransition;import android.content.Context;import android.content.res.TypedArray;import android.util.AttributeSet;import android.view.LayoutInflater;import android.widget.LinearLayout;import java.util.ArrayList;public class PageIndicator extends LinearLayout {    @SuppressWarnings("unused")    private static final String TAG = "PageIndicator";    // Want this to look good? Keep it odd    private static final boolean MODULATE_ALPHA_ENABLED = false;    private LayoutInflater mLayoutInflater;    private int[] mWindowRange = new int[2];    private int mMaxWindowSize;    private ArrayList<PageIndicatorMarker> mMarkers =            new ArrayList<PageIndicatorMarker>();    private int mActiveMarkerIndex;    public static class PageMarkerResources {        int activeId;        int inactiveId;        public PageMarkerResources() {            activeId = R.drawable.ic_pageindicator_current;            inactiveId = R.drawable.ic_pageindicator_default;        }        public PageMarkerResources(int aId, int iaId) {            activeId = aId;            inactiveId = iaId;        }    }    public PageIndicator(Context context) {        this(context, null);    }    public PageIndicator(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public PageIndicator(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        TypedArray a = context.obtainStyledAttributes(attrs,                R.styleable.PageIndicator, defStyle, 0);        mMaxWindowSize = a.getInteger(R.styleable.PageIndicator_windowSize, 15);        mWindowRange[0] = 0;        mWindowRange[1] = 0;        mLayoutInflater = LayoutInflater.from(context);        a.recycle();        //Set the layout transition properties        LayoutTransition transition = getLayoutTransition();        if (transition != null) {            transition.setDuration(175);        }    }    private void enableLayoutTransitions() {        LayoutTransition transition = getLayoutTransition();        transition.enableTransitionType(LayoutTransition.APPEARING);        transition.enableTransitionType(LayoutTransition.DISAPPEARING);        transition.enableTransitionType(LayoutTransition.CHANGE_APPEARING);        transition.enableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);    }    private void disableLayoutTransitions() {        LayoutTransition transition = getLayoutTransition();        transition.disableTransitionType(LayoutTransition.APPEARING);        transition.disableTransitionType(LayoutTransition.DISAPPEARING);        transition.disableTransitionType(LayoutTransition.CHANGE_APPEARING);        transition.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);    }    void offsetWindowCenterTo(int activeIndex, boolean allowAnimations) {        if (activeIndex < 0) {            new Throwable().printStackTrace();        }        int windowSize = Math.min(mMarkers.size(), mMaxWindowSize);        int hWindowSize = (int) windowSize / 2;        float hfWindowSize = windowSize / 2f;        int windowStart = Math.max(0, activeIndex - hWindowSize);        int windowEnd = Math.min(mMarkers.size(), windowStart + mMaxWindowSize);        windowStart = windowEnd - Math.min(mMarkers.size(), windowSize);        int windowMid = windowStart + (windowEnd - windowStart) / 2;        boolean windowAtStart = (windowStart == 0);        boolean windowAtEnd = (windowEnd == mMarkers.size());        boolean windowMoved = (mWindowRange[0] != windowStart) ||                (mWindowRange[1] != windowEnd);        if (!allowAnimations) {            disableLayoutTransitions();        }        // Remove all the previous children that are no longer in the window        for (int i = getChildCount() - 1; i >= 0; --i) {            PageIndicatorMarker marker = (PageIndicatorMarker) getChildAt(i);            int markerIndex = mMarkers.indexOf(marker);            if (markerIndex < windowStart || markerIndex >= windowEnd) {                removeView(marker);            }        }        // Add all the new children that belong in the window        for (int i = 0; i < mMarkers.size(); ++i) {            PageIndicatorMarker marker = (PageIndicatorMarker) mMarkers.get(i);            if (windowStart <= i && i < windowEnd) {                if (indexOfChild(marker) < 0) {                    addView(marker, i - windowStart);                }                if (i == activeIndex) {                    marker.activate(windowMoved);                } else {                    marker.inactivate(windowMoved);                }            } else {                marker.inactivate(true);            }            if (MODULATE_ALPHA_ENABLED) {                // Update the marker's alpha                float alpha = 1f;                if (mMarkers.size() > windowSize) {                    if ((windowAtStart && i > hWindowSize) ||                            (windowAtEnd && i < (mMarkers.size() - hWindowSize)) ||                            (!windowAtStart && !windowAtEnd)) {                        alpha = 1f - Math.abs((i - windowMid) / hfWindowSize);                    }                }                marker.animate().alpha(alpha).setDuration(500).start();            }        }        if (!allowAnimations) {            enableLayoutTransitions();        }        mWindowRange[0] = windowStart;        mWindowRange[1] = windowEnd;    }    void addMarker(int index, PageMarkerResources marker, boolean allowAnimations) {        index = Math.max(0, Math.min(index, mMarkers.size()));        PageIndicatorMarker m =                (PageIndicatorMarker) mLayoutInflater.inflate(R.layout.page_indicator_marker,                        this, false);        m.setMarkerDrawables(marker.activeId, marker.inactiveId);        mMarkers.add(index, m);        offsetWindowCenterTo(mActiveMarkerIndex, allowAnimations);    }    void addMarkers(ArrayList<PageMarkerResources> markers, boolean allowAnimations) {        for (int i = 0; i < markers.size(); ++i) {            addMarker(Integer.MAX_VALUE, markers.get(i), allowAnimations);        }    }    void updateMarker(int index, PageMarkerResources marker) {        PageIndicatorMarker m = mMarkers.get(index);        m.setMarkerDrawables(marker.activeId, marker.inactiveId);    }    void removeMarker(int index, boolean allowAnimations) {        if (mMarkers.size() > 0) {            index = Math.max(0, Math.min(mMarkers.size() - 1, index));            mMarkers.remove(index);            offsetWindowCenterTo(mActiveMarkerIndex, allowAnimations);        }    }    void removeAllMarkers(boolean allowAnimations) {        while (mMarkers.size() > 0) {            removeMarker(Integer.MAX_VALUE, allowAnimations);        }    }    void setActiveMarker(int index) {        // Center the active marker        mActiveMarkerIndex = index;        offsetWindowCenterTo(index, false);    }    void dumpState(String txt) {        System.out.println(txt);        System.out.println("\tmMarkers: " + mMarkers.size());        for (int i = 0; i < mMarkers.size(); ++i) {            PageIndicatorMarker m = mMarkers.get(i);            System.out.println("\t\t(" + i + ") " + m);        }        System.out.println("\twindow: [" + mWindowRange[0] + ", " + mWindowRange[1] + "]");        System.out.println("\tchildren: " + getChildCount());        for (int i = 0; i < getChildCount(); ++i) {            PageIndicatorMarker m = (PageIndicatorMarker) getChildAt(i);            System.out.println("\t\t(" + i + ") " + m);        }        System.out.println("\tactive: " + mActiveMarkerIndex);    }        public synchronized int getMarksSize(){        return mMarkers.size();    }}

PageIndicatorMarker.java 

import android.content.Context;import android.content.res.Resources;import android.util.AttributeSet;import android.widget.ImageView;import android.widget.FrameLayout;public class PageIndicatorMarker extends FrameLayout {    @SuppressWarnings("unused")    private static final String TAG = "PageIndicator";    private static final int MARKER_FADE_DURATION = 175;    private ImageView mActiveMarker;    private ImageView mInactiveMarker;    private boolean mIsActive = false;    public PageIndicatorMarker(Context context) {        this(context, null);    }    public PageIndicatorMarker(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public PageIndicatorMarker(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);    }    protected void onFinishInflate() {        mActiveMarker = (ImageView) findViewById(R.id.active);        mInactiveMarker = (ImageView) findViewById(R.id.inactive);    }    void setMarkerDrawables(int activeResId, int inactiveResId) {        Resources r = getResources();        mActiveMarker.setImageDrawable(r.getDrawable(activeResId));        mInactiveMarker.setImageDrawable(r.getDrawable(inactiveResId));    }    void activate(boolean immediate) {        if (immediate) {            mActiveMarker.animate().cancel();            mActiveMarker.setAlpha(1f);            mActiveMarker.setScaleX(1f);            mActiveMarker.setScaleY(1f);            mInactiveMarker.animate().cancel();            mInactiveMarker.setAlpha(0f);        } else {            mActiveMarker.animate()                    .alpha(1f)                    .scaleX(1f)                    .scaleY(1f)                    .setDuration(MARKER_FADE_DURATION).start();            mInactiveMarker.animate()                    .alpha(0f)                    .setDuration(MARKER_FADE_DURATION).start();        }        mIsActive = true;    }    void inactivate(boolean immediate) {        if (immediate) {            mInactiveMarker.animate().cancel();            mInactiveMarker.setAlpha(1f);            mActiveMarker.animate().cancel();            mActiveMarker.setAlpha(0f);            mActiveMarker.setScaleX(0.5f);            mActiveMarker.setScaleY(0.5f);        } else {            mInactiveMarker.animate().alpha(1f)                    .setDuration(MARKER_FADE_DURATION).start();            mActiveMarker.animate()                    .alpha(0f)                    .scaleX(0.5f)                    .scaleY(0.5f)                    .setDuration(MARKER_FADE_DURATION).start();        }        mIsActive = false;    }    boolean isActive() {        return mIsActive;    }}


使用方式:

            在你的布局文件中 添加PageIndicator VIew即可。 在代码中使用 removeMarker addMarker 等来添加。

    <com.example.ddd.PageIndicator        android:id="@+id/pageIndicator1"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_gravity="center"        android:animateLayoutChanges="true"        android:gravity="center" >    </com.example.ddd.PageIndicator>

Demo :            http://download.csdn.net/detail/davyjoneswang/7298941


 


0 0