A floating menu library for Android.

Related tags

Layout hover
Overview

Hover

Hover is a floating menu implementation for Android.

Goals

The goals of Hover are to:

  1. Provide an easy-to-use, out-of-the-box floating menu implementation for Android developers, and

  2. Provide common tools for Android developers to create their own floating menu.

Beta Notice

Hover is still under heavy development. There is still a lot of code cleanup to do, so expect breaking API changes over time.

That said, Hover should be in a usable state at this time.

0.9.8 Major Breaking Changes

Version 0.9.8 introduces major breaking changes to Hover. This refactor was done to simplify the code structure to make it easier to fix existing bugs and further extend behavior.

0.9.8 also introduces a number of bug fixes, behavior improvements, and Android O alterations:

Feature Updates:

  • Added Android O support for application overlay.
  • Added support for HoverMenuService as foreground Service (important for Android O).
  • Added acceptance criteria as hover.feature file.
  • Added Checkstyle support (no git hooks yet).
  • Added many Hello World demos to show Hover versatility.
  • Added ability to switch out HoverMenus at any time.
  • Much more robust support for adding/removing/changing menu content in HoverView.

Hover Code Alterations:

  • Moved Hover implementation from 'defaultmenu' package to 'hover' package.
  • Can now instantiate a HoverView directly (no Builder required).
  • Replaced HoverMenuAdapter interface with HoverMenu base class.
  • Added HoverMenuView XML attributes for initial dock position.
  • Added 'Closed' menu state (in addition to 'Collapsed' and 'Expanded')
  • Clients can now provide initial dock when constructing HoverMenuView.
  • Hover collapsed position now saved with menu ID to avoid clobbering multiple menus saved state.
  • HoverView is now based on state pattern.

There is still code to clean, but hopefully no further refactor of this scale will be necessary.

Demo Hover Menu

A demo app (called Kitchen Sink) is included with the Hover repo. Here are some screenshots of the demo in action.

Demo Hover Menu - Launching Demo Hover Menu - Launching

Demo Hover Menu - Launching Demo Hover Menu - Launching Demo Hover Menu - Launching

Getting Started

Subclass HoverMenuService

To get started with Hover, create a subclass of HoverMenuService to host your Hover menu. Implement onHoverMenuLaunched(Intent, HoverView) to take control of your HoverView. You'll want to set it's HoverMenu, and also start it in the collapsed or expanded state:

public class MyHoverMenuService extends HoverMenuService {

    @Override
    protected void onHoverMenuLaunched(@NonNull Intent intent, @NonNull HoverView hoverView) {
        // Configure and start your HoverView.
        HoverMenu menu = ...;
        hoverView.setMenu(menu);
        hoverView.collapse();
    }
    
}

Implement A HoverMenu

A HoverMenu is the content that appears within a HoverView. A HoverMenu is divided into an ordered list of Sections. Each Section has a tab as well as Content that appear in your HoverView.

public class MyHoverMenu extends HoverMenu {
 
    private Context mContext;
    private Section mSection;
 
    private SingleSectionHoverMenu(@NonNull Context context) {
        mContext = context;
 
        mSection = new Section(
                new SectionId("1"),
                createTabView(),
                createScreen()
        );
    }
 
    private View createTabView() {
        ImageView imageView = new ImageView(mContext);
        imageView.setImageResource(R.drawable.tab_background);
        imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
        return imageView;
    }
 
    private Content createScreen() {
        return new MyContent(mContext, "Screen 1");
    }
 
    @Override
    public String getId() {
        return "singlesectionmenu";
    }
 
    @Override
    public int getSectionCount() {
        return 1;
    }
 
    @Nullable
    @Override
    public Section getSection(int index) {
        if (0 == index) {
            return mSection;
        } else {
            return null;
        }
    }
 
    @Nullable
    @Override
    public Section getSection(@NonNull SectionId sectionId) {
        if (sectionId.equals(mSection.getId())) {
            return mSection;
        } else {
            return null;
        }
    }
 
    @NonNull
    @Override
    public List<Section> getSections() {
        return Collections.singletonList(mSection);
    }
 
}

