Giter Site home page Giter Site logo

hauler's Introduction

Hauler

Maven Central minSdk:21 Android Arsenal Publish Snapshot License

Hauler is an Android library containing custom layout which enables to easily create swipe to dismiss Activity. Implementation is based on code from project Plaid.

Alt text

Installation

dependencies {
    implementation("app.futured.hauler:hauler:latestVersion")

    // optional dependency with set of Data Binding adapters
    implementation("app.futured.hauler:databinding:latestVersion")
}

Snapshot installation

Add new maven repo to your top level gradle file.

maven { url "https://oss.sonatype.org/content/repositories/snapshots" }

Snapshots are grouped based on major version, so for version 5.x.x use:

implementation "app.futured.hauler:hauler:5.X.X-SNAPSHOT"

Features

Hauler library comes with highly customizable HaulerView which provides swipe to dismiss functionality. It also ships with databinding module which contains Binding Adapters for smoother experience with Android Data Binding implementation.

Usage

Activity which is meant to be dismissed must contain HaulerView as a root view and NestedScrollView (or other View what supports nested scroll) as its child. Make sure your NestedScrollview's attribute android:fillViewport is set to true otherwise it might not behave as expected:

<app.futured.hauler.HaulerView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/haulerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    <androidx.core.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fillViewport="true">
            
            <!-- your layout-->
            
    </androidx.core.widget.NestedScrollView>
</app.futured.hauler.HaulerView>

Secondly, define translucent floating Theme and assign it to the Activity you want to give dismiss ability:

<style name="AppTheme.Draggable" parent="Theme.AppCompat.Light.NoActionBar">
       <item name="android:colorBackgroundCacheHint">@null</item>
       <item name="android:windowContentOverlay">@null</item>
       <item name="android:windowIsFloating">false</item>
       <item name="android:windowIsTranslucent">true</item>
       <item name="android:windowNoTitle">true</item>
       <item name="android:windowBackground">@color/dark_gray</item>
</style>
<activity
        android:name=".draggable.SimpleUsageActivity"
        android:theme="@style/AppTheme.Draggable"/>

Set onDragDismissListener to react properly to user dismiss request. Example implementation might look like this:

    override fun onCreate(savedInstanceState: Bundle?) {
        // ...

        haulerView.setOnDragDismissedListener {
            finish() // finish activity when dismissed
        }
    }

Customization

There are few styleable attributes you might want to use to customize your HaulerView:

<app.futured.hauler.HaulerView
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       app:dragDismissDistance="112dp"
       app:dragDismissFraction="0.9"
       app:dragElasticity="0.7"
       app:dragDismissScale="0.95"/>
Attribute name Type Default value Description
app:dragDismissDistance dimen 100dp Distance which should be View swiped to consider Activity as dismissed
app:dragDismissFraction float unspecified <0;1> - Fraction of View's height we should reach swiping to consider Activity as dismissed
app:dragElasticity float 0.8 <0;1> - Toughness of swipe. Higher value indicates more rigid feeling
app:dragDismissScale float 0.95 <0;1> - Scale factor of View while performing swipe action
app:dragUpEnabled boolean false Flag indicating if drag up dismiss gesture is enabled
app:fadeSystemBars boolean true Flag indicating if system bars (status & navigation) fades while dismiss is in progress

Attributes dragDismissDistance and dragDismissFraction are exclusive. Do not use them together.

License

Hauler is available under the MIT license. See the LICENSE file for more information.

hauler's People

Contributors

matejsemancik avatar okalman avatar skywall 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

hauler's Issues

Black status bar and blinking navigation bar after multitasking

Hi!

I just started using Hauler and implemented a basic prototype according to the instructions in the readme. On first open it works as expected, but if switching app and going back (going to the multitask app picker and select my app again) the status bar gets black and the navigation bar gets black or starts blinking. I've not used black anywhere in the theme, and the blinking is definitely not supposed to happen. :)

I can provide screenshots and code if neccessary. Tested on Pixel 4XL, android 10.

Thanks for making this excellent library! :)

Hauler & ConstraintLayout

Hi!

My activity uses a ConstraintLayout that should be scrollable. Expected behavior is that when scrolling down in the activity the rest of the constraintLayout content should become visible, however, the hauler view displays the not-drag-dismissable animation.

Here is the view:

<com.thefuntasty.hauler.HaulerView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/dragDownDismissView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:theme="@style/AppTheme.Draggable"    
    app:dragUpEnabled="false">

    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true">

        <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            xmlns:tools="http://schemas.android.com/tools"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

          <--rest of view -->

        </androidx.constraintlayout.widget.ConstraintLayout>

    </androidx.core.widget.NestedScrollView>

</com.thefuntasty.hauler.HaulerView>

Issue with non androidx project

I'm not using androidx and get this exception:

2019-01-04 11:18:06.646 8158-8158/com.tandoo.android E/InputEventReceiver: Exception dispatching input event. 2019-01-04 11:18:06.646 8158-8158/com.tandoo.android E/MessageQueue-JNI: Exception in MessageQueue callback: handleReceiveCallback 2019-01-04 11:18:06.648 8158-8158/com.tandoo.android E/MessageQueue-JNI: java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/core/view/animation/PathInterpolatorCompat; at com.thefuntasty.hauler.HaulerView.onStopNestedScroll(HaulerView.kt:115) at android.support.v4.view.ViewParentCompat.onStopNestedScroll(ViewParentCompat.java:258) at android.support.v4.view.NestedScrollingChildHelper.stopNestedScroll(NestedScrollingChildHelper.java:188) at android.support.v4.widget.NestedScrollView.stopNestedScroll(NestedScrollView.java:226) at android.support.v4.widget.NestedScrollView.onInterceptTouchEvent(NestedScrollView.java:783) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2511) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2990) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657) at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:448) at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1829) at android.app.Activity.dispatchTouchEvent(Activity.java:3307) at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69) at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:410) at android.view.View.dispatchPointerEvent(View.java:12015) at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4795) at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4609) at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4147) at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4200) at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4166) at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4293) at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4174) at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4350) at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4147) at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4200) at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4166) at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4174) at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4147) at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6661) at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6635) at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6596) at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6764) at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:186) at android.os.MessageQueue.nativePollOnce(Native Method) at android.os.MessageQueue.next(MessageQueue.java:325) at android.os.Looper.loop(Looper.java:142) at android.app.ActivityThread.main(ActivityThread.java:6494) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) Caused by: java.lang.ClassNotFoundException: Didn't find class "androidx.core.view.animation.PathInterpolatorCompat" on path: DexPathList[[zip file "/data/app/com.tandoo.android-s5o0WtJeASia7aIJ0JMucw==/base.apk", zip file "/data/app/com 2019-01-04 11:18:06.648 8158-8158/com.tandoo.android D/AndroidRuntime: Shutting down VM

Interoperability with JAVA

Hi,
I am working in a project using java, I want to know how to call this kotlin based interface in my JAVA activity?
Any help would be appreciated

Hauler and ViewPager

I have the following layout:

<?xml version="1.0" encoding="utf-8"?>
<com.thefuntasty.hauler.HaulerView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/haulerView"
    app:dragUpEnabled="true"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            xmlns:tools="http://schemas.android.com/tools"
            android:fitsSystemWindows="true">

            <View
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/dismiss_click_view"
                android:background="@color/details_preview_dialog_background" />

            <androidx.constraintlayout.widget.ConstraintLayout
                android:layout_width="0dp"
                android:layout_height="0dp"
                app:layout_constraintWidth_percent="@dimen/details_preview_width_ratio_percentage"
                app:layout_constraintHeight_percent="@dimen/details_preview_height_ratio_percentage"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                >

                <androidx.cardview.widget.CardView
                    android:id="@+id/cardView"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_margin="8dp"
                    app:cardCornerRadius="@dimen/details_preview_rounding"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintStart_toStartOf="parent" >

                    <androidx.viewpager.widget.ViewPager
                        android:id="@+id/view_pager"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent" />

                </androidx.cardview.widget.CardView>

                <TextView
                    android:id="@+id/totalNumberOfPhotosTextView"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    tools:text="2/1234"
                    android:textSize="9sp"
                    android:layout_margin="-50dp"
                    android:gravity="center"
                    android:height="@dimen/badge_size"
                    android:minWidth="@dimen/badge_size"
                    android:textColor="@color/badgeTextColor"
                    android:elevation="10dp"
                    android:background="@drawable/badge_secondary"
                    app:layout_constraintTop_toTopOf="parent"
                    app:layout_constraintEnd_toEndOf="parent"
                    />

            </androidx.constraintlayout.widget.ConstraintLayout>

            <ProgressBar
                android:id="@+id/loadingProgressBar"
                style="@style/Widget.AppCompat.ProgressBar"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                android:elevation="10dp"
                />

        </androidx.constraintlayout.widget.ConstraintLayout>

    </androidx.core.widget.NestedScrollView>

</com.thefuntasty.hauler.HaulerView>

So a HaulerView with it's NestedScrollView, which contaisn a ViewPager.
It works, but the ViewPager needs to be scrolled exactly in a horizontal way in order to swipe to the next item, otherwise the HaulerView takes the wipe moved a bit up/down.
it there a way of defining the angle or a treshold or something to make the horizontal scroll prior to the vertical scroll, depending on the angle or something?

EDIT: With a maps fragment inside, I can't scroll the map anymore.

Animation transition in tablet doesn't look good

Thank you for your wonderful library. It works perfectly on smartphones, but it kinda looks problematic on tablets. After dragging activity to dismiss it, foreground activity goes to the right and disappears (while we expect it to go to the bottom not the right). Samsung Galaxy Tab A 10.1 (2016) shows this weird behavior. Is there any workaround for it? Also when i set android:fillViewport="true" in my nestedScrollView, it destroys layout all together.

Example request: Hauler and CollapsingToolbar

Hi!

Is it possible to use Hauler together with a Collapsing Toolbar from Material Components? I'm experiencing issues with propagating the scroll event to both Hauler and the toolbar. Seems like one of them will consume the event.

If possible, I would very much like to see an example with best practices.

Thanks.

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.