写在前面
不知道大牛们怎么实现的,自己尝试鼓捣了几个方式,有的并不可取(源代码注释有说明),只作为知识点掌握吧。
本次之所以用Android 5.0开发完成是因为有一个很好的demo(github上)是建立在此基础上的,不过你可以稍微修改就能向下兼容,我做了注释,我集成在本Demo中是倒数第二个。由于是整合,里面的资源文件自然都写在一起了,如果想分离某一种实现方式还请看懂Demo逐一分离,根据Demo分离所依赖的资源。另外,没有加入内部存储,不过包含了这个工具类,为了演示效果没有往具体功能里面添加相关判断是不是首次引导的代码,这个在跳转成功的那个连接或者按钮提示处添加就行啦,比较简单。
简单解释

单独拿出了主文件和跳转成功页面,每个包是一种实现方式,里面有包含Activity。这是src

布局中activity_是上面说的单独拿出的两个activity,layout_都是分别实现的布局文件,shade_是倒数第二种大牛实现的方式的activity。这是布局。

关于资源文件分离要慎重,这是res,慎重哟~ 就是这样
实现说明
1. Splash实现方式
说白了就是利用Handler的延迟功能,核心代码如下:
-
-
-
-
- private void splashShow() {
- AnimationUtil.activityZoomAnimation(this);
- new Handler().postDelayed(new Runnable() {
-
- @Override
- public void run() {
- startActivity(new Intent(SplashActivity.this, SuessedActivity.class));
- AnimationUtil.finishActivityAnimation(SplashActivity.this);
- }
- }, Constant.DELAY);
- }
2.3. ViewPage实现
借助V4包下的ViewPage组件实现,这里实现两种方式,第二种是仿知乎的。核心是
- private void pageGuide() {
- ImageView imageView = null;
- guides.clear();
-
- for (int i = 0; i < ids.length; i++) {
- imageView = creatImageView(ids[i]);
- guides.add(imageView);
- }
-
-
- mCurDotImageView.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() {
-
- @Override
- public boolean onPreDraw() {
- offset = mCurDotImageView.getWidth();
- return true;
- }
- });
-
- myGuidePageAdapter = new MyGuidePageAdapter(guides);
- mViewPager.setAdapter(myGuidePageAdapter);
- mViewPager.clearAnimation();
-
- mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){
- @Override
- public void onPageSelected(int position) {
- int pos = position % ids.length;
-
- moveCursorTo(pos);
-
- if (pos == ids.length-1) {
- handler.sendEmptyMessageDelayed(TO_THE_END, 500);
- } else if (curPos == ids.length - 1) {
- handler.sendEmptyMessageDelayed(LEAVE_FROM_END, 100);
- }
- curPos = pos;
- super.onPageSelected(position);
- }
-
- });
- }
- private void moveCursorTo(int pos) {
- AnimationSet animationSet = new AnimationSet(true);
- TranslateAnimation tAnim =
- new TranslateAnimation(offset * curPos, offset * pos, 0, 0);
- animationSet.addAnimation(tAnim);
- animationSet.setDuration(300);
- animationSet.setFillAfter(true);
- mCurDotImageView.startAnimation(animationSet);
- }
-
- private ImageView creatImageView(int id){
- ImageView iv = new ImageView(this);
- iv.setImageResource(id);
- ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.MATCH_PARENT);
- iv.setLayoutParams(params);
- iv.setScaleType(ScaleType.FIT_XY);
- return iv;
- }
4. ScrollView实现上下的滑动,仿赶集网,重写了ScrollView,根据滑动的高度显示布局,核心:
- public void onScrollChanged(int top, int oldTop) {
- int animTop = mLinearLayout.getTop() - top;
- if (top > oldTop) {
- if (animTop < mStartAnimateTop && !hasStart) {
- Animation anim = AnimationUtils
- .loadAnimation(this, R.anim.show);
- mLinearLayout.setVisibility(View.VISIBLE);
- mLinearLayout.startAnimation(anim);
- hasStart = true;
- }
- } else {
- if (animTop > mStartAnimateTop && hasStart) {
- Animation anim = AnimationUtils.loadAnimation(this,
- R.anim.close);
- mLinearLayout.setVisibility(View.INVISIBLE);
- mLinearLayout.startAnimation(anim);
- hasStart = false;
- }
- }
- }
5. 用美工的图片进行遮罩,好笨的方式,很简单实现,主要是布局,控制显示和不显示。
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical" >
-
- <TextView
- android:id="@+id/tv"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerInParent="true"
- android:text="我是新功能"/>
- <RelativeLayout
- android:id="@+id/tip_rl"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/g_tips">
-
- </RelativeLayout>
- </RelativeLayout>
6. WindowManager实现【
不推荐使用】
因为它是系统级别的Window,是整个OS唯一的Window,所以出现引导按home键会有问题,可以利用它实现悬浮框,比如360的小球。核心如下,通过addView(),removeView();实现
- private void initParam() {
- params = new LayoutParams();
-
- params.type = LayoutParams.TYPE_SYSTEM_ALERT;
-
- params.flags = LayoutParams.FLAG_ALT_FOCUSABLE_IM;
-
-
- params.format = PixelFormat.TRANSLUCENT;
- params.width = LayoutParams.MATCH_PARENT;
- params.height = LayoutParams.MATCH_PARENT;
- }
-
-
-
-
-
-
- public void display(int layoutId) {
- initParam();
- final View view = LayoutInflater.from(context).inflate(layoutId, null);
-
- mWindowManager.addView(view, params);
- view.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- if (view.getParent() != null) {
- mWindowManager.removeView(view);
- }
-
- }
- });
7. getWindow().getDecorView()实现,这个呢和上一种方式区别就是获取的是当前布局的根View,利用FramLayout的特性实现的,通过用户传入几张遮罩图就分多少部遮罩显示实现连贯性,当然传入一个就遮罩步骤一个呗:
- public void display() {
- ViewParent viewParent = rootView.getParent();
-
- if (viewParent instanceof FrameLayout) {
- if (length > 0 && current < length) {
- final FrameLayout container = (FrameLayout) viewParent;
- final ImageView imageView = new ImageView(activity);
- imageView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
- imageView.setBackgroundResource(coverIds[current]);
- imageView.setScaleType(ScaleType.FIT_XY);
- imageView.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- container.removeView(imageView);
- handler.sendEmptyMessage(CONTINUE);
- }
- });
- current ++ ;
- container.addView(imageView);
- }
- }
- }
8. popubwindow实现,这个是采用它里面的SetContentView(View)实现的:
- @SuppressWarnings("deprecation")
- public void init(int layoutId) {
- View view = LayoutInflater.from(context).inflate(layoutId, null);
- this.setOutsideTouchable(true);
- this.setBackgroundDrawable(new BitmapDrawable());
- this.setHeight(LayoutParams.MATCH_PARENT);
- this.setWidth(LayoutParams.MATCH_PARENT);
- this.setFocusable(true);
- this.setContentView(view);
- this.setAnimationStyle(R.style.dialog_animation);
- view.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View v) {
- popuWindowHelper.dismiss();
- }
- });
-
- }
9. 自定义View实现【大牛】,值得推荐
其核心就是自定义一个View并添加点击事件监听,为了做到连贯性,采用一个suquence队列显示需要引导的item,用这个队列管理引导步骤,如果是单纯的一个指示的话就用不到该队列了。。
- package com.lzy.shadeguide.child.shade.way_three.thrid_lib;
-
- import android.annotation.SuppressLint;
- import android.annotation.TargetApi;
- import android.app.Activity;
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.graphics.Point;
- import android.graphics.PorterDuff;
- import android.graphics.PorterDuffXfermode;
- import android.graphics.Rect;
- import android.os.Build;
- import android.os.Handler;
- import android.text.TextUtils;
- import android.util.AttributeSet;
- import android.util.DisplayMetrics;
- import android.view.Gravity;
- import android.view.LayoutInflater;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.ViewGroup;
- import android.view.ViewTreeObserver;
- import android.widget.FrameLayout;
- import android.widget.TextView;
-
- import java.util.ArrayList;
- import java.util.List;
-
- import com.lzy.shadeguide.R;
- import com.lzy.shadeguide.child.shade.way_three.thrid_lib.shape.CircleShape;
- import com.lzy.shadeguide.child.shade.way_three.thrid_lib.shape.NoShape;
- import com.lzy.shadeguide.child.shade.way_three.thrid_lib.shape.RectangleShape;
- import com.lzy.shadeguide.child.shade.way_three.thrid_lib.shape.Shape;
- import com.lzy.shadeguide.child.shade.way_three.thrid_lib.target.Target;
- import com.lzy.shadeguide.child.shade.way_three.thrid_lib.target.ViewTarget;
-
-
-
-
-
- public class MaterialShowcaseView extends FrameLayout implements View.OnTouchListener, View.OnClickListener {
-
- private int mOldHeight;
- private int mOldWidth;
- private Bitmap mBitmap;
- private Canvas mCanvas;
- private Paint mEraser;
- private Target mTarget;
- private Shape mShape;
- private int mXPosition;
- private int mYPosition;
- private boolean mWasDismissed = false;
- private int mShapePadding = ShowcaseConfig.DEFAULT_SHAPE_PADDING;
-
- private View mContentBox;
- private TextView mContentTextView;
- private TextView mDismissButton;
- private int mGravity;
- private int mContentBottomMargin;
- private int mContentTopMargin;
- private boolean mDismissOnTouch = false;
- private boolean mShouldRender = false;
- private int mMaskColour;
- private AnimationFactory mAnimationFactory;
- private boolean mShouldAnimate = true;
- private long mFadeDurationInMillis = ShowcaseConfig.DEFAULT_FADE_TIME;
- private Handler mHandler;
- private long mDelayInMillis = ShowcaseConfig.DEFAULT_DELAY;
- private int mBottomMargin = 0;
- private boolean mSingleUse = false;
- private PrefsManager mPrefsManager;
- List<IShowcaseListener> mListeners;
- private UpdateOnGlobalLayout mLayoutListener;
- private IDetachedListener mDetachedListener;
-
- public MaterialShowcaseView(Context context) {
- super(context);
- init(context);
- }
-
- public MaterialShowcaseView(Context context, AttributeSet attrs) {
- super(context, attrs);
- init(context);
- }
-
- public MaterialShowcaseView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- init(context);
- }
-
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- public MaterialShowcaseView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
- init(context);
- }
-
-
- private void init(Context context) {
- setWillNotDraw(false);
-
-
- mAnimationFactory = new AnimationFactory();
-
- mListeners = new ArrayList<IShowcaseListener>();
-
-
- mLayoutListener = new UpdateOnGlobalLayout();
- getViewTreeObserver().addOnGlobalLayoutListener(mLayoutListener);
-
-
- setOnTouchListener(this);
-
- mMaskColour = Color.parseColor(ShowcaseConfig.DEFAULT_MASK_COLOUR);
- setVisibility(INVISIBLE);
-
-
- View contentView = LayoutInflater.from(getContext()).inflate(R.layout.shade_showcase_content, this, true);
- mContentBox = contentView.findViewById(R.id.content_box);
- mContentTextView = (TextView) contentView.findViewById(R.id.tv_content);
- mDismissButton = (TextView) contentView.findViewById(R.id.tv_dismiss);
- mDismissButton.setOnClickListener(this);
- }
-
-
-
-
-
-
-
-
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
-
-
- if (!mShouldRender) return;
-
-
- int width = getMeasuredWidth();
- int height = getMeasuredHeight();
-
-
- if (mBitmap == null || mCanvas == null || mOldHeight != height || mOldWidth != width) {
-
- if (mBitmap != null) mBitmap.recycle();
-
- mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-
-
- mCanvas = new Canvas(mBitmap);
- }
-
-
- mOldWidth = width;
- mOldHeight = height;
-
-
- mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
-
-
- mCanvas.drawColor(mMaskColour);
-
-
- if (mEraser == null) {
- mEraser = new Paint();
- mEraser.setColor(0xFFFFFFFF);
- mEraser.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
- mEraser.setFlags(Paint.ANTI_ALIAS_FLAG);
- }
-
-
- mShape.draw(mCanvas, mEraser, mXPosition, mYPosition, mShapePadding);
-
-
- canvas.drawBitmap(mBitmap, 0, 0, null);
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
-
-
-
-
-
-
- if (!mWasDismissed && mSingleUse && mPrefsManager != null) {
- mPrefsManager.resetShowcase();
- }
-
-
- notifyOnDismissed();
-
- }
-
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- if (mDismissOnTouch) {
- hide();
- }
- return true;
- }
-
-
- private void notifyOnDisplayed() {
- for (IShowcaseListener listener : mListeners) {
- listener.onShowcaseDisplayed(this);
- }
- }
-
- private void notifyOnDismissed() {
- if (mListeners != null) {
- for (IShowcaseListener listener : mListeners) {
- listener.onShowcaseDismissed(this);
- }
-
- mListeners.clear();
- mListeners = null;
- }
-
-
-
-
- if (mDetachedListener != null) {
- mDetachedListener.onShowcaseDetached(this, mWasDismissed);
- }
- }
-
-
-
-
-
-
- @Override
- public void onClick(View v) {
- hide();
- }
-
-
-
-
-
-
-
-
- public void setTarget(Target target) {
- mTarget = target;
-
-
- updateDismissButton();
-
- if (mTarget != null) {
-
-
-
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- mBottomMargin = getSoftButtonsBarSizePort((Activity) getContext());
- FrameLayout.LayoutParams contentLP = (LayoutParams) getLayoutParams();
-
- if (contentLP != null && contentLP.bottomMargin != mBottomMargin)
- contentLP.bottomMargin = mBottomMargin;
- }
-
-
- Point targetPoint = mTarget.getPoint();
- Rect targetBounds = mTarget.getBounds();
- setPosition(targetPoint);
-
-
- int height = getMeasuredHeight();
- int midPoint = height / 2;
- int yPos = targetPoint.y;
-
- int radius = Math.max(targetBounds.height(), targetBounds.width()) / 2;
- if (mShape != null) {
- mShape.updateTarget(mTarget);
- radius = mShape.getHeight() / 2;
- }
-
- if (yPos > midPoint) {
-
- mContentTopMargin = 0;
- mContentBottomMargin = (height - yPos) + radius + mShapePadding;
- mGravity = Gravity.BOTTOM;
- } else {
-
- mContentTopMargin = yPos + radius + mShapePadding;
- mContentBottomMargin = 0;
- mGravity = Gravity.TOP;
- }
- }
-
- applyLayoutParams();
- }
-
- private void applyLayoutParams() {
-
- if (mContentBox != null && mContentBox.getLayoutParams() != null) {
- FrameLayout.LayoutParams contentLP = (LayoutParams) mContentBox.getLayoutParams();
-
- boolean layoutParamsChanged = false;
-
- if (contentLP.bottomMargin != mContentBottomMargin) {
- contentLP.bottomMargin = mContentBottomMargin;
- layoutParamsChanged = true;
- }
-
- if (contentLP.topMargin != mContentTopMargin) {
- contentLP.topMargin = mContentTopMargin;
- layoutParamsChanged = true;
- }
-
- if (contentLP.gravity != mGravity) {
- contentLP.gravity = mGravity;
- layoutParamsChanged = true;
- }
-
-
-
-
- if (layoutParamsChanged)
- mContentBox.setLayoutParams(contentLP);
- }
- }
-
-
-
-
-
- void setPosition(Point point) {
- setPosition(point.x, point.y);
- }
-
- void setPosition(int x, int y) {
- mXPosition = x;
- mYPosition = y;
- }
-
- private void setContentText(CharSequence contentText) {
- if (mContentTextView != null) {
- mContentTextView.setText(contentText);
- }
- }
-
- private void setDismissText(CharSequence dismissText) {
- if (mDismissButton != null) {
- mDismissButton.setText(dismissText);
-
- updateDismissButton();
- }
- }
-
- private void setContentTextColor(int textColour) {
- if (mContentTextView != null) {
- mContentTextView.setTextColor(textColour);
- }
- }
-
- private void setDismissTextColor(int textColour) {
- if (mDismissButton != null) {
- mDismissButton.setTextColor(textColour);
- }
- }
-
- private void setShapePadding(int padding) {
- mShapePadding = padding;
- }
-
- private void setDismissOnTouch(boolean dismissOnTouch) {
- mDismissOnTouch = dismissOnTouch;
- }
-
- private void setShouldRender(boolean shouldRender) {
- mShouldRender = shouldRender;
- }
-
- private void setMaskColour(int maskColour) {
- mMaskColour = maskColour;
- }
-
- private void setDelay(long delayInMillis) {
- mDelayInMillis = delayInMillis;
- }
-
- private void setFadeDuration(long fadeDurationInMillis) {
- mFadeDurationInMillis = fadeDurationInMillis;
- }
-
- public void addShowcaseListener(IShowcaseListener showcaseListener) {
- mListeners.add(showcaseListener);
- }
-
- public void removeShowcaseListener(MaterialShowcaseSequence showcaseListener) {
- if (mListeners.contains(showcaseListener)) {
- mListeners.remove(showcaseListener);
- }
- }
-
- void setDetachedListener(IDetachedListener detachedListener) {
- mDetachedListener = detachedListener;
- }
-
- public void setShape(Shape mShape) {
- this.mShape = mShape;
- }
-
-
-
-
-
-
- public void setConfig(ShowcaseConfig config) {
- setDelay(config.getDelay());
- setFadeDuration(config.getFadeDuration());
- setContentTextColor(config.getContentTextColor());
- setDismissTextColor(config.getDismissTextColor());
- setMaskColour(config.getMaskColor());
- setShape(config.getShape());
- setShapePadding(config.getShapePadding());
- }
-
- private void updateDismissButton() {
-
- if (mDismissButton != null) {
- if (TextUtils.isEmpty(mDismissButton.getText())) {
- mDismissButton.setVisibility(GONE);
- } else {
- mDismissButton.setVisibility(VISIBLE);
- }
- }
- }
-
- public boolean hasFired() {
- return mPrefsManager.hasFired();
- }
-
-
-
-
- private class UpdateOnGlobalLayout implements ViewTreeObserver.OnGlobalLayoutListener {
-
- @Override
- public void onGlobalLayout() {
- setTarget(mTarget);
- }
- }
-
-
-
-
-
-
- public static class Builder {
- private static final int CIRCLE_SHAPE = 0;
- private static final int RECTANGLE_SHAPE = 1;
- private static final int NO_SHAPE = 2;
-
- private boolean fullWidth = false;
- private int shapeType = CIRCLE_SHAPE;
-
- final MaterialShowcaseView showcaseView;
-
- private final Activity activity;
-
- public Builder(Activity activity) {
- this.activity = activity;
-
- showcaseView = new MaterialShowcaseView(activity);
- }
-
-
-
-
- public Builder setTarget(View target) {
- showcaseView.setTarget(new ViewTarget(target));
- return this;
- }
-
-
-
-
- public Builder setDismissText(int resId) {
- return setDismissText(activity.getString(resId));
- }
-
- public Builder setDismissText(CharSequence dismissText) {
- showcaseView.setDismissText(dismissText);
- return this;
- }
-
-
-
-
- public Builder setContentText(int resId) {
- return setContentText(activity.getString(resId));
- }
-
-
-
-
- public Builder setContentText(CharSequence text) {
- showcaseView.setContentText(text);
- return this;
- }
-
-
- public Builder setDismissOnTouch(boolean dismissOnTouch) {
- showcaseView.setDismissOnTouch(dismissOnTouch);
- return this;
- }
-
- public Builder setMaskColour(int maskColour) {
- showcaseView.setMaskColour(maskColour);
- return this;
- }
-
- public Builder setContentTextColor(int textColour) {
- showcaseView.setContentTextColor(textColour);
- return this;
- }
-
- public Builder setDismissTextColor(int textColour) {
- showcaseView.setDismissTextColor(textColour);
- return this;
- }
-
- public Builder setDelay(int delayInMillis) {
- showcaseView.setDelay(delayInMillis);
- return this;
- }
-
- public Builder setFadeDuration(int fadeDurationInMillis) {
- showcaseView.setFadeDuration(fadeDurationInMillis);
- return this;
- }
-
- public Builder setListener(IShowcaseListener listener) {
- showcaseView.addShowcaseListener(listener);
- return this;
- }
-
- public Builder singleUse(String showcaseID) {
- showcaseView.singleUse(showcaseID);
- return this;
- }
-
- public Builder setShape(Shape shape) {
- showcaseView.setShape(shape);
- return this;
- }
-
- public Builder withCircleShape() {
- shapeType = CIRCLE_SHAPE;
- return this;
- }
-
- public Builder withoutShape() {
- shapeType = NO_SHAPE;
- return this;
- }
-
- public Builder setShapePadding(int padding) {
- showcaseView.setShapePadding(padding);
- return this;
- }
-
- public Builder withRectangleShape() {
- return withRectangleShape(false);
- }
-
- public Builder withRectangleShape(boolean fullWidth) {
- this.shapeType = RECTANGLE_SHAPE;
- this.fullWidth = fullWidth;
- return this;
- }
-
- public MaterialShowcaseView build() {
- if (showcaseView.mShape == null) {
- switch (shapeType) {
- case RECTANGLE_SHAPE: {
- showcaseView.setShape(new RectangleShape(showcaseView.mTarget.getBounds(), fullWidth));
- break;
- }
- case CIRCLE_SHAPE: {
- showcaseView.setShape(new CircleShape(showcaseView.mTarget));
- break;
- }
- case NO_SHAPE: {
- showcaseView.setShape(new NoShape());
- break;
- }
- default:
- throw new IllegalArgumentException("Unsupported shape type: " + shapeType);
- }
- }
-
- return showcaseView;
- }
-
- public MaterialShowcaseView show() {
- build().show(activity);
- return showcaseView;
- }
-
- }
-
- private void singleUse(String showcaseID) {
- mSingleUse = true;
- mPrefsManager = new PrefsManager(getContext(), showcaseID);
- }
-
- @SuppressWarnings("deprecation")
- public void removeFromWindow() {
- if (getParent() != null && getParent() instanceof ViewGroup) {
- ((ViewGroup) getParent()).removeView(this);
- }
-
- if (mBitmap != null) {
- mBitmap.recycle();
- mBitmap = null;
- }
-
- mEraser = null;
- mAnimationFactory = null;
- mCanvas = null;
- mHandler = null;
-
- getViewTreeObserver().removeGlobalOnLayoutListener(mLayoutListener);
- mLayoutListener = null;
-
- if (mPrefsManager != null)
- mPrefsManager.close();
-
- mPrefsManager = null;
-
-
- }
-
-
-
-
-
-
-
-
- public boolean show(final Activity activity) {
-
-
-
-
- if (mSingleUse) {
- if (mPrefsManager.hasFired()) {
- return false;
- } else {
- mPrefsManager.setFired();
- }
- }
-
- ((ViewGroup) activity.getWindow().getDecorView()).addView(this);
-
- setShouldRender(true);
-
- mHandler = new Handler();
- mHandler.postDelayed(new Runnable() {
- @Override
- public void run() {
-
- if (mShouldAnimate) {
- fadeIn();
- } else {
- setVisibility(VISIBLE);
- notifyOnDisplayed();
- }
- }
- }, mDelayInMillis);
-
- updateDismissButton();
-
- return true;
- }
-
-
- public void hide() {
-
-
-
-
- mWasDismissed = true;
-
- if (mShouldAnimate) {
- fadeOut();
- } else {
- removeFromWindow();
- }
- }
-
- public void fadeIn() {
- setVisibility(INVISIBLE);
-
- mAnimationFactory.fadeInView(this, mFadeDurationInMillis,
- new IAnimationFactory.AnimationStartListener() {
- @Override
- public void onAnimationStart() {
- setVisibility(View.VISIBLE);
- notifyOnDisplayed();
- }
- }
- );
- }
-
- public void fadeOut() {
-
- mAnimationFactory.fadeOutView(this, mFadeDurationInMillis, new IAnimationFactory.AnimationEndListener() {
- @Override
- public void onAnimationEnd() {
- setVisibility(INVISIBLE);
- removeFromWindow();
- }
- });
- }
-
- public void resetSingleUse() {
- if (mSingleUse && mPrefsManager != null) mPrefsManager.resetShowcase();
- }
-
-
-
-
-
-
-
- public static void resetSingleUse(Context context, String showcaseID) {
- PrefsManager.resetShowcase(context, showcaseID);
- }
-
-
-
-
-
-
- public static void resetAll(Context context) {
- PrefsManager.resetAll(context);
- }
-
- @SuppressLint("NewApi")
- public static int getSoftButtonsBarSizePort(Activity activity) {
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
- DisplayMetrics metrics = new DisplayMetrics();
- activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
- int usableHeight = metrics.heightPixels;
- activity.getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
- int realHeight = metrics.heightPixels;
- if (realHeight > usableHeight)
- return realHeight - usableHeight;
- else
- return 0;
- }
- return 0;
- }
-
- }
队列管理:
10. 如今很流行的WebView方式实现,里面可以嵌入H5更炫丽的实现方式,很简单就是利用webview的loadUrl()方法。当然,我这里实现了两种方式,里面用回调来处理页面点击交互,使用方式就是实现OnOpenListener接口:
- @SuppressLint("SetJavaScriptEnabled")
- private void init_() {
- mWebSettings.setJavaScriptEnabled(true);
- }
-
- @SuppressWarnings("deprecation")
- @SuppressLint({ "SetJavaScriptEnabled", "NewApi" })
- private void init() {
- mWebSettings.setJavaScriptCanOpenWindowsAutomatically(true);
- mWebSettings.setUseWideViewPort(true);
-
-
-
-
-
- mWebSettings.setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
-
- mWebSettings.setDisplayZoomControls(false);
- mWebSettings.setJavaScriptEnabled(true);
- mWebSettings.setAllowFileAccess(true);
- mWebSettings.setBuiltInZoomControls(true);
- mWebSettings.setSupportZoom(false);
-
- mWebSettings.setLoadWithOverviewMode(true);
-
- DisplayMetrics metrics = new DisplayMetrics();
- ((Activity)context).getWindowManager().getDefaultDisplay().getMetrics(metrics);
- int mDensity = metrics.densityDpi;
- if (mDensity == 240) {
- mWebSettings.setDefaultZoom(ZoomDensity.FAR);
- } else if (mDensity == 160) {
- mWebSettings.setDefaultZoom(ZoomDensity.MEDIUM);
- } else if(mDensity == 120) {
- mWebSettings.setDefaultZoom(ZoomDensity.CLOSE);
- }else if(mDensity == DisplayMetrics.DENSITY_XHIGH){
- mWebSettings.setDefaultZoom(ZoomDensity.FAR);
- }else if (mDensity == DisplayMetrics.DENSITY_TV){
- mWebSettings.setDefaultZoom(ZoomDensity.FAR);
- }else{
- mWebSettings.setDefaultZoom(ZoomDensity.MEDIUM);
- }
-
- }
-
- public void loadLocalHtml(String assetUrl) {
- init_();
- mWebView.setWebViewClient(new MyWebViewClient());
- mWebView.loadUrl(assetUrl);
- }
-
- public void loadHtml(String htmlData) {
- init();
- mWebView.setWebViewClient(new MyWebViewClient());
- mWebView.loadDataWithBaseURL("about:blank", htmlData, "text/html", "utf-8", null);
- }
-
- public void setOnOpenListener(OnOpenListener onOpenListener){
- this.mOnOpenListener = onOpenListener;
- }
-
- public interface OnOpenListener {
- void onOpen(String url);
-
-
- }
-
- class MyWebViewClient extends WebViewClient{
-
- @Override
- public boolean shouldOverrideUrlLoading(WebView view, String url) {
- if (mOnOpenListener != null) {
- mOnOpenListener.onOpen(url);
- }
- return true;
- }
-
- }
OK,如果有更好的实现方式或者不足的指出,还请在评论区交流,共同学习,共同进步!
Demo下载