在我们第一次安装app的时候,有一些app会出现一个覆盖在我们原来View上面的浮层view,用来做一个app的指示,让用户更快的知道app的整体架构和功能点。下面大家看一下效果图;
这就是我们要出现的效果。首先我们需要实现的功能点大概就是 ,在第一次安装的时候我们才会去触发这个浮层view的效果,我们就需要去保存这个。我们还需要去绘制一个浮层view在盖在原有的view上面,需要写一个列表,当他下拉的时候,符合某些条件就触发一个浮层。大概的要求我们知道了就可以开工了,
我们先看一下整体的项目结构:
大概的架构也跃然于屏了,获取屏幕像素的工具类,浮层view管理者,构造类,对象类,主类实现 效果和一点小小逻辑。
我们先从 像素工具类开始看:
ScreenUtils
package com.newbieguide;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import java.lang.reflect.Field;
/**
* 获取手机屏幕参数的功能工具类
* Created by nzx on 2016/9/2.
* 屏幕区域的获取 :就是整个手机的可见范围
* activity.getWindowManager().getDefaultDisplay();
* 应用区域的获取:就是没有包括 那些 应用商,时间的那个栏 剩下的部分=屏幕部分减去时间栏
* <p/>
* Rect outRect = new Rect();
* activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(outRect);
* 我们绘制view的绘制:就是应用区域 减去(我们没有隐藏标题栏应用状态下( this.requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏 ) )的部分=View 部分
* <p/>
* Rect outRect = new Rect();
* activity.getWindow().findViewById(Window.ID_ANDROID_CONTENT).getDrawingRect(outRect);
*/
public class ScreenUtils {
private ScreenUtils() {
throw new AssertionError();
}
//屏幕距离(dp)转换成像素距离(px)
public static float dpToPx(Context context, float dp) {
if (context == null) {
return -1;
}
return dp * context.getResources().getDisplayMetrics().density;
}
public static int dpToPx(Context context, int dp) {
return (int) (dp * context.getResources().getDisplayMetrics().density);
}
/**
* 获取屏幕宽度
* DisplayMetrics 这是 一个系统 用来 专门 管理 手机 像素 屏幕尺寸的类
*/
public static int getScreenWidth(Context context) {
DisplayMetrics dm = context.getResources().getDisplayMetrics();
int screenHeight = dm.widthPixels;
return screenHeight;
}
/**
* 获取屏幕高度
*/
public static int getScreenHeight(Context context) {
DisplayMetrics dm = context.getResources().getDisplayMetrics();
int screenHeight = dm.heightPixels;
return screenHeight;
}
/**
* 获取状态栏的高
*/
public static int getStatusBarHeight(Activity context) {
Rect frame = new Rect();
context.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
int statusBarHeight = frame.top;
if (0 == statusBarHeight) {
statusBarHeight = getStatusBarHeightByReflection(context);
}
return statusBarHeight;
}
public static int getStatusBarHeight1(Activity context) {
Rect rect = new Rect();
context.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
int statuBarHeight = rect.top;
if (0 == statuBarHeight) {
statuBarHeight = getStatusBarHeightByReflection(context);
}
return statuBarHeight;
}
//获取状态栏高度 。
public static int getStatusBarHeightByReflection(Context context) {
Class<?> c;
Object obj;
Field field;
// 默认为38,貌似大部分是这样的
int x, statusBarHeight = 38;
try {
c = Class.forName("com.android.internal.R$dimen");
obj = c.newInstance();
field = c.getField("status_bar_height");
x = Integer.parseInt(field.get(obj).toString());
statusBarHeight = context.getResources().getDimensionPixelSize(x);
} catch (Exception e1) {
e1.printStackTrace();
}
return statusBarHeight;
}
}
我生疏一点的方法我都会去写上注释这样看来 也比较轻松。
下面 我们开始绘制 我们的表面的浮层view了
GuideView
package com.newbieguide;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.widget.RelativeLayout;
import java.util.List;
/**
* Created by nzx on 2016/9/2.
* 我们实现浮层指引view的业务代码逻辑的实现
*/
public class GuideView extends RelativeLayout {
private int mBgColor = 0xb2000000;
private float mStrokeWidth;
private Paint mPaint;
private Bitmap mBitmap;
private RectF mBitmapRect;
private Canvas mCanvas;
private List<HoleBean> mHoleList;
private PorterDuffXfermode pdf;
public GuideView(Context context) {
super(context);
init();
}
public GuideView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public GuideView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
pdf = new PorterDuffXfermode(PorterDuff.Mode.CLEAR);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(mBgColor);
mPaint.setMaskFilter(new BlurMaskFilter(10, BlurMaskFilter.Blur.INNER));
mBitmapRect = new RectF();
setClickable(true);
setWillNotDraw(false);
}
public void setDate(List<HoleBean> holeList) {
mHoleList = holeList;
if (mHoleList != null && !mHoleList.isEmpty()) {
for (HoleBean hole : mHoleList) {
mBitmapRect.union(hole.getRectF());
}
}
mStrokeWidth = Math.max(Math.max(mBitmapRect.left, mBitmapRect.top), Math.max(ScreenUtils.getScreenWidth(getContext()) -
mBitmapRect.right, ScreenUtils.getScreenHeight(getContext()) - mBitmapRect.bottom));
if (mBitmapRect.width() > 0 && mBitmapRect.height() > 0) {
mBitmap = Bitmap.createBitmap((int) mBitmapRect.width(), (int) mBitmapRect.height(), Bitmap.Config.ARGB_8888);
} else {
mBitmap = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888);
throw new UnsupportedOperationException("需要高亮的view尚未加载完,请调整适当的时机或者延迟");
}
mCanvas = new Canvas(mBitmap);
mCanvas.drawColor(mBgColor);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mHoleList != null && mHoleList.size() > 0) {
mPaint.setXfermode(pdf);
mPaint.setStyle(Paint.Style.FILL);
for (HoleBean hole : mHoleList) {
RectF rectF = hole.getRectF();
rectF.offset(-mBitmapRect.left, -mBitmapRect.top);
switch (hole.getType()) {
case HoleBean.TYPE_CIRCLE:
mCanvas.drawCircle(rectF.centerX(), rectF.centerY(), hole.getRadius(), mPaint);
break;
case HoleBean.TYPE_RECTANGLE:
mCanvas.drawRect(rectF, mPaint);
break;
case HoleBean.TYPE_OVAL:
mCanvas.drawOval(rectF, mPaint);
break;
}
}
canvas.drawBitmap(mBitmap, mBitmapRect.left, mBitmapRect.top, null);
//绘制剩余空间的矩形
mPaint.setXfermode(null);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(mStrokeWidth + 0.1f);
canvas.drawRect(fillRect(mBitmapRect), mPaint);
}
}
private RectF fillRect(RectF rectF) {
RectF fillRect = new RectF();
fillRect.left = rectF.left - mStrokeWidth / 2;
fillRect.top = rectF.top - mStrokeWidth / 2;
fillRect.right = rectF.right + mStrokeWidth / 2;
fillRect.bottom = rectF.bottom + mStrokeWidth / 2;
return fillRect;
}
public void recycler() {
if (mBitmap != null) {
mBitmap.recycle();
mBitmap = null;
}
}
}
浮层view 的一些封装的对象类
HoleBean
package com.newbieguide;
import android.graphics.RectF;
import android.view.View;
/**
* Created by nzx on 2016/9/2.
*改变原有的对象类 ,覆盖在原有层上面的表面view
*/
public class HoleBean {
public static final int TYPE_CIRCLE = 0; //圆
public static final int TYPE_RECTANGLE = TYPE_CIRCLE + 1; //长方形
public static final int TYPE_OVAL = TYPE_RECTANGLE + 1; //椭圆
private View mHole;
private int mType;
public HoleBean(View hole, int type) {
this.mHole = hole;
this.mType = type;
}
//获得我们需要绘制的浮层view 宽,高
public int getRadius() {
return mHole != null ? Math.min(mHole.getWidth(), mHole.getHeight()) / 2 : 0;
}
public RectF getRectF() {
RectF rectF = new RectF();
if (mHole != null) {
int[] location = new int[2];
mHole.getLocationOnScreen(location);
rectF.left = location[0];
rectF.top = location[1];
rectF.right = location[0] + mHole.getWidth();
rectF.bottom = location[1] + mHole.getHeight();
}
return rectF;
}
public int getType() {
return mType;
}
}
下面就是我们怎么去设置浮层view的管理者类咯,这里对于我们来说就比较重要,想要什么样式,点击事件,时间的回调,什么字的那个操作都需要在这边进行修改。
NewbieGuide
package com.newbieguide;
import android.app.Activity;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
/**
* Created by nzx on 2016/9/2.
* 新的页面层
*/
public class NewbieGuide {
public static final int CENTER = 0;
private boolean mEveryWhereTouchable = true;
private OnGuideChangedListener mOnGuideChangedListener;
private List<HoleBean> mHoleList;
private Activity mActivity;
private GuideView mGuideView;
private FrameLayout mParentView;
public NewbieGuide(Activity activity) {
init(activity);
}
//初始化我们的整个视图
private NewbieGuide init(Activity activity) {
mActivity = activity;
mParentView = (FrameLayout) mActivity.getWindow().getDecorView();
mGuideView = new GuideView(mActivity);
mHoleList = new ArrayList<>();
return this;
}
//添加 我们高亮view的 视图 对象
public NewbieGuide addHighLightView(View view, int type) {
HoleBean hole = new HoleBean(view, type);
mHoleList.add(hole);
return this;
}
//蒙版提示图标
public NewbieGuide addIndicateImg(int id, int offsetX, int offsetY) {
ImageView arrowImg = new ImageView(mActivity);
arrowImg.setImageResource(id);
mGuideView.addView(arrowImg, getLp(offsetX, offsetY));
return this;
}
// 蒙版提示的消息
public NewbieGuide addMessage(String msg, int offsetX, int offsetY) {
mGuideView.addView(generateMsgTv(msg), getLp(offsetX, offsetY));
return this;
}
//蒙版提示的消息文本
public NewbieGuide addKnowTv(String text, int offsetX, int offsetY) {
mGuideView.addView(generateKnowTv(text), getLp(offsetX, offsetY));
return this;
}
//蒙版提示的消息文本的显示位置
public NewbieGuide addMsgAndKnowTv(String msg, int offsetY) {
mGuideView.addView(generateMsgAndKnowTv(msg), getLp(CENTER, offsetY));
return this;
}
//生成提示文本
private TextView generateMsgTv(String msg) {
TextView msgTv = new TextView(mActivity);
msgTv.setText(msg);
msgTv.setTextColor(0xffffffff);
msgTv.setTextSize(15);
//设置文本的行距间距
msgTv.setLineSpacing(ScreenUtils.dpToPx(mActivity, 5), 1f);
//文本的相对位置
msgTv.setGravity(Gravity.CENTER);
return msgTv;
}
//生成我知道了文本
private TextView generateKnowTv(String text) {
TextView knowTv = new TextView(mActivity);
knowTv.setTextColor(0xffffffff);
knowTv.setTextSize(15);
knowTv.setPadding(ScreenUtils.dpToPx(mActivity, 15), ScreenUtils.dpToPx(mActivity, 5), ScreenUtils.dpToPx(mActivity, 15),
ScreenUtils.dpToPx(mActivity, 5));
knowTv.setBackgroundResource(R.drawable.solid_white_bg);
knowTv.setText(text);
knowTv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(mActivity,"继续下一个动画",Toast.LENGTH_LONG).show();
remove();
}
});
return knowTv;
}
private TextView generateKnowTv1(String text) {
TextView knowTv1 = new TextView(mActivity);
knowTv1.setTextColor(0xffffffff);
knowTv1.setTextSize(15);
knowTv1.setPadding(ScreenUtils.dpToPx(mActivity, 15), ScreenUtils.dpToPx(mActivity, 5), ScreenUtils.dpToPx(mActivity, 15),
ScreenUtils.dpToPx(mActivity, 5));
knowTv1.setBackgroundResource(R.drawable.solid_white_bg);
knowTv1.setText(text);
knowTv1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
remove();
}
});
return knowTv1;
}
//生成提示文本和我知道了文本
private LinearLayout generateMsgAndKnowTv(String msg) {
LinearLayout container = new LinearLayout(mActivity);
container.setOrientation(LinearLayout.VERTICAL);
container.setGravity(Gravity.CENTER_HORIZONTAL);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams
.WRAP_CONTENT);
container.addView(generateMsgTv(msg), lp);
lp.topMargin = ScreenUtils.dpToPx(mActivity, 10);
container.addView(generateKnowTv("就你TM话多"), lp);
return container;
}
//生成布局参数
private RelativeLayout.LayoutParams getLp(int offsetX, int offsetY) {
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams
.WRAP_CONTENT);
//水平方向
if (offsetX == CENTER) {
lp.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
} else if (offsetX < 0) {
lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
lp.rightMargin = -offsetX;
} else {
lp.leftMargin = offsetX;
}
//垂直方向
if (offsetY == CENTER) {
lp.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
} else if (offsetY < 0) {
lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
lp.bottomMargin = -offsetY;
} else {
lp.topMargin = offsetY;
}
return lp;
}
public void show() {
int paddingTop = ScreenUtils.getStatusBarHeight(mActivity);
mGuideView.setPadding(0, paddingTop, 0, 0);
mGuideView.setDate(mHoleList);
mParentView.addView(mGuideView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams
.MATCH_PARENT));
if (mOnGuideChangedListener != null) mOnGuideChangedListener.onShowed();
if (mEveryWhereTouchable) {
mGuideView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
remove();
return false;
}
});
}
}
public void remove() {
if (mGuideView != null && mGuideView.getParent() != null) {
mGuideView.recycler();
((ViewGroup) mGuideView.getParent()).removeView(mGuideView);
if (mOnGuideChangedListener != null) {
mOnGuideChangedListener.onRemoved();
}
}
}
public NewbieGuide setEveryWhereTouchable(boolean everyWhereTouchable) {
mEveryWhereTouchable = everyWhereTouchable;
return this;
}
public void setOnGuideChangedListener(OnGuideChangedListener onGuideChangedListener) {
this.mOnGuideChangedListener = onGuideChangedListener;
}
//浮层显示后的回调
public interface OnGuideChangedListener {
void onShowed();
void onRemoved();
}
}
下面这个类 我们就实现了 一个相关的点击等时间了 比如怎么设置 高亮区,我们的按钮回调等,像是我们需要很多自定义操作都在这里可以实现
NewbieGuideManager
package com.newbieguide;
import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Handler;
import android.view.View;
import android.widget.Toast;
/**
* Created by nzx on 2016/9/2.
* 新的指引页面管理者
*/
public class NewbieGuideManager {
static final String TAG = "newbie_guide";
public static final int TYPE_LIST = 0;// list
public static final int TYPE_COLLECT = 1;// 收藏
Activity mActivity;
SharedPreferences sp; NewbieGuide mNewbieGuide;
int mType;
public NewbieGuideManager(Activity activity, int type) {
mNewbieGuide = new NewbieGuide(activity);
sp = activity.getSharedPreferences(TAG, Activity.MODE_PRIVATE);
mActivity = activity;
mType = type;
}
//添加 我们高亮view的 视图
public NewbieGuideManager addView(View view, int shape) {
mNewbieGuide.addHighLightView(view, shape);
return this;
}
public void show() {
show(0);
}
public void show(int delayTime) {
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean(TAG + mType, false);
editor.apply();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
switch (mType) {
case TYPE_LIST:
mNewbieGuide.setEveryWhereTouchable(false).addIndicateImg(R.drawable.left_arrow, ScreenUtils.dpToPx(mActivity,
60), ScreenUtils.dpToPx(mActivity, 110)).addMsgAndKnowTv("这个listview滚动到item6后出现新手引导浮层,\n只有点击我知道啦才会想消失",
-ScreenUtils.dpToPx(mActivity, 250)).show();
Toast.makeText(mActivity,"辣鸡",Toast.LENGTH_LONG).show();
break;
case TYPE_COLLECT:
mNewbieGuide.addIndicateImg(R.drawable.right, ScreenUtils.dpToPx(mActivity, -70), ScreenUtils.dpToPx(mActivity,
50)).addMsgAndKnowTv("写了一个测试的,随便点击哪里都可以\n废话就不那么多了,你们看看吧", ScreenUtils.dpToPx(mActivity, 150)).show();
break;
}
}
}, delayTime);
}
public void showWithListener(int delayTime, NewbieGuide.OnGuideChangedListener onGuideChangedListener) {
mNewbieGuide.setOnGuideChangedListener(onGuideChangedListener);
show(delayTime);
}
/**
* 判断新手引导也是否已经显示了
*/
public static boolean isNeverShowed(Activity activity, int type) {
return activity.getSharedPreferences(TAG, Activity.MODE_PRIVATE).getBoolean(TAG + type, true);
}
}
下面 就开始写我们的listview列表了,这个都很熟悉了 适配器 布局item 都是轻车熟路了 布局我就不贴了 后面可以拿demo看
ListAdapter
package com.newbieguide;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
/**
* Created by nzx on 2016/9/2.
*/
class ListAdapter extends BaseAdapter {
private List<String> mList;
private LayoutInflater inflater;
private Context context;
public ListAdapter(List<String> list,Context context) {
mList = list;
this.context = context;
this.inflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return mList != null ? mList.size() : 0;
}
@Override
public Object getItem(int position) {
return mList != null ? mList.get(position) : null;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if(convertView == null) {
holder = new ViewHolder();
convertView = View.inflate(context,R.layout.item, null) ;
holder.logo = (ImageView) convertView.findViewById(R.id.logo);
holder.item = (TextView) convertView.findViewById(R.id.details);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.item.setText(mList.get(position).toString());
return convertView;
}
}
class ViewHolder {
ImageView logo;
TextView item;
}
下面的MainActivity 实现的逻辑 就是第一次一进来app
我们就实现 浮层view ,还有一些关于 listview的相关操作
package com.newbieguide;
import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends Activity implements AbsListView.OnScrollListener {
private ImageView mCollect;
private TextView mTitleTv;
private ListView mListView;
private List<String> mList;
private boolean isShow;
SharedPreferences sp;
private boolean isFirst = false;//是否第一次打开App
private Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
initData();
}
private void initData()
{
sp= getSharedPreferences("WelcomeActivity", 0);
isFirst = sp.getBoolean("isFirst",true);
//判断是否第一次打开App,是的话跳转到引导页,否则跳转到主页
if (isFirst) {
handler.postDelayed(new Runnable() {
@Override
public void run() {
/** if (NewbieGuideManager.isNeverShowed(MainActivity.this, NewbieGuideManager.TYPE_COLLECT)) {
new NewbieGuideManager(MainActivity.this, NewbieGuideManager.TYPE_COLLECT).addView(mCollect, HoleBean.TYPE_CIRCLE).addView(mTitleTv,
HoleBean.TYPE_RECTANGLE).show();
} */
onWindowFocusChanged(true);
}
}, 550);
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean("isFirst", false);
editor.commit();
} else {
handler.postDelayed(new Runnable() {
@Override
public void run() {
onWindowFocusChanged(false);
}
}, 2000);
}
}
private void init() {
mCollect = (ImageView) findViewById(R.id.collect);
mTitleTv = (TextView) findViewById(R.id.title);
mListView = (ListView) findViewById(R.id.list);
mList = new ArrayList<>();
for (int i = 0; i < 50; i++) {
mList.add("Item:" + i);
}
mListView.setAdapter(new ListAdapter(mList,getApplicationContext()));
mListView.setOnScrollListener(this);
}
@Override
protected void onResume() {
super.onResume();
}
/**如果刚启动Activity时就要计算这些数据,最好在 onWindowFocusChanged 函数中进行,
否则得到的某些数据可能是错误的,比如,应用区域高宽的获取 */
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {}
@Override
public void onScroll(final AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if(firstVisibleItem >= 6 && NewbieGuideManager.isNeverShowed(this, NewbieGuideManager.TYPE_LIST) && !isShow) {
isShow = true;
mListView.smoothScrollToPosition(6);
mListView.postDelayed(new Runnable() {
@Override
public void run() {
mListView.setSelection(6);
mListView.post(new Runnable() {
@Override
public void run() {
new NewbieGuideManager(MainActivity.this, NewbieGuideManager.TYPE_LIST).addView(view.getChildAt(0)
.findViewById(R.id.logo), HoleBean.TYPE_RECTANGLE).show();
}
});
}
}, 200);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//todo 下面代码需要删掉
/** SharedPreferences.Editor editor = getSharedPreferences("newbie_guide", MODE_PRIVATE).edit();
editor.putBoolean("newbie_guide" + NewbieGuideManager.TYPE_LIST, true);
editor.putBoolean("newbie_guide" + NewbieGuideManager.TYPE_COLLECT, true);
editor.apply(); */
}
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if(NewbieGuideManager.isNeverShowed(this, NewbieGuideManager.TYPE_COLLECT)){
new NewbieGuideManager(this, NewbieGuideManager.TYPE_COLLECT).addView(mCollect, HoleBean.TYPE_CIRCLE).addView(mTitleTv, HoleBean.TYPE_RECTANGLE).show(); } }}
这里的逻辑都在 ui操作里面 我们操作过了app 就改变布尔值 来 通过
onWindowFocusChanged(true或者false)来决定我们是不是需要 在去拉起浮层view。
new NewbieGuideManager(this, NewbieGuideManager.TYPE_COLLECT).addView(mCollect, HoleBean.TYPE_CIRCLE).addView(mTitleTv,
HoleBean.TYPE_RECTANGLE).show();
这个方法 我们可以觉得显示view的对象,样式,和我们需要显示的高亮区域等。
通过这个 能对 view 和轻量级存储,listview 像素计算 有不错的进步的。