Code Monkey home page Code Monkey logo

Comments (9)

WieFel avatar WieFel commented on June 24, 2024 1

Hi @pishguy, thanks for opening the issue.
Please check this section of the readme, where we describe that you can't directly access the Backdrop.of(context) within the same widget context, in which you create the BackdropScaffold.

You

  1. either need to put the use of Backdrop.of(context) into a separate widget (i.e. create a new StatelessWidget and put the GestureDetector stuff into it), or
  2. you wrap your GestureDetector (in this case) in a Builder widget. Like that you have a "new" context, from which you can access Backdrop.of(context)

from backdrop.

WieFel avatar WieFel commented on June 24, 2024 1

I created a small example app for you, which does the following:

  1. There is a home page, which redirects to a page which has a BackdropScaffold
  2. The front layer is "hidden" at start. It can be shown with a button placed on the back layer.
  3. When pressing the back button, or pressing the back arrow in the app bar, it is possible to navigate back to the home page.
import 'package:backdrop/backdrop.dart';
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Backdrop Demo',
      home: Scaffold(
        appBar: AppBar(
          title: const Text("My App"),
        ),
        body: Center(
          // Builder necessary here to be able to use Navigator.push (as we are in the same widget as
          // our MaterialApp)
          child: Builder(builder: (context) {
            return ElevatedButton(
              child: const Text("Open Backdrop Page"),
              onPressed: () => Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => const MyCustomPage(),
                ),
              ),
            );
          }),
        ),
      ),
    );
  }
}

class MyCustomPage extends StatelessWidget {
  const MyCustomPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return BackdropScaffold(
      appBar: AppBar(
        title: const Text("Backdrop Example"),
      ),
      concealBacklayerOnBackButton: false,
      revealBackLayerAtStart: true,
      backLayerBackgroundColor: Colors.grey.shade300,
      backLayer: Center(
        // Builder necessary here to be able to call Backdrop.of(context), as we are inside the same
        // widget as our BackdropScaffold
        child: Builder(
          builder: (context) {
            return ElevatedButton(
              onPressed: () => Backdrop.of(context).concealBackLayer(),
              child: const Text("Conceal Back Layer"),
            );
          },
        ),
      ),
      subHeader: const BackdropSubHeader(
        title: Text("Sub Header"),
      ),
      frontLayer: const Center(
        child: Text("Front Layer"),
      ),
    );
  }
}

In my opinion, it should not be necessary to make any change to the library for this.
Hope this helps...

from backdrop.

WieFel avatar WieFel commented on June 24, 2024 1

Yes, but you need to put it in the correct place. As I said, it needs to be BELOW the BackdropScaffold in the widget tree. Otherwise, Backdrop.of(context) won't find anything...

from backdrop.

pishguy avatar pishguy commented on June 24, 2024

@WieFel hi again :)

could you help me whats the correct context in this code? i want to close Backdrop manually:

using Builder context:

return ValueListenableBuilder<bool>(
  valueListenable: wm.bottomSheetVisibility,
  builder: (_, bool visibility, __) {
    return Builder(
      builder: (context) {
        return WillPopScope(
          onWillPop: () async {
            if (visibility) {
              wm.onChangeBottomSheetVisibility(context: context, visibility: false);
              return Future.value(false);
            }
            wm.onChangeBottomSheetVisibility(context: context, visibility: true);
            return Future.value(true);
          },
          child: BackdropScaffold(
            revealBackLayerAtStart: true,
            frontLayerActiveFactor: .9,
            resizeToAvoidBottomInset: false,
            onBackLayerConcealed: () {
              wm.bottomSheetVisibility.value = true;
            },
            onBackLayerRevealed: () {
              wm.bottomSheetVisibility.value = false;
            },

onChangeBottomSheetVisibility method:

  void onChangeBottomSheetVisibility({
    required BuildContext context,
    required bool visibility,
  }) {
    bottomSheetVisibility.value = visibility;
    Backdrop.of(context).fling();
  }

using ValueListenableBuilder context:

return ValueListenableBuilder<bool>(
  valueListenable: wm.bottomSheetVisibility,
  builder: (context, bool visibility, __) {
    return WillPopScope(
      onWillPop: () async {
        if (visibility) {
          wm.onChangeBottomSheetVisibility(context: context, visibility: false);
          return Future.value(false);
        }
        wm.onChangeBottomSheetVisibility(context: context, visibility: true);
        return Future.value(true);
      },
      child: BackdropScaffold(

using the widget context:

builder: (_, bool visibility, __) {
  return WillPopScope(
    onWillPop: () async {
      if (visibility) {
        wm.onChangeBottomSheetVisibility(visibility: false);
        return Future.value(false);
      }
      wm.onChangeBottomSheetVisibility(visibility: true);
      return Future.value(true);
    },

onChangeBottomSheetVisibility method:

void onChangeBottomSheetVisibility({required bool visibility}) {
    bottomSheetVisibility.value = visibility;
    Backdrop.of(context).fling();
  }

i'm opening frontLayer by clicking on subHeader widget, thanks so much

from backdrop.

WieFel avatar WieFel commented on June 24, 2024

I think the problem here is that the context that you pass to Backdrop.of(context).fling(); in all cases is not the correct one. They are ALL from "above" (outside) the BackdropScaffold. But what you need is a context from ONE LEVEL BELOW the BackdropScaffold.

So, having the ValueListenableBuilder inside the BackdropScaffold (e.g. in the body, if possible) would solve the problem in my opinion. Then, you wouldn't even need an additional Builder, but using the context of the ValueListenableBuilder would be enough.

from backdrop.

pishguy avatar pishguy commented on June 24, 2024

@WieFel if i put ValueListenableBuilder inside BackdropScaffold how can i close frontLayer manually with WillPopScope?

my widget has a default context and i tested that before.

is this your meant?

@override
Widget build(ILocationScreenWidgetModel wm) {
  return ValueListenableBuilder<bool>(
    valueListenable: wm.bottomSheetVisibility,
    builder: (context, bool visibility, __) {
      return WillPopScope(
        onWillPop: () async {
          if (visibility) {
            wm.bottomSheetVisibility.value = false;
            Backdrop.of(context).fling();
            return Future.value(false);
          }
          wm.bottomSheetVisibility.value = true;
          return Future.value(true);
        },
        child: BackdropScaffold(
          ...
          onBackLayerConcealed: () {
            wm.bottomSheetVisibility.value = true;
          },
          onBackLayerRevealed: () {
            wm.bottomSheetVisibility.value = false;
          },

problem is closing the frontLayer inside WillPopScope widget not inside of subHeader

return ValueListenableBuilder<bool>(
  valueListenable: wm.bottomSheetVisibility,
  builder: (_, bool visibility, __) {
    return Builder(
      builder: (context) {
        return WillPopScope(
          onWillPop: () async {
            if (visibility) {
              wm.bottomSheetVisibility.value = false;
              Backdrop.of(context).fling();
              return Future.value(false);
            }
            wm.bottomSheetVisibility.value = true;
            return Future.value(true);
          },
          child: BackdropScaffold(
            //...
            subHeader: BackdropSubHeader(
              leading: Builder(
                builder: (context) {
                  return IconButton(
                    onPressed: () => Backdrop.of(context).fling(),
                    icon: const Icon(Icons.close_rounded),
                  );
                },
              ),

from backdrop.

WieFel avatar WieFel commented on June 24, 2024

Could you briefly explain again what you are trying to achieve?
I am a bit confused... Could you maybe provide a simpler example of what your use case is?

as far as I understand, you have the following:

  1. you have a BackdropScaffold with an initially "open" front layer (?)
  2. you want to close the front layer (conceal the back layer) on some event

is that correct?

from backdrop.

pishguy avatar pishguy commented on June 24, 2024

@WieFel

In the default state, the frontLayer widget is hidden, and when I click a button, its state changes to visible. The first fundamental issue was that when I pressed the back button on the phone, I expected to be able to return the frontLayer widget to the hidden state, which was not happening.

The second issue is that when the frontLayer widget is in the hidden state, I should be able to return to the previous screen by clicking the back button.

These two states were not implementable outside of the library, so I modified the library itself to address these issues.

please check this pull request: #135

from backdrop.

pishguy avatar pishguy commented on June 24, 2024

@WieFel i checked your code, thanks

closing frontLayer doesn't work every where such as my project, i tires to use Builder but it couldn't resolve py problem

from backdrop.

Related Issues (20)

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.