Git Product home page Git Product logo

insetter's Introduction

Insetter

GitHub release

Insetter is a library to help apps handle WindowInsets more easily. Please visit the website for more information.

Contributions

Please contribute! We will gladly review any pull requests. Make sure to read the Contributing page first though.

License

Copyright 2019 Google LLC.

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

    https://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.

insetter's People

Contributors

alexvanyo avatar chrisbanes avatar coltonidle avatar dallasgutauckis avatar ivaniskandar avatar kdrag0n avatar mercuriy94 avatar osipxd avatar paulwoitaschek avatar pfmaggi avatar poliver avatar samystudio avatar simonmarquis avatar steinerok avatar vitaliybelyaev avatar zacsweers 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  avatar  avatar  avatar  avatar

insetter's Issues

Add CHANGELOG file

It would be great if you could add a CHANGELOG file, so we can see what changes have been made.

IllegalAccessError for OnApplyInsetsListener

Insetter version: 0.1.0 with ktx
I start use insetter and catch this exception:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: ru.desk.gesture_view, PID: 4053
    java.lang.IllegalAccessError: Interface dev.chrisbanes.insetter.OnApplyInsetsListener implemented by class ru.desk.gesture_view.ImageViewerActivity$onCreate$$inlined$doOnApplyWindowInsets$1 is inaccessible (declaration of 'ru.desk.gesture_view.ImageViewerActivity$onCreate$$inlined$doOnApplyWindowInsets$1' appears in /data/app/ru.desk.gesture_view-u1iHhsBDTS7EvCxxHDbseQ==/base.apk!classes2.dex)
        at java.lang.Class.newInstance(Native Method)
        at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:69)
        at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45)
        at android.app.Instrumentation.newActivity(Instrumentation.java:1216)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2864)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3081)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1831)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:201)
        at android.app.ActivityThread.main(ActivityThread.java:6806)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)

I think problem is that OnApplyInsetsListener is not public...

Not work in Motion Layout

I have a button which has layout_constraintTop_toTopOf="parent" then I will apply inset status bar to its but not work; neither Insetter Builder nor data binding worked.

My solution: the button will be bottom of Guildline then I will setGuidelineBegin = inset.systemWindowInsetTop to the Guideline now it works.

Issue with animated inset keyboard padding

I am facing a few issues with using the animated ime support in my app. As you can see the edittext's animate upwards and drop back again behind the keyboard

Went through a few issues and i think the issue is similar to #93. Hence, i tried applying the padding to the linearlayout as recommended there but the issue persists as shown in the attached video.

I have attached my project along with relevant commit https://github.com/kriticalflare/SocietyApp/tree/84088adbab5e7dae533ae5dc443aaa2c3c0c38be

animated.ime.mp4

Using android:windowTranslucentStatus causes problem with adjustResize

I am using this library for a form which uses fullscreen mode for drawing the form behind statusBar. I am very delighted to have found this amazing library which helps in calculating the insets rather than calculating it manually, for that, I thank you.

As for the issue, forms would normally has EditTexts and mine have several.
I was only using app:paddingTopSystemWindowInsets="@{true}" for the layout as I only need the top padding. But this causes problem as my Activity doesn't respect adjustResize anymore, unelss I add app:paddingBottomSystemWindowInsets="@{true}".

Is this an intended behavior?
Or is it actually an issue?

InsetterConstraintLayout does not work with ConstraintLayout 2.1.0-alpha2

ConstraintLayout 2.1.0-alpha2 introduced the following change:

ConstraintLayout.LayoutParams now inherits directly from ViewGroup.LayoutParams, not ViewGroup.MarginLayoutParams.

This causes the following exception to be thrown when trying to use InsetterConstraintLayout with something like app:layout_marginSystemWindowInsets:

java.lang.IllegalArgumentException: Margin inset handling requested but view LayoutParams do not extend MarginLayoutParams
    at dev.chrisbanes.insetter.Insetter.applyInsetsToView(Insetter.java:459)
    at dev.chrisbanes.insetter.widgets.constraintlayout.InsetterConstraintLayout.onApplyWindowInsets(InsetterConstraintLayout.java:94)
    at android.view.View.dispatchApplyWindowInsets(View.java:9801)
    at android.view.ViewGroup.dispatchApplyWindowInsets(ViewGroup.java:7076)
    at android.view.ViewGroup.dispatchApplyWindowInsets(ViewGroup.java:7080)
    at android.view.ViewGroup.dispatchApplyWindowInsets(ViewGroup.java:7080)
    at android.view.ViewGroup.dispatchApplyWindowInsets(ViewGroup.java:7080)
    at android.view.ViewGroup.dispatchApplyWindowInsets(ViewGroup.java:7080)
    at android.view.ViewGroup.dispatchApplyWindowInsets(ViewGroup.java:7080)
    at android.view.ViewRootImpl.dispatchApplyInsets(ViewRootImpl.java:1664)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1766)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1463)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7190)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:949)
    at android.view.Choreographer.doCallbacks(Choreographer.java:761)
    at android.view.Choreographer.doFrame(Choreographer.java:696)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:935)
    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:491)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

Insets should be applied every time the view is attached to a window

Currently, requestApplyInsets is called once when the view is attached to a window, via doOnAttach (either immediately or the next time the view is attached):

view.doOnAttach { v ->
ViewCompat.requestApplyInsets(v)
}

This works well for most cases, but there are corner cases where this isn't enough.

For instance, suppose a view within a ViewHolder within a RecyclerView is has left/right insets applied to it from the systemBars insets. The consider the following sequence of events:

  • The device is put in landscape orientation, with 3-button navigation (so the left/right insets are non-zero)
  • The user scrolls the RecyclerView, so that some ViewHolders that have insets applied are detached from the window
  • The user directly rotates the device 180 degrees. Since this is still landscape, no recreation of views occurs, but new insets are dispatched.
  • The user scrolls the RecyclerView so that the previously detached ViewHolders are reattached to the window.

Since the new insets were dispatched while the ViewHolders were detached, these ViewHolders will now be incorrectly displaying the old insets, and since they were already attached once, requestApplyInsets won't be called again.

The following video shows an example of that case:

device-2021-01-23-155654.mp4

My proposed fix is to replace doOnAttach with doOnEveryAttach, which will run the action immediately if the view is already attached, and then will run the action again upon every subsequent attach.

Render problem [Insetter-widgets]

java.lang.NoClassDefFoundError: Could not initialize class dev.chrisbanes.insetter.widgets.constraintlayout.InsetterConstraintLayout$LayoutParams
at dev.chrisbanes.insetter.widgets.constraintlayout.InsetterConstraintLayout.generateLayoutParams(InsetterConstraintLayout.kt:99)
at dev.chrisbanes.insetter.widgets.constraintlayout.InsetterConstraintLayout.generateLayoutParams(InsetterConstraintLayout.kt:61)
at android.view.LayoutInflater.rInflate_Original(LayoutInflater.java:1125)
at android.view.LayoutInflater_Delegate.rInflate(LayoutInflater_Delegate.java:72)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:1097)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1084)
at android.view.LayoutInflater.inflate(LayoutInflater.java:682)
at android.view.LayoutInflater.inflate(LayoutInflater.java:501)
at com.android.layoutlib.bridge.impl.RenderSessionImpl.inflate(RenderSessionImpl.java:328)
at com.android.layoutlib.bridge.Bridge.createSession(Bridge.java:373)
at com.android.tools.idea.layoutlib.LayoutLibrary.createSession(LayoutLibrary.java:141)
at com.android.tools.idea.rendering.RenderTask.createRenderSession(RenderTask.java:713)
at com.android.tools.idea.rendering.RenderTask.lambda$inflate$6(RenderTask.java:844)
at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1604)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)

I can't see preview

Request: please explain more about the attribute "app:layout_edgeToEdge"

This is the only thing I can see about it:
https://github.com/chrisbanes/insetter/blob/master/dbx/README.md#edge-to-edge-attributes

"
There is currently just one edge-to-edge attribute:

app:layout_edgeToEdge: Set this view's system-ui visibility with the flags required to be laid out 'edge-to-edge', or not.
"

But what does it do? When to use it? When is it useful?
Is it for Edge display? How is it related to insets?

Please explain.

Create InsetterConstraintHelper for ConstraintLayout

The library will provide InsetterConstraintLayout. It would be nice to have also ConstraintHelper that does the same thing. It's a pluggable mechanism of ConstraintLayout so the users of this library will be able to use Insetter with normal ConstraintLayout.

Attribute layout_marginSystemWindowInsets not work

Margin seems not working for Insetter Builder and InsetterConstraintHelper but Padding is totally fine

Both of that code not working

  • Insetter Builder
    binding.textView.applyInsetter { type(statusBars = true) { margin() } }

  • InsetterConstraintHelper

     <dev.chrisbanes.insetter.widgets.constraintlayout.InsetterConstraintHelper
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          app:constraint_referenced_ids="textView"
          app:layout_constraintEnd_toEndOf="parent"
          app:layout_constraintStart_toStartOf="parent"
          app:layout_constraintTop_toTopOf="parent"
          app:layout_marginSystemWindowInsets="top" />
    

I also tried InsetterConstraintLayout but not work either
I'm using version 0.5.0

systemWindowInsetBottom = -1

Hi,

I'm really really sorry to ask here but it's the easiest way to reach the proper people with issue tracker being changed to prevent posting in many sections to force external triage :(

With AndroidX core 1.2.0 I'm facing a very very strange issue on some devices in some cases that I don't understand and it was quite hard to figure out:

            ViewCompat.setOnApplyWindowInsetsListener(button) { _, insets ->
                filler.layoutParams = filler.layoutParams.apply { this.height = insets.systemWindowInsetBottom }
                insets
            }

In this piece of code insets.systemWindowInsetBottom value is -1 this is not documented anywhere and as unexpected have the effect of setting the view height to match parent and as you can imagine fill the whole screen and hide all the content instead of moving a filler view above the navigation bar.

Is this something known or already seen? Should I report to AndroidX or it can be a specific device issue (OnePlus 6T/ Samsung S10 and Mi 9t pro are the devices that randomly does that and users reported to me) or it's a documentation issue ?
By randomly I means that it happens on very rare instance of those devices but is constant on those
devices.

Seeing one screenshot of a user it's maybe related to some settings those devices have to completely hide the navigation bar as I don't see any on it.
image

setOnApplyInsetsListener always returns insets with 0

I had the issue that the listener received window insets always with 0px
My layout looks like this and I applied the doOnApplyWindowInsets to BottomNavigationView.
I fixed it for me by waiting until it is attached and then listen for insets on the top most parent view.

<androidx.coordinatorlayout.widget.CoordinatorLayout
            android:fitsSystemWindows="false"
            ...>
<com.google.android.material.bottomnavigation.BottomNavigationView
                ... />

Fixed code in kotlin...

/**
     * A wrapper around [ViewCompat.setOnApplyWindowInsetsListener] which stores the initial view state, and provides them whenever a
     * [android.view.WindowInsets] instance is dispatched to the listener provided.
     *
     *
     * This allows the listener to be able to append inset values to any existing view state
     * properties, rather than overwriting them.
     */
    fun setOnApplyInsetsListener(view: View, listener: OnApplyInsetsListener) {
        val tagState = view.getTag(R.id.insetter_initial_state) as ViewState?
        val initialState: ViewState

        if (tagState != null) {
            initialState = tagState
        } else {
            initialState = ViewState(view)
            view.setTag(R.id.insetter_initial_state, initialState)
        }

        if (ViewCompat.isAttachedToWindow(view)) {
            registerForWindowInsets(view, getMostParentView(view), initialState, listener)
        } else {
            view.addOnAttachStateChangeListener(
                object : View.OnAttachStateChangeListener {
                    override fun onViewAttachedToWindow(v: View) {
                        v.removeOnAttachStateChangeListener(this)
                        registerForWindowInsets(v, getMostParentView(v), initialState, listener)
                    }

                    override fun onViewDetachedFromWindow(v: View) {
                        // no-op
                    }
                })
        }
    }

    /**
     * Register for window insets.
     * Commits result through wrapper.
     */
    private fun registerForWindowInsets(
        view: View,
        mostParent: View,
        initialState: ViewState,
        listener: OnApplyInsetsListener
    ) {
        ViewCompat.setOnApplyWindowInsetsListener(
            mostParent
        ) { v, insets ->
            listener.onApplyInsets(view, insets, initialState)
            // Always return the initial insets instance
            insets
        }

        ViewCompat.requestApplyInsets(mostParent)
    }

    /**
     * Returns the most parent view in its hierarchy
     */
    private fun getMostParentView(view: View): View =
        view.parent.run {
            if (this != null && this is View && this.id != android.R.id.content) {
                getMostParentView(this)
            } else view
        }

Cann't set inset for MaterialToolbar inside CollapsingToolbarLayout

Inside my XML

<androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/rootFull">
        <com.google.android.material.appbar.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/topAppBarLayout">
            <com.google.android.material.appbar.CollapsingToolbarLayout
                android:layout_width="match_parent"
                android:layout_height="300sp"
                android:id="@+id/topAppBar"
                app:title="HIEUTHUHAI"
                app:expandedTitleTextAppearance="@style/artist_name"
                app:expandedTitleTextColor="@android:color/white"
                app:collapsedTitleTextAppearance="@style/TextAppearance.Material3.TitleMedium"
                app:layout_scrollFlags="scroll|exitUntilCollapsed"
                app:contentScrim="?attr/colorSurface">
                <ImageView
                    android:id="@+id/ivArtistImage"
                    android:layout_width="match_parent"
                    android:layout_height="300dp"
                    android:scaleType="centerCrop"
                    android:src="@drawable/artist_thumbail"
                    app:layout_collapseMode="parallax"
                    app:layout_collapseParallaxMultiplier="0.7" />
                <com.google.android.material.appbar.MaterialToolbar
                    android:id="@+id/toolBar"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    app:navigationIcon="@drawable/baseline_arrow_back_ios_24"
                    app:layout_collapseMode="pin"
                    app:popupTheme="@style/Widget.Material3.PopupMenu.Overflow">

                </com.google.android.material.appbar.MaterialToolbar>
            </com.google.android.material.appbar.CollapsingToolbarLayout>
        </com.google.android.material.appbar.AppBarLayout>
        ......

In my fragment onCreateView:

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentArtistBinding.inflate(inflater, container, false)
        binding.toolBar.applyInsetter {
            type(statusBars = true) {
                padding()
            }
        }

        return binding.root
    }

My result:
image
image

Toolbar still be overlap
How to fix it? Thanks for make a best library

Request: Inset builder to have option to return the actual size

I am using https://github.com/cashapp/contour in a project and it would be nice to have something like

val actualStatusBarsSize  = Insetter.builder().valueTop(statusBars =true).build().value

There are probably other uses cases outside of using contour where this could be helpful like

val navBarSize  = Insetter.builder().valueTop(navigationBars =true).build().value
view1.updatePadding(0,navBarSize,0,0)
view2.updatePadding(0,navBarSize,0,0)

Support Insets for Android R

Hello
Are you planning to add support to this library of api inserts from Android 11? Or will it all be implemented in another library?

Thanks you

InsetterDsl -> Insetter.CONSUME_AUTO

Currently all we have is
fun consume(consume: Boolean) { builder = builder.consume(if (consume) Insetter.CONSUME_ALL else Insetter.CONSUME_NONE) }
And if I want to use Insetter.CONSUME_AUTO then I have to use builder.
Can we get this option via dsl pls?

Migration from 0.3.1 to 0.6.0

Just created functions with annotation @Deprecated and replaceWith expressions to make migration easier in simple cases.

@file:Suppress("PackageDirectoryMismatch", "unused")

package dev.chrisbanes.insetter

import android.view.View

@Deprecated(
    level = DeprecationLevel.ERROR,
    message = "Use applyInsetter instead",
    replaceWith = ReplaceWith(
        "this.applyInsetter { type(statusBars = top, navigationBars = bottom) { padding() } }",
        "dev.chrisbanes.insetter.applyInsetter"
    )
)
fun View.applySystemWindowInsetsToPadding(top: Boolean = false, bottom: Boolean = false) {
    error("should not be used")
}

@Deprecated(
    level = DeprecationLevel.ERROR,
    message = "Use applyInsetter instead",
    replaceWith = ReplaceWith(
        "this.applyInsetter { type(statusBars = top, navigationBars = bottom) { margin() } }",
        "dev.chrisbanes.insetter.applyInsetter"
    )
)
fun View.applySystemWindowInsetsToMargin(top: Boolean = false, bottom: Boolean = false) {
    error("should not be used")
}

object Insetter {
    @Deprecated(
        level = DeprecationLevel.ERROR,
        message = "Use WindowCompat.setDecorFitsSystemWindows() instead",
        replaceWith = ReplaceWith(
            "WindowCompat.setDecorFitsSystemWindows(window, !enabled)",
            "androidx.core.view.WindowCompat"
        )
    )
    fun setEdgeToEdgeSystemUiFlags(view: View, enabled: Boolean = true) {
        error("should not be used")
    }
}

Support for other popular view group

Hello!
Do you think it makes sense to add support for other popular view groups to the insetter-widgets module: FrameLayout, LinearLayout, etc.?

Request: add alternative to data-binding, in code

For each of those :
https://github.com/chrisbanes/insetter/blob/master/dbx/README.md

For example, we have paddingBottomSystemWindowInsets as attribute of data-binding.
I suggest we have it in code too.

Maybe like this in this case:

view.setPaddingSystemWindowInsets(bottom=true)

Or even better: handle both padding and margins together:

view.setPaddingAndMarginsSystemWindowInsets(Type.MARGIN_BOTTOM,Type.PADDING_LEFT,TYPE.PADDING_RIGHT...)

This will add the insets to the original padding and margins that were set before.

This way, in a single line we could handle an entire view's insets related stuff...

Keyboard inset padding and NestedScrollView

@chrisbanes hi!
A strange situation occurred while working with keyboard insets
If you install paddings from the keyboard for NestedScrollView, the view in focus does not remain visible, hiding behind the keyboard
How can you handle this scenario so that the EditText respects the keyboard that appears? Only by setting margins for NestedScrollView?

Activity and layout code is below

class MainActivity : AppCompatActivity(R.layout.activity_main) {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val rootView = findViewById<LinearLayout>(R.id.root_view)
        val nestedScroll = findViewById<NestedScrollView>(R.id.nested_scroll)
        val toolbar = findViewById<Toolbar>(R.id.toolbar)

        WindowCompat.setDecorFitsSystemWindows(window, false)

        Insetter.builder().setOnApplyInsetsListener { _, insets, _ ->
            toolbar.updatePadding(
                top = insets.getInsets(WindowInsetsCompat.Type.systemBars()).top
            )
            nestedScroll.updatePadding(
                bottom = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom + insets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom
            )
        }.applyToView(rootView)
    }
}

<androidx.appcompat.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:title="@string/app_name" />

<androidx.core.widget.NestedScrollView
    android:id="@+id/nested_scroll"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="750dp"
            android:layout_marginBottom="120dp"
            android:hint="This will be hide by the keyboard" />
    </LinearLayout>
</androidx.core.widget.NestedScrollView>
Recording_2021-02-09-12-11-05.mp4

Duplicate class dev.chrisbanes.insetter.DataBinderMapperImpl

This library doesn't appear to be working.

After just adding the library to the project:

implementation "dev.chrisbanes:insetter-dbx:0.2.0"

And then syncing Gradle files + rebuilding the project, we get the following errors:

Duplicate class dev.chrisbanes.insetter.DataBinderMapperImpl found in modules jetified-insetter-dbx-0.2.0-runtime.jar (dev.chrisbanes.insetter:insetter-dbx:0.2.0) and jetified-insetter-dbx-0.2.0-runtime.jar (dev.chrisbanes:insetter-dbx:0.2.0)
Duplicate class dev.chrisbanes.insetter.DataBinderMapperImpl$InnerBrLookup found in modules jetified-insetter-dbx-0.2.0-runtime.jar (dev.chrisbanes.insetter:insetter-dbx:0.2.0) and jetified-insetter-dbx-0.2.0-runtime.jar (dev.chrisbanes:insetter-dbx:0.2.0)
Duplicate class dev.chrisbanes.insetter.DataBinderMapperImpl$InnerLayoutIdLookup found in modules jetified-insetter-dbx-0.2.0-runtime.jar (dev.chrisbanes.insetter:insetter-dbx:0.2.0) and jetified-insetter-dbx-0.2.0-runtime.jar (dev.chrisbanes:insetter-dbx:0.2.0)
Duplicate class dev.chrisbanes.insetter.InsetterBindingAdapters found in modules jetified-insetter-dbx-0.2.0-runtime.jar (dev.chrisbanes.insetter:insetter-dbx:0.2.0) and jetified-insetter-dbx-0.2.0-runtime.jar (dev.chrisbanes:insetter-dbx:0.2.0)
Duplicate class dev.chrisbanes.insetter.InsetterBindingAdapters$1 found in modules jetified-insetter-dbx-0.2.0-runtime.jar (dev.chrisbanes.insetter:insetter-dbx:0.2.0) and jetified-insetter-dbx-0.2.0-runtime.jar (dev.chrisbanes:insetter-dbx:0.2.0)

The external libraries being fetched are the following:

Gradle: dev.chrisbanes.insetter:insetter:0.2.0@aar
Gradle: dev.chrisbanes.insetter:insetter-dbx:0.2.0@aar
Gradle: dev.chrisbanes.insetter:insetter-ktx:0.2.0@aar
Gradle: dev.chrisbanes.insetter:insetter-widgets:0.2.0@aar
Gradle: dev.chrisbanes:insetter:0.2.0@jar
Gradle: dev.chrisbanes:insetter-dbx:0.2.0@aar

Improvements in Insetter

  1. Very often with applying insets via doOnApplyWindowInsets using set content edge-to-edge. It would be nice to add a function like this:
inline fun View.setEdgeToEdgeContent() {
    if (ViewCompat.getFitsSystemWindows(this)) {
        systemUiVisibility =
                // Tells the system that you wish to be laid out
                // as if the navigation bar was hidden
            View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or
                    // Optional, if we want you be laid out fullscreen,
                    // behind the status bar
                    View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
                    // Tells the system that you wish to be laid out at
                    // the most extreme scenario of any other flags
                    View.SYSTEM_UI_FLAG_LAYOUT_STABLE
    }
}
  1. Also it would be nice make constructors in ViewState and ViewDimensions public to allow usage in customs options, like where need return consumed or modified insets.

  2. And also it would be nice provide opportunities to return modified insets, like this usecase:
    https://github.com/google/iosched/blob/4054aa3f8934b8b1208d5823fdbf531a8eb367af/mobile/src/main/java/com/google/samples/apps/iosched/ui/MainActivity.kt#L154

Request: Add a BottomSheetDialog example with a RecyclerView inside

Hi,
I'd be nice to have an example featuring a BottomSheetDialog, which would have views at the top of the layout, a RecyclerView with more items than can fit in the screen, and views in the bottom as well.

This would be very helpful to not just me as I failed to find how to do it right on the public web (and failed to do it right on my own, having views behind the SystemUI).

Warnings in build output

> Task :app:processDebugManifest
[dev.chrisbanes:insetter-ktx:0.2.0] /Users/coltonidle/.gradle/caches/transforms-2/files-2.1/9ee7ca0ad1b0e0be19f2cbb93fe9a9b4/jetified-insetter-ktx-0.2.0/AndroidManifest.xml Warning:
        Package name 'dev.chrisbanes.insetter' used in: dev.chrisbanes:insetter-ktx:0.2.0, dev.chrisbanes:insetter:0.2.0.
[androidx.navigation:navigation-runtime-ktx:2.2.0-rc03] /Users/coltonidle/.gradle/caches/transforms-2/files-2.1/e682aca97378e5c9a1eb9b8882f83385/navigation-runtime-ktx-2.2.0-rc03/AndroidManifest.xml Warning:
        Package name 'androidx.navigation.ktx' used in: androidx.navigation:navigation-runtime-ktx:2.2.0-rc03, androidx.navigation:navigation-common-ktx:2.2.0-rc03.

Noticed a bunch of these warnings in my build output and wanted to let you know.

Request: Remove insets

What:
Ability to remove insets on views.

Why
With some complex views sometimes we have to play with insets in order to match a specific design.
With Insetter it makes it super easy and clean to add insets, but we don't have the opportunity yet to remove an inset that was previously applied.

Would it make sense to have a feature like this?

Thanks a lot in advance!

Ability to adjust applied paddings/margins before applying them to a view

Desired feature

Whenever new insets are applied I want to be able to adjust them. That's especially useful if insets do depend on user settings, e.g. I may change paddings/margins of a view if the user changes a setting and in such cases, I can't use insetter.

Example

Consider a list that always expands behind the navigation bar and an optional "dock" above the navigation bar. If the dock is visible, the content list needs more bottom padding than if the dock is not visible to allow that all items can be scrolled up to the interactable region...

Currently I have to do everything fully manually like following:

Insetter.builder()
            .padding(windowInsetTypesOf(navigationBars = true))
            .setOnApplyInsetsListener { view, insets, initialState ->
                val extraPadding = if (Prefs.desktopDock.value) { 48.dpToPx } else 0
                view.updatePadding(bottom = insets.getInsets(WindowInsets.Type.navigationBars()).bottom + initialState.paddings.bottom + extraPadding)
                L.tag("DESKTOP").d { "LISTENER: Padding Bottom: ${view.paddingBottom}" }
            }
            .applyToView(binding.rvData)

Suggestion

Maybe you can add an optional hook that can adjust paddings/margins before applying them. Something that can adjust the values before applying them in following 2 places:

setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom)

if (lp.updateMargins(marginLeft, marginTop, marginRight, marginBottom)) {

Issues applying to margins after updating to 0.5.0

Upgraded to the 0.5.0 from 0.3.1

Code was this

   recycler.applySystemWindowInsetsToMargin(top = true)
  recycler.applySystemGestureInsetsToPadding(bottom = true)

and is now this

recycler.applyInsetter {
                type(systemGestures = true) {
                    padding(bottom = true)
                }
                type(statusBars = true) {
                    margin(top = true)
                }
            }

I have to apply the statusbars to margin top or else it fails

View's LayoutParams do not extend MarginLayoutParams errors since updating
java.lang.IllegalArgumentException: Margin window insets handling requested but View's LayoutParams do not extend MarginLayoutParams

Bug: Custom listener + consuming insets

In method applyToView and checking for custom listener, there's probably a bug with checking if insets should be consumed.

return@setOnApplyWindowInsetsListener if (consume != CONSUME_NONE) insets

The problem is in the if condition - it should be reverted and therefore if(consume == CONSUME_NONE) insets else WindowInsetsCompat.CONSUMED because when none consumed, then we should return the initial insets, right?

This breaks insetter when custom listener is applied somewhere in the view hierarchy.

Request: CONSUME_AUTO support in Kotlin DSL

Right now using Kotlin DSL possible only if I use consume with boolean arg, like this:

view.applyInsetter {
    consume(false)
}

witch equals CONSUME_ALL or CONSUME_NONE, but in some cases I need CONSUME_AUTO, like this:

        Insetter.builder()
            .applySystemWindowInsetsToPadding(Side.RIGHT or Side.LEFT)
            .consumeSystemWindowInsets(Insetter.CONSUME_AUTO)
            .applyToView(view)

and is impossible with Kotlin DSL :(

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.