Working Directly With A HoverView

If you want to create your own Hover Service from scratch, or if you want to experiment with a HoverView directly, you can instantiate one yourself.

// Create a HoverView to display in a Window:
HoverView hoverView = HoverView.createForWindow(
        context,
        new WindowViewController(
            (WindowManager) getSystemService(Context.WINDOW_SERVICE)
        )
);
hoverView.setOnExitListener(onExitListener);
hoverView.addToWindow();
hoverView.setMenu(...);
hoverView.collapse();
 
// Create a HoverView to display in a View hierarchy:
HoverView hoverView = HoverView.createForView(context);
viewGroup.addView(hoverView);
hoverView.setOnExitListener(onExitListener);
hoverView.setMenu(...);
hoverView.collapse();
 
// Create a HoverView in XML:
<io.mattcarroll.hover.HoverView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:hover="http://schemas.android.com/apk/res-auto"
    android:id="@+id/hovermenu"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    hover:dockSide="right"
    hover:dockPosition="70%"
    />

Download

Hover is available through jCenter:

implementation 'io.mattcarroll.hover:hover:0.9.8'

Issues

When Hover is used within a Window, there is always a fullscreen View - even when nothing is visible. This is done to dramatically simplify the layout logic. However, this causes problems when apps request runtime permissions because the Android OS complains that an overlay is visible.

There is no built-in solution for this problem at this time. You should take care to destroy your Hover Service when the HoverView is closed. You may also want to inform the users of your app that issues with runtime permission dialogs might occur, and that those users should exit your Hover menu if problems occur.

Disclaimer

This is not an official Google product.

License

Copyright (C) 2016 Nest Labs

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Comments
  • Fix how HoverMenuView.addAllTabs() handles ids

    Fix how HoverMenuView.addAllTabs() handles ids

    1. Removed the call tomTabIds.add() in this function. addTab() also has this call, so the id is getting added twice.
    2. Using the HoverMenuAdapter.getTabId() for the id, rather than the position.

    Confirmed no regressions on the sample app scenarios.

    opened by Fitzpasd 11
  • Screen overlay detected

    Screen overlay detected

    When the floating menu is running, other apps can not request permissions. When I request permissions on my another app, the permission dialog came up. No matter I choose deny or allow. The infamous "Screen overlay detected" appeared.

    opened by ljoaquin 9
  • Can't find BaseHoverMenuAdapter

    Can't find BaseHoverMenuAdapter

    Hey there, i'm trying to implement your awesome library into my app but i can't seem to find the BaseHoverMenuAdapter superclass, is it based on an older version or am i missing something?

    Thanks

    image

    opened by AhmedMourad0 8
  • Cannot close a single active session

    Cannot close a single active session

    Currently Hover does not provide the support to close a single active section. If only a single section exists, then dismiss the Hover when the section is closed.

    opened by brijeshshah13 6
  • catched a crash.

    catched a crash.

    E/AndroidRuntime: FATAL EXCEPTION: main Process: io.mattcarroll.hover.hoverdemo, PID: 15843 java.lang.IllegalArgumentException: View=io.mattcarroll.hover.defaulthovermenu.HoverMenuView{42e09eb0 V.E..... ......ID 0,0-1080,1845} not attached to window manager at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:389) at android.view.WindowManagerGlobal.updateViewLayout(WindowManagerGlobal.java:304) at android.view.WindowManagerImpl.updateViewLayout(WindowManagerImpl.java:74) at io.mattcarroll.hover.defaulthovermenu.window.WindowViewController.makeTouchable(WindowViewController.java:93) at io.mattcarroll.hover.defaulthovermenu.window.WindowHoverMenu$1.onExpanded(WindowHoverMenu.java:69) at io.mattcarroll.hover.defaulthovermenu.HoverMenuView$11.run(HoverMenuView.java:445) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:157) at android.app.ActivityThread.main(ActivityThread.java:5335) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081) at dalvik.system.NativeStart.main(Native Method)

    opened by IrvingRyan 6
  • Hover menu disappears when I move it to the top or bottom of the screen.

    Hover menu disappears when I move it to the top or bottom of the screen.

    As the title, it disappears without being retrievable, although the left and right sides of the screen work very well, thank you. Sorry about my English.

    Video description: https://youtu.be/fuzfx4zt9f4

    opened by huynguyenvu1996 4
  • Remove early exit from onLayout

    Remove early exit from onLayout

    This is the same PR I initially put out for issue #34, but closed because I wanted to understand the problem more and test.

    It is not safe to return early from onLayout, even if changed == false, since the adapter can raise content changed events. This event triggers an onLayout call because all the old tabs are removed and new ones added to the view. In this case, the new tabs need to be positioned.

    The repro for this issue is to add content when the menu is collapsed. Once all the old tabs are removed and new ones added, onLayout does not tell mActiveTab to position itself at the anchor. It defaults to the top-right of the screen, and is misaligned with the Dragger so does not accept clicks/drags.

    I've tested that this fixes the issue in my sample app here, and I've confirmed no regressions in project samples.

    opened by Fitzpasd 3
  • I got a NPE when i tap the hoverView after drag as soon as i can

    I got a NPE when i tap the hoverView after drag as soon as i can

    09-04 15:32:42.129 8157-8157/io.mattcarroll.hover.hoverdemo E/AndroidRuntime: FATAL EXCEPTION: main Process: io.mattcarroll.hover.hoverdemo, PID: 8157 java.lang.NullPointerException: Attempt to read from field 'io.mattcarroll.hover.HoverMenu$SectionId io.mattcarroll.hover.HoverView.mSelectedSectionId' on a null object reference at io.mattcarroll.hover.HoverViewStateExpanded.onTabSelected(HoverViewStateExpanded.java:516) at io.mattcarroll.hover.HoverViewStateExpanded.access$300(HoverViewStateExpanded.java:39) at io.mattcarroll.hover.HoverViewStateExpanded$2.onClick(HoverViewStateExpanded.java:152) at android.view.View.performClick(View.java:4909) at android.view.View$PerformClick.run(View.java:20390) at android.os.Handler.handleCallback(Handler.java:815) at android.os.Handler.dispatchMessage(Handler.java:104) at android.os.Looper.loop(Looper.java:194) at android.app.ActivityThread.main(ActivityThread.java:5869) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1020) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815)

    opened by dengyibin 2
  • EditText in content, keyboeard overlaying layout, params.softInputMode not affect

    EditText in content, keyboeard overlaying layout, params.softInputMode not affect

    if i use edittext in content layout it is not adjusting when keyboard open, which is not usable at all in a chat head particulary. I tried to edit WindowViewController with params.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN with and without FLAG_NOT_FOCUSABLE ..... with TYPE_PHONE and TYPE_SYSTEM_ALERT on addView and showView and in the content custom view but nothing worked can you please suggest what should i do and thanks

    opened by abselt 2
  • Empty Packages on Dependency Download

    Empty Packages on Dependency Download

    When adding this library to my android project, gradle finishes the building and syncing tasks, but when I go to use the library, no classes are actually available. My IDE can see the packages and the R class, but everything else is missing. Any reason why this might occur?

    opened by vontell 2
  • Adding content when menu is collapsed causes it to become unresponsive

    Adding content when menu is collapsed causes it to become unresponsive

    I've uploaded a sample app that displays the issue here.

    Changing content and notifying the listeners causes the collapsed menu to move to the top of the screen and become unresponsive.

    I've a fix for this issue which I'll submit for PR.

    opened by Fitzpasd 2
  • Class does not implement the equals method

    Class does not implement the equals method

    The Section does not implement the equals method https://github.com/google/hover/blob/4242c499cf304dc88aaedbcfc61ef4bbaf8eaa0c/hover/src/main/java/io/mattcarroll/hover/HoverMenu.java#L52

    opened by QiAnXinCodeSafe 0
  • Hard drag to bottom permanently removes hover menu.

    Hard drag to bottom permanently removes hover menu.

    Steps to reproduce: Hard drag hover view to the bottom of the screen and hover view will disappear. After that, if you try to launch hover menu, it will not be visible anywhere on the screen. One would have to clear app data to get it back

    opened by yogeshbalan 0
  • removing selected section causes invisible FAB (still draggable)

    removing selected section causes invisible FAB (still draggable)

    If mycustomHoverMenu removes a selected Section from mSections(the ArrayList<Section>) while it is expanded, then calling notifyMenuChanged() causes a crash. To demonstrate, change 1 to 0 on line 123 of MutatingSectionsHoverMenuService.java of the hoverdemo-helloworld app. And manually expand the FAB after starting the "Launch Changing Sections".

    removeTab(0);

    That change just targets the currently selected section/tab for removal instead of a non-selected section. If I collapse the hoverView first, I can avoid the crash, but then I've seen the FAB ends up invisible (still referring to the removed section if it is at the end of the list), or sometimes crash after manually clicking the FAB, but I wonder if there's a better/safer procedure to removing sections.

    I realize this is unsupported. But just in case there's a community using this cool library, I thought I'd post this question. And hopefully, my workaround shortly.

    The crash details:

    E/AndroidRuntime: FATAL EXCEPTION: main
        Process: org.codecanon.hover.hoverdemo.helloworld, PID: 27913
        java.lang.ArrayIndexOutOfBoundsException: length=10; index=-1
            at java.util.ArrayList.get(ArrayList.java:439)
            at io.mattcarroll.hover.hoverdemo.helloworld.MutatingSectionsHoverMenuService$MutatingHoverMenu.getSection(MutatingSectionsHoverMenuService.java:179)
            at io.mattcarroll.hover.HoverViewStateExpanded.removeSection(HoverViewStateExpanded.java:492)
            at io.mattcarroll.hover.HoverViewStateExpanded.removeSections(HoverViewStateExpanded.java:466)
            at io.mattcarroll.hover.HoverViewStateExpanded.access$600(HoverViewStateExpanded.java:39)
            at io.mattcarroll.hover.HoverViewStateExpanded$6.onRemoved(HoverViewStateExpanded.java:327)
            at android.support.v7.util.BatchingListUpdateCallback.dispatchLastEvent(BatchingListUpdateCallback.java:62)
            at android.support.v7.util.DiffUtil$DiffResult.dispatchUpdatesTo(DiffUtil.java:729)
            at io.mattcarroll.hover.HoverMenu.notifyMenuChanged(HoverMenu.java:76)
            at io.mattcarroll.hover.hoverdemo.helloworld.MutatingSectionsHoverMenuService$MutatingHoverMenu.removeTab(MutatingSectionsHoverMenuService.java:224)
            at io.mattcarroll.hover.hoverdemo.helloworld.MutatingSectionsHoverMenuService$MutatingHoverMenu.access$100(MutatingSectionsHoverMenuService.java:59)
            at io.mattcarroll.hover.hoverdemo.helloworld.MutatingSectionsHoverMenuService$MutatingHoverMenu$10.run(MutatingSectionsHoverMenuService.java:123)
            at io.mattcarroll.hover.hoverdemo.helloworld.MutatingSectionsHoverMenuService$MutatingHoverMenu$12.run(MutatingSectionsHoverMenuService.java:142)
            at android.os.Handler.handleCallback(Handler.java:873)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:193)
            at android.app.ActivityThread.main(ActivityThread.java:6718)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
    
    opened by tsengstudios 1
Owner
Google
Google ❤️ Open Source
Google
An elegant way to show your menu or messages.

Android View Hover In my opinion, jumping to a new activity to show your menu is a kind of wasting time and life. So, I think, we need a hover view, t

代码家 3.2k Dec 6, 2022
iOS 7/8 style side menu with parallax effect.

RESideMenu iOS 7/8 style side menu with parallax effect inspired by Dribbble shots (first and second). Since version 4.0 you can add menu view control

Roman Efimov 7.2k Dec 28, 2022
Android library used to create an awesome Android UI based on a draggable element similar to the last YouTube graphic component.

Draggable Panel DEPRECATED. This project is not maintained anymore. Draggable Panel is an Android library created to build a draggable user interface

Pedro Vicente Gómez Sánchez 3k Jan 5, 2023
Bubbles for Android is an Android library to provide chat heads capabilities on your apps. With a fast way to integrate with your development.

Bubbles for Android Bubbles for Android is an Android library to provide chat heads capabilities on your apps. With a fast way to integrate with your

Txus Ballesteros 1.5k Jan 2, 2023
Android library used to create an awesome Android UI based on a draggable element similar to the last YouTube New graphic component.

Please switch to DragView, for the best support, thank you DraggablePanel Download allprojects { repositories { ... maven { url 'https://jitp

Hoàng Anh Tuấn 103 Oct 12, 2022
FixedHeaderTableLayout is a powerful Android library for displaying complex data structures and rendering tabular data composed of rows, columns and cells with scrolling and zooming features. FixedHeaderTableLayout is similar in construction and use as to Android's TableLayout

FixedHeaderTableLayout is a powerful Android library for displaying complex data structures and rendering tabular data composed of rows, columns and cells with scrolling and zooming features. FixedHeaderTableLayout is similar in construction and use as to Android's TableLayout

null 33 Dec 8, 2022
An Android library that help you to build app with swipe back gesture.

SwipeBackLayout An Android library that help you to build app with swipe back gesture. Demo Apk GooglePlay Requirement The latest android-support-v4.j

ike_w0ng 6.1k Dec 29, 2022
SwipeBack is an android library that can finish a activity by using gesture.

SwipeBack SwipeBack is a android library that can finish a activity by using gesture. You can set the swipe direction,such as left,top,right and botto

Eric 1.7k Nov 21, 2022
A very simple arc layout library for Android

ArcLayout A very simple arc layout library for Android. Try out the sample application on the Play Store. Usage (For a working implementation of this

ogaclejapan 1.4k Dec 26, 2022
This library provides a simple way to add a draggable sliding up panel (popularized by Google Music and Google Maps) to your Android application. Brought to you by Umano.

Note: we are not actively responding to issues right now. If you find a bug, please submit a PR. Android Sliding Up Panel This library provides a simp

Umano: News Read To You 9.4k Dec 31, 2022
Simple android library to present an animated ferris wheel

Ferris Wheel View Overview An Android Library used to implement an animated Ferris Wheel in android. API SDK 15+ Written in Kotlin Supports landscape

Igor Lashkov 318 Dec 7, 2022
Android Library that lights items for tutorials or walk-throughs etc...

Spotlight Gradle dependencies { implementation 'com.github.takusemba:spotlight:x.x.x' } Usage val spotlight = Spotlight.Builder(this) .setTarg

TakuSemba 3.4k Dec 23, 2022
It's an Android library that allows you to use Layout as RadioButton or CheckBox.

Android - CompoundLayout It's an Android library that allows you to use Layout as RadioButton or CheckBox. The librarie is Android 14+ compatible. Gra

null 483 Nov 25, 2022
An Android library that help you to build app with swipe back gesture.

SwipeBackLayout An Android library that help you to build app with swipe back gesture. Demo Apk GooglePlay Requirement The latest android-support-v4.j

ike_w0ng 6.1k Jan 3, 2023
A simple customised version of the TextInputLayout from the Android Design Support Library ⌨️

Buffer Text Input Layout (Coming to maven central soon!) This is a simple customisation of the TextInputLayout found in the Design Support Library. Wh

Buffer 988 Nov 24, 2022
Share Layout Android Library

Share any layout screenshot including any string of any Android App to any app via Intent .

Amit Maity 5 Sep 13, 2022
A library that easily allows you to mask layouts/viewgroups

Maskable Layout Overview ======================= The Maskable Layout is a simple framelayout that allows you to easily mask views and viewgroups. You

Christophe Smet 654 Dec 2, 2022
A library for showing different types of layouts when a list view is empty

Android Empty Layout Please note that this project is not being maintained now. Hopefully a new version will be available soon. A library for showing

Raquib-ul Alam (Kanak) 606 Nov 26, 2022