Страницы

Поиск по вопросам

суббота, 21 декабря 2019 г.

Android Как реализовать режим “обучения” в приложении?

#java #android


Видел в некоторых приложениях нечто вроде режима обучения:


Основная активность немного затемнена
Поверх выскакивают тексты, типа "Нажмите сюда" и выделяют область


Хочется такое-же реализовать. 

Не подскажите куда копать?
    


Ответы

Ответ 1



Когда-то форкал библиотеку, чтоб сделать свое обучение в приложении, основывался на этом https://github.com/sjwall/MaterialTapTargetPrompt очень помогло, возможно и вам подойдет. Также видел https://github.com/TakuSemba/Spotlight это примерно то что вы хотите

Ответ 2



Использовал для подобного PopupWindow (подсказка) в связке с таким классом (затенение): public class OverlayView extends FrameLayout { private Bitmap bitmap; int paddings, offset; RectF rect; public OverlayView(Context context) { super(context); init(); } public OverlayView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public OverlayView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) public OverlayView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); init(); } private void init() { rect = new RectF(0, 0, 0, 0); //у меня почему-то идет смещение на +24 пикселя, поэтому вымерил и выставляю смещение назад вручную offset = (int) (-24 * getContext().getResources().getDisplayMetrics().density); //padding - по вкусу paddings = (int) getContext().getResources().getDimension(R.dimen.paddings); } @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); if (bitmap == null) { createWindowFrame(); } canvas.drawBitmap(bitmap, 0, 0, null); } protected void createWindowFrame() { bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); Canvas osCanvas = new Canvas(bitmap); RectF outerRectangle = new RectF(0, 0, getWidth(), getHeight()); Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setColor(getResources().getColor(R.color.dark)); osCanvas.drawRect(outerRectangle, paint); paint.setColor(Color.TRANSPARENT); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT)); osCanvas.drawRoundRect(rect, paddings, paddings, paint); } //если надо исключить из тени 1 view public void setView(View v) { int xStart = getRelativeLeft(v); int yStart = getRelativeTop(v) + offset; int xEnd = xStart + v.getWidth(); int yEnd = yStart + v.getHeight(); rect = new RectF(xStart, yStart, xEnd, yEnd); createWindowFrame(); postInvalidate(); } //если надо исключить из тени 2 view (можно настроить на большее количество) public void setTwoView(View v1, View v2) { int xStart = getRelativeLeft(v1); int yStart = getRelativeTop(v1) + offset; int xEnd = xStart + v1.getWidth(); int yEnd = yStart + v1.getHeight(); int xStart2 = getRelativeLeft(v2); int yStart2 = getRelativeTop(v2) + offset; int xEnd2 = xStart2 + v2.getWidth(); int yEnd2 = yStart2 + v2.getHeight(); rect = new RectF(Math.min(xStart, xStart2), Math.min(yStart, yStart2), Math.max(xEnd, xEnd2), Math.max(yEnd, yEnd2)); createWindowFrame(); postInvalidate(); } @Override public boolean isInEditMode() { return true; } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); bitmap = null; } private int getRelativeLeft(View myView) { if (myView.getParent() == myView.getRootView()) return myView.getLeft(); else return myView.getLeft() + getRelativeLeft((View) myView.getParent()); } private int getRelativeTop(View myView) { if (myView.getParent() == myView.getRootView()) return myView.getTop(); else return myView.getTop() + getRelativeTop((View) myView.getParent()); } public void reset() { rect = new RectF(0, 0, 0, 0); createWindowFrame(); postInvalidate(); } } Вот так сделать PopupWindow: private void setPopup() { popup = new PopupWindow(this); View v = LayoutInflater.from(this).inflate(R.layout.popup_window, null); hint = v.findViewById(R.id.hint); popup.setContentView(v); popup.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); v.setOnClickListener(onNextClick); } Примерно так обрабатывать клики: int state = -1; //текущая подсказка private void onNextClick(View v) { state++; popup.dismiss(); View anchor = null; switch (state) { case 0: setPopup(); screen.setTwoView(views.get(PLAYER_NAME), views.get(PLAYER_HEADER)); anchor = views.get(PLAYER_NAME); break; case 1: screen.setTwoView(views.get(PLAYER_ARMY), views.get(ARMY_HEADER)); anchor = views.get(PLAYER_ARMY); break; ... } if (anchor != null) popup.showAsDropDown(anchor, 0, 10); if (state < hints.length) setHint(hints[state]); } В xml OverlayView добавлен последним элементом в глобальный FrameLayout с параметрами match_parent

Комментариев нет:

Отправить комментарий