Giter VIP home page Giter VIP logo

tutoshowcase's Introduction

Tuto Showcase

A simple and Elegant Showcase view for Android

Android app on Google Play

screen

TutoShowcase.from(this)
    .setContentView(R.layout.tuto_sample)

    .on(R.id.about) //a view in actionbar
    .addCircle()
    .withBorder()
    .onClick(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //custom action
        }
    })

    .on(R.id.swipable)
    .displaySwipableRight()

    .show();

Download

Buy Me a Coffee at ko-fi.com

Download

compile 'com.github.florent37:tutoshowcase:1.0.1'

Tutorial

You can simply limit a showcase visibility to once with .showOnce(string)

Content View

It's simple to add a content view into the TutoShowcase, you can for example add images or descriptions texts

TutoShowcase.from(this)
    .setContentView(R.layout.tuto_sample)
    ...
    .show()

screen

Indicators

You can higlight some elements to user

Circle

.on(view)
.addCircle()

screen

RoundRect

.on(view)
.addRoundRect()

screen

Actions

Some actions can be explained to the user

Scrollable

.on(view)
.displayScrollable()

Swipable Left

.on(view)
.displaySwipableLeft()

screen

Swipable Right

.on(view)
.displaySwipableRight()

screen

Events

You can listen for indicator click

.on(view)
. //your indicator
.onClick(new View.OnClickListener(){
    public void onClick(View view){
         //your action
    }
}

If you have any clickable view into your content layout

TutoShowcase.from(this)
    .setContentView(R.layout.tuto_sample)
    .onClickContentView(R.id.clickableView, new View.OnClickListener() {
        @Override
        public void onClick(View view) {
                            
        }
    })
    ...
    .show()
Android app on Google Play

Fiches Plateau Moto : https://www.fiches-plateau-moto.fr/

tutoshowcase's People

Contributors

ezaquarii avatar florent37 avatar rayliverified avatar the-twenty-five avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tutoshowcase's Issues

how to use it on Recycler view

i'm using recycler view in a fragment in my app and i need to say something about first recyclerview item
using this code :

TutoShowcase.from(getActivity())
            .setContentView(R.layout.tuto)
            .on(recyclerView.getChildAt(1))
            .addCircle()
            .show();

but when i use "recyclerView.getChildAt(1)"
returns me this error :

java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.ViewTreeObserver android.view.View.getViewTreeObserver()' on a null object reference

what can i do about this ?
thank's

Can you only set shapes on views?

Great lib and thanks for your effortl

I want to know can I set shapes on some custom layout dimensions?
I dont want to set shapes to views sometimes, need custom shapes for action bar items or anything else.

No centering round rect correctly

I am trying to use TutoShowcase to show hint in a view that is a page of a ViewPager. For any view inside that view the roundrect is displayed displaced. See the image.
problem

Both layouts draw at same time

I'm having two fragments in ViewPager tab and when Showcase loads first layout it seems that at same time second layout is loaded.Screen gets darker and when clicked first time, it get some brightnest.

OnClick methods from second fragment works on first fragment.Bot methods are called inside onViewCreated lifecycle callback.
Do I need to dismiss instance of showcase when fragment is destroying?

Here is 1.st fragment:

  public void showFeedTutorial() {
    TutoShowcase.from(getActivity())
        .setContentView(R.layout.tuto_sample)
        .on(viewTutorial)
        .addRoundRect(0)

        .onClickContentView(R.id.imageall, new View.OnClickListener() {
          @Override public void onClick(View view) {
            Log.d("tuto", "clicking all view");
            //dismissTutorial();
          }
        })
        .onClickContentView(R.id.title, new View.OnClickListener() {
          @Override public void onClick(View view) {
                navigateTo(MarketFragment.class);

          }
        })
    .show();

  }

Here is second fragment:

public void showMarketTutorial() {
    TutoShowcase.from(getActivity())
        .setContentView(R.layout.tuto_sample2)
        .show();
  }

make animated to non animated

i also make animated item to non animated .

code

private void displayScrollableUpOnView() {
final Rect rect = new Rect();
view.getGlobalVisibleRect(rect);
final int height = rect.height();

        final ImageView hand = new ImageView(view.getContext());
        hand.setImageResource(R.drawable.ic_hand_finger_on_up_arrow);
        ViewGroup.MarginLayoutParams layoutParams = new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);

        hand.setLayoutParams(layoutParams);
        hand.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                int x = (int) (rect.centerX() - hand.getWidth() / 2f);
                int y = (int) (rect.centerY() - hand.getHeight() / 2f) - getStatusBarOffset();
                ViewCompat.setTranslationY(hand, y - 25);
                ViewCompat.setTranslationX(hand, x);

//
// if (settings.animated)
// ViewCompat.animate(hand) // - height * 0.8f - getStatusBarOffset()
// .translationY(rect.top-50)
// .setStartDelay(settings.delay != null ? settings.delay : 1500)
// .setDuration(settings.duration != null ? settings.duration : 3000)
// .setInterpolator(new DecelerateInterpolator());

                hand.getViewTreeObserver().removeOnPreDrawListener(this);
                return false;
            }
        });


        tutoShowcase.container.addView(hand, layoutParams);
        tutoShowcase.container.invalidate();
    }

Show text below circle or square

Thanks for the library, is it possible to know the position of the circle/square so that we can change the position of the text accordingly? Something done in other libraries such as https://github.com/deano2390/MaterialShowcaseView

The issue with current version is that it is difficult to predict the margin/padding to be provided so as to prevent text coming inside/overlapping circles/squares. Also, as many other posted, since there is no way to even change the text of the TextViews, we end up creating same/similar layout files for individual screens. This all can be prevented, as done in mentioned library.

showOnce not working

I'm using showOnce("key") but the animation is still running every time the application opens

 TutoShowcase.from(this)
            .on(R.id.preapproveTxtVw)
            .displaySwipableLeft()
            .animated(true)
            .delayed(300)
            .duration(2000)
            .show()
            .showOnce("key");

Show tutoShowCase above dialog

tutoshowcase can not work with dialog. when i try to display tutoshowcase above dialog then it not work.
any way to display above dialog?.

Displaced circle and round rect when activity in full screen.

The circle or rect is displaced when the activity is in full screen.
I copied the project over and fixed it in the following way.

`public final class TutoShowcase {

public static final float DEFAULT_ADDITIONAL_RADIUS_RATIO = 1.5f;
private static final String SHARED_TUTO = "SHARED_TUTO";
private FrameLayout container;
private TutoView tutoView;
private SharedPreferences sharedPreferences;
private boolean isFullScreen = false;

private TutoShowcase(@NonNull Activity activity) {
    this.sharedPreferences = activity.getSharedPreferences(SHARED_TUTO, Context.MODE_PRIVATE);
    this.container = new FrameLayout(activity);
    this.tutoView = new TutoView(activity);
    Window window = activity.getWindow();
    if (window != null) {
        ViewGroup decorView = (ViewGroup) window.getDecorView();
        if (decorView != null) {
            ViewGroup content = (ViewGroup) decorView.findViewById(android.R.id.content);
            if (content != null) {
                content.addView(container, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
                this.container.addView(tutoView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
            }
        }
    }

    int flg = activity.getWindow().getAttributes().flags;
    if ((flg & WindowManager.LayoutParams.FLAG_FULLSCREEN) == WindowManager.LayoutParams.FLAG_FULLSCREEN) {
        isFullScreen = true;
    }

    this.container.setVisibility(View.GONE);
    ViewCompat.setAlpha(container, 0f);
}`

`public static class ViewActions {
private final TutoShowcase tutoShowcase;
private final View view;
private final ViewActionsSettings settings;
private final boolean isFullScreen;

    public ViewActions(final TutoShowcase tutoShowcase, View view, boolean fullScreen) {
        this.tutoShowcase = tutoShowcase;
        this.view = view;
        this.settings = new ViewActionsSettings();
        this.isFullScreen = fullScreen;
    }`

` private int getStatusBarHeight() {
int result = 0;
Context context = view.getContext();
Resources resources = context.getResources();
int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = resources.getDimensionPixelSize(resourceId);
}
if( isFullScreen ) {
result = 0;
}

        return result;
    }`

unable to find not animated down finger image

i'm unable to find not animated down finger in you library. so i have make some adjustment in your code to get this functionality.

here code to make adjustment to get this functionality

private void displayScrollableDownOnView() {
final Rect rect = new Rect();
view.getGlobalVisibleRect(rect);
final int height = rect.height();

        final ImageView hand = new ImageView(view.getContext());
        hand.setImageResource(R.drawable.ic_tutoshowcase_finger_moving_down);
        hand.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));


        hand.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                int x = (int) (rect.centerX() - hand.getWidth() / 2f);
                int y = (int) (rect.centerY() - hand.getHeight() / 2f) - getStatusBarOffset();

                if (Build.VERSION.SDK_INT > 20) {
                    ViewCompat.setTranslationY(hand, y - 215);
                } else {
                    ViewCompat.setTranslationY(hand, y - 150);
                }


                ViewCompat.setTranslationX(hand, x);

// if (settings.animated)
// ViewCompat.animate(hand) //- height * 0.8f - getStatusBarOffset()
// .translationY(x)
// .setStartDelay(settings.delay != null ? settings.delay : 500)
// .setDuration(settings.duration != null ? settings.duration : 600)
// .setInterpolator(new DecelerateInterpolator());

                hand.getViewTreeObserver().removeOnPreDrawListener(this);
                return false;
            }
        });

Example with latest version

Hi,

Thanks for the lib.

Does anyone have an example using the latest version?

Things like this on(R.id.name) are no longer valid, there is a second parameter but I don't quite get how it works.

Thanks

set proper location & size of view to be highlight

i face some issue to highlight view . when i use this some device show it perfect. some device not show perfectly . so i make some adjustment to achieve this .

here i show code which i make adjustment.

    private void addCircleOnView(float additionalRadiusRatio) {
        Rect rect = new Rect();
        int[] locations = new int[2];
        view.getGlobalVisibleRect(rect);
        view.getLocationOnScreen(locations);

        Log.i(TAG, "addCircleOnView: rect values");
        Log.i(TAG, "addCircleOnView:left " + rect.left);
        Log.i(TAG, "addCircleOnView:top " + rect.top);
        Log.i(TAG, "addCircleOnView:right " + rect.right);
        Log.i(TAG, "addCircleOnView:bottom " + rect.bottom);


        Log.i(TAG, "addCircleOnView: using view's method");

        Log.i(TAG, "addCircleOnView:X " + view.getX());
        Log.i(TAG, "addCircleOnView:Y " + view.getY());

        Log.i(TAG, "addCircleOnView:get top " + view.getTop());
        Log.i(TAG, "addCircleOnView: get left " + view.getLeft());
        Log.i(TAG, "addCircleOnView: get right " + view.getRight());
        Log.i(TAG, "addCircleOnView:get bottom " + view.getBottom());

        Log.i(TAG, "addCircleOnView: loction on screen");
        Log.i(TAG, "addCircleOnView:location X " + locations[0]);
        Log.i(TAG, "addCircleOnView: location Y " + locations[1]);


        view.getLocationOnScreen(locations);
        int cx;
        cx = (int) (rect.left + rect.top - view.getY());
        int cy = rect.top;

// int cy = locations[1];
int radius = (int) (Math.max(rect.width(), rect.height()) / 2f * additionalRadiusRatio);
Circle circle = new Circle(cx, cy, radius);
circle.setDisplayBorder(settings.withBorder);

        tutoShowcase.tutoView.addCircle(circle);

        addClickableView(rect, settings.onClickListener, additionalRadiusRatio);

        tutoShowcase.tutoView.postInvalidate();
    }

private void addRoundRectOnView(float additionalRadiusRatio) {
Rect rect = new Rect();
int locations[] = new int[2];
view.getLocationOnScreen(locations);
view.getGlobalVisibleRect(rect);
int padding;

        Log.i(TAG, "addRectOnView: rect values");
        Log.i(TAG, "addRectOnView:left " + rect.left);
        Log.i(TAG, "addRectOnView:top " + rect.top);
        Log.i(TAG, "addRectOnView:right " + rect.right);
        Log.i(TAG, "addRectOnView:bottom " + rect.bottom);
        Log.i(TAG, "addRectOnView:width " + rect.width());
        Log.i(TAG, "addRectOnView:height " + rect.height());


        Log.i(TAG, "addRectOnView: using view's method");

        Log.i(TAG, "addRectOnView:X " + view.getX());
        Log.i(TAG, "addRectOnView:Y " + view.getY());

        Log.i(TAG, "addRectOnView:get top " + view.getTop());
        Log.i(TAG, "addRectOnView: get left " + view.getLeft());
        Log.i(TAG, "addRectOnView: get right " + view.getRight());
        Log.i(TAG, "addRectOnView:get bottom " + view.getBottom());
        Log.i(TAG, "addRectOnView:width " + view.getWidth());
        Log.i(TAG, "addRectOnView:height " + view.getHeight());

        Log.i(TAG, "addRectOnView: loction on screen");
        Log.i(TAG, "addRectOnView:location X " + locations[0]);
        Log.i(TAG, "addRectOnView: location Y " + locations[1]);


        int x, y, width, height;



        if (Build.VERSION.SDK_INT < 20) {
            x = view.getLeft() - view.getLeft() / 4;
            y = locations[1] - 40;
            width = view.getWidth() + view.getLeft() / 2;
            height = rect.height();
        } else {
            x = view.getLeft() - view.getLeft() / 4;
            y = rect.top;
            width = view.getWidth() + view.getLeft() / 2;
            height = rect.height();
        }
        RoundRect roundRect = new RoundRect(x, y, width, height);
        roundRect.setDisplayBorder(settings.withBorder);
        tutoShowcase.tutoView.addRoundRect(roundRect);
        addClickableView(rect, settings.onClickListener, additionalRadiusRatio);
        tutoShowcase.tutoView.postInvalidate();
    }

Make findViewById public

Right now I would need to create a new layout for every Showcase I am showing - I would like to use the library for my changelog however, which means there should be an easy way to manipulate view like text once they have been inflated.

By making the function findViewById public this could be easily done.

How to achieve drawing a simple rectangle?

So I'd like to have a simple rectangle drawn instead the rounded corners one.
I am having trouble in finding any method to do this, and also tried to extend the TutoShowcase proved to be a hellish task, as its construction is almost non-extendable.

So is there any simple way other than actually downloading and manually changing the lib my self, which I'd like to avoid if possible.

Cheers

Disabling auto close when showcaseview clicked

I've tried to disable auto closing tutorial, and tried with setting TutoShowcase listener and onDismissed callback.Is there any other way to do this? Thanks for your effort and amazing lib!

public void showFeedTutorial(){
    TutoShowcase.from(getActivity())
        .setContentView(R.layout.tuto_sample)
        .on(viewTutorial)
        .addRoundRect(0)
        .setListener(new TutoShowcase.Listener() {
          @Override
          public void onDismissed() {
            Log.d("Tuto","onDismissed");
          }
        })
        .show();
  }

How to disable auto close

Hi, thanks for great plugin, but I want to disable auto close when clicking on TutoShowcase. That mean I just want to close it using custom button.

Maybe have a syntax i can use like
TutoShowcase.from(this)
.enableClose(false)

How to animate showcaseview

How can I animate apperance of ShowcaseView?I've tried static method from your samples (animate(true) ) but it doesn't work.

  public void showFeedTutorial(){
    TutoShowcase.from(getActivity())
        .setContentView(R.layout.tuto_sample)
        .on(viewTutorial)

        .addRoundRect(0)
        .onClickContentView(R.id.circleLogin, new View.OnClickListener() {
          @Override
          public void onClick(View view) {
          
            navigateTo(MarketActivity.class);
          }
        })
        .show();
  }

custom borderColor

Can you please make borderColor customizable with setter? Last thing for me, to make it perfect.
Thanks

Show tutoShowCase in dialog.

Is there any way we can show tutorial in the dialog ? Currently when I try to do, the tutorial is shown beneath the dialog. How can we show above the dialog?

Provide default layouts

Hi,

It would be very nice including some default layouts in the library, to use with:
TutoShowcase.from(this) .setContentView(R.layout.tuto_sample)

Thanks & Regards,
Marcello

Flexibility in view layout

In most of cases I have the same layout with the difference only in text. At this moment I see no way how to exclude layout files duplication. It is really annoying to have 20 almost equal layouts. Do you have any idea how to get rid of them? I can use reflection but it doesn't look like a good solution.

Animation customization

Great library, thanks. It will be cool, if you add scrollable animation customization: repeat it and change image, for example.

Repeat animation

Hi,

Thanks for the awesome library. How can i repeat the swipeleft animation in a loop? As of now the animation comes only once.

Show the ShowcaseView Once

Hi florent, Great job on this library, it really simplifies creating showcase views. However, is there any feature in this library where the showcase view can be shown once after the first launch!

Regards

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.