引导页指示器
来源:互联网 发布:面向接口编程事例 编辑:程序博客网 时间: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
- 引导页指示器
- 安卓引导页指示器实现
- App引导页的实现带圆点指示器
- 一个带指示器的引导页(ViewPager)
- 引导页圆点指示器
- 用ViewPager实现引导页,带页面指示器
- Android之ViewPager引导页(动态加载指示器)
- Android启动引导页及圆点指示器详解
- Android 引导页动态添加圆点指示器
- Android-实现引导页的圆点指示器
- 指示器
- 指示器
- 指示器
- Fragment + TabLayout (页签指示器)
- 引导页
- 引导页
- 引导页
- 引导页
- 利用taskset有效控制cpu资源
- 用VB6实现中英文文本的私钥加密——VB的另类用法
- 【存储管理】外部设备存储空间的地址映射
- 驱动程序的Makefile
- 网络流题集
- 引导页指示器
- Calf Flac-usaco
- svchost.exe占网速解决方法
- 解决实体机与虚拟机实现文件共享问…
- Linux下安装boa(嵌入式web服务器…
- 关闭microsoft office 2013上载中心
- boa服务器make错误[转载]
- 交叉编译工具链arm-linux-gcc-4.3.…
- Linux下安装sqlite3