Android “Top Sheet” equivalent of “Bottom Sheet”?












10















I am wanting to implement a "Bottom Sheet" type of layout, but with a twist where the "bottom" sheet will be a MapFragment, which won't work very well as an up/down draggable view.



I had a probably naive thought to "flip" the logic to a "Top Sheet" design, where you drag the Top Sheet up/down to show more/less of the bottom MapFragment.



ie: From this...
Bottom Sheet Example



...to [something like] this...
Top Sheet Example



Is this possible given the Support Design Tools, or will I have to roll something like this on my own?










share|improve this question


















  • 3





    I think you are going to sign up to do a substantial amount of heavy lifting to do two things. First, to create your custom implementation. Second, to identify how your implementation conflicts with the android implementation and to defend against those scenarios. My personal opinion, the Material Design Language has been put in place to visually communicate the ways your users can expect to interact with the app. Something like this may be great as a personal endeavour for learning, but once you hit the market - you need to expect that every single person won't understand how to use your app.

    – apelsoczi
    Aug 22 '16 at 20:44













  • I ended up just adding a bottomsheet layout that has a Toolbar at its top that allows the user to drag the toolbar up. The trick is then to resize the Map as the user drags the toolbar. I can post my code if anyone is interested.

    – swooby
    Sep 9 '16 at 21:08











  • I'd like to see it @swooby, I'm trying to do something similar

    – odiggity
    Nov 18 '16 at 17:26











  • @odiggity you can check my answer, I finally made it working exactly as the BottomSheetBehavior, but from the top.

    – Carlos Alberto Martínez Gadea
    Nov 21 '18 at 11:17
















10















I am wanting to implement a "Bottom Sheet" type of layout, but with a twist where the "bottom" sheet will be a MapFragment, which won't work very well as an up/down draggable view.



I had a probably naive thought to "flip" the logic to a "Top Sheet" design, where you drag the Top Sheet up/down to show more/less of the bottom MapFragment.



ie: From this...
Bottom Sheet Example



...to [something like] this...
Top Sheet Example



Is this possible given the Support Design Tools, or will I have to roll something like this on my own?










share|improve this question


















  • 3





    I think you are going to sign up to do a substantial amount of heavy lifting to do two things. First, to create your custom implementation. Second, to identify how your implementation conflicts with the android implementation and to defend against those scenarios. My personal opinion, the Material Design Language has been put in place to visually communicate the ways your users can expect to interact with the app. Something like this may be great as a personal endeavour for learning, but once you hit the market - you need to expect that every single person won't understand how to use your app.

    – apelsoczi
    Aug 22 '16 at 20:44













  • I ended up just adding a bottomsheet layout that has a Toolbar at its top that allows the user to drag the toolbar up. The trick is then to resize the Map as the user drags the toolbar. I can post my code if anyone is interested.

    – swooby
    Sep 9 '16 at 21:08











  • I'd like to see it @swooby, I'm trying to do something similar

    – odiggity
    Nov 18 '16 at 17:26











  • @odiggity you can check my answer, I finally made it working exactly as the BottomSheetBehavior, but from the top.

    – Carlos Alberto Martínez Gadea
    Nov 21 '18 at 11:17














10












10








10


1






I am wanting to implement a "Bottom Sheet" type of layout, but with a twist where the "bottom" sheet will be a MapFragment, which won't work very well as an up/down draggable view.



I had a probably naive thought to "flip" the logic to a "Top Sheet" design, where you drag the Top Sheet up/down to show more/less of the bottom MapFragment.



ie: From this...
Bottom Sheet Example



...to [something like] this...
Top Sheet Example



Is this possible given the Support Design Tools, or will I have to roll something like this on my own?










share|improve this question














I am wanting to implement a "Bottom Sheet" type of layout, but with a twist where the "bottom" sheet will be a MapFragment, which won't work very well as an up/down draggable view.



I had a probably naive thought to "flip" the logic to a "Top Sheet" design, where you drag the Top Sheet up/down to show more/less of the bottom MapFragment.



ie: From this...
Bottom Sheet Example



...to [something like] this...
Top Sheet Example



Is this possible given the Support Design Tools, or will I have to roll something like this on my own?







android bottom-sheet






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Aug 22 '16 at 20:34









swoobyswooby

1,7712431




1,7712431








  • 3





    I think you are going to sign up to do a substantial amount of heavy lifting to do two things. First, to create your custom implementation. Second, to identify how your implementation conflicts with the android implementation and to defend against those scenarios. My personal opinion, the Material Design Language has been put in place to visually communicate the ways your users can expect to interact with the app. Something like this may be great as a personal endeavour for learning, but once you hit the market - you need to expect that every single person won't understand how to use your app.

    – apelsoczi
    Aug 22 '16 at 20:44













  • I ended up just adding a bottomsheet layout that has a Toolbar at its top that allows the user to drag the toolbar up. The trick is then to resize the Map as the user drags the toolbar. I can post my code if anyone is interested.

    – swooby
    Sep 9 '16 at 21:08











  • I'd like to see it @swooby, I'm trying to do something similar

    – odiggity
    Nov 18 '16 at 17:26











  • @odiggity you can check my answer, I finally made it working exactly as the BottomSheetBehavior, but from the top.

    – Carlos Alberto Martínez Gadea
    Nov 21 '18 at 11:17














  • 3





    I think you are going to sign up to do a substantial amount of heavy lifting to do two things. First, to create your custom implementation. Second, to identify how your implementation conflicts with the android implementation and to defend against those scenarios. My personal opinion, the Material Design Language has been put in place to visually communicate the ways your users can expect to interact with the app. Something like this may be great as a personal endeavour for learning, but once you hit the market - you need to expect that every single person won't understand how to use your app.

    – apelsoczi
    Aug 22 '16 at 20:44













  • I ended up just adding a bottomsheet layout that has a Toolbar at its top that allows the user to drag the toolbar up. The trick is then to resize the Map as the user drags the toolbar. I can post my code if anyone is interested.

    – swooby
    Sep 9 '16 at 21:08











  • I'd like to see it @swooby, I'm trying to do something similar

    – odiggity
    Nov 18 '16 at 17:26











  • @odiggity you can check my answer, I finally made it working exactly as the BottomSheetBehavior, but from the top.

    – Carlos Alberto Martínez Gadea
    Nov 21 '18 at 11:17








3




3





I think you are going to sign up to do a substantial amount of heavy lifting to do two things. First, to create your custom implementation. Second, to identify how your implementation conflicts with the android implementation and to defend against those scenarios. My personal opinion, the Material Design Language has been put in place to visually communicate the ways your users can expect to interact with the app. Something like this may be great as a personal endeavour for learning, but once you hit the market - you need to expect that every single person won't understand how to use your app.

– apelsoczi
Aug 22 '16 at 20:44







I think you are going to sign up to do a substantial amount of heavy lifting to do two things. First, to create your custom implementation. Second, to identify how your implementation conflicts with the android implementation and to defend against those scenarios. My personal opinion, the Material Design Language has been put in place to visually communicate the ways your users can expect to interact with the app. Something like this may be great as a personal endeavour for learning, but once you hit the market - you need to expect that every single person won't understand how to use your app.

– apelsoczi
Aug 22 '16 at 20:44















I ended up just adding a bottomsheet layout that has a Toolbar at its top that allows the user to drag the toolbar up. The trick is then to resize the Map as the user drags the toolbar. I can post my code if anyone is interested.

– swooby
Sep 9 '16 at 21:08





I ended up just adding a bottomsheet layout that has a Toolbar at its top that allows the user to drag the toolbar up. The trick is then to resize the Map as the user drags the toolbar. I can post my code if anyone is interested.

– swooby
Sep 9 '16 at 21:08













I'd like to see it @swooby, I'm trying to do something similar

– odiggity
Nov 18 '16 at 17:26





I'd like to see it @swooby, I'm trying to do something similar

– odiggity
Nov 18 '16 at 17:26













@odiggity you can check my answer, I finally made it working exactly as the BottomSheetBehavior, but from the top.

– Carlos Alberto Martínez Gadea
Nov 21 '18 at 11:17





@odiggity you can check my answer, I finally made it working exactly as the BottomSheetBehavior, but from the top.

– Carlos Alberto Martínez Gadea
Nov 21 '18 at 11:17












2 Answers
2






active

oldest

votes


















2














Here is the basis of my solution that I commented about above.
I will come back and flesh it out later.



@Override
protected void onCreate(
@Nullable
Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if (isFinishing())
{
return;
}


setContentView(R.layout.activity_home);

...

mGroupBottomSheetFiller = (ViewGroup) findViewById(R.id.groupBottomSheetFiller);

final NestedScrollView bottomSheetMap = (NestedScrollView) findViewById(R.id.bottomSheetMap);
mBottomSheetMapBehavior = BottomSheetBehavior.from(bottomSheetMap);
mBottomSheetMapBehavior.setBottomSheetCallback(new BottomSheetCallback()
{
@Override
public void onStateChanged(
@NonNull
View bottomSheet,
int newState)
{
//Log.e(TAG, "mBottomSheetMapBehavior.onStateChanged(bottomSheet, newState=" +
// bottomSheetBehaviorStateToString(newState) + ')');
int visibility = isBottomSheetExpanded(mBottomSheetMapBehavior) ? View.VISIBLE : View.GONE;
mImageBottomSheetMapClose.setVisibility(visibility);
}

@Override
public void onSlide(
@NonNull
View bottomSheet,
float slideOffset)
{
//Log.e(TAG, "mBottomSheetMapBehavior.onStateChanged(bottomSheet, slideOffset=" + slideOffset + ')');
resizeMap();
}
});
bottomSheetMap.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener()
{
@Override
public void onGlobalLayout()
{
//Log.e(TAG, "onGlobalLayout()");
bottomSheetMap.getViewTreeObserver().removeOnGlobalLayoutListener(this);
resizeMap();
}
});

...
}

private void resizeMap()
{
int screenHeightPixels = PbPlatformUtils.getScreenHeightPixels();
//Log.e(TAG, "resizeMap: screenHeightPixels=" + screenHeightPixels);

int location = new int[2];
mGroupMap.getLocationInWindow(location);
//Log.e(TAG, "resizeMap: getLocationInWindow=" + Arrays.toString(location));

LayoutParams groupMapLayoutParams = mGroupMap.getLayoutParams();
groupMapLayoutParams.height = screenHeightPixels - location[1];
mGroupMap.requestLayout();
}

public static String bottomSheetBehaviorStateToString(int state)
{
String s;
switch (state)
{
case BottomSheetBehavior.STATE_COLLAPSED:
s = "STATE_COLLAPSED";
break;
case BottomSheetBehavior.STATE_DRAGGING:
s = "STATE_DRAGGING";
break;
case BottomSheetBehavior.STATE_EXPANDED:
s = "STATE_EXPANDED";
break;
case BottomSheetBehavior.STATE_HIDDEN:
s = "STATE_HIDDEN";
break;
case BottomSheetBehavior.STATE_SETTLING:
s = "STATE_SETTLING";
break;
default:
s = "UNKNOWN";
break;
}
return s + '(' + state + ')';
}

private static boolean isBottomSheetExpanded(
@NonNull
BottomSheetBehavior bottomSheetBehavior)
{
return bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED;
}

private void bottomSheetMapExpand()
{
mGroupBottomSheetFiller.setVisibility(View.VISIBLE);
int peekHeightPx = getResources().getDimensionPixelSize(R.dimen.home_bottom_sheet_map_peek_height);
mBottomSheetMapBehavior.setPeekHeight(peekHeightPx);
mBottomSheetMapBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
mBottomSheetMapBehavior.setHideable(false);
}

private void bottomSheetMapCollapse()
{
mGroupBottomSheetFiller.setVisibility(View.VISIBLE);
int peekHeightPx = getResources().getDimensionPixelSize(R.dimen.home_bottom_sheet_map_peek_height);
mBottomSheetMapBehavior.setPeekHeight(peekHeightPx);
mBottomSheetMapBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
mBottomSheetMapBehavior.setHideable(false);
}

private void bottomSheetMapHide()
{
mBottomSheetMapBehavior.setHideable(true);
mBottomSheetMapBehavior.setPeekHeight(0);
mBottomSheetMapBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
mGroupBottomSheetFiller.setVisibility(View.GONE);
}





share|improve this answer



















  • 1





    did you encounter compatibility issues with this solution? in case you have a working app in the playstore using this functionality it'd be great to check it out :)

    – carlosavoy
    May 29 '17 at 15:33













  • You can check my answer @swooby , perhaps it's nearer to what you were looking for. At least, it behaves exactly as I imagined a TopSheet to be equivalent to a BottomSheetBehavior.

    – Carlos Alberto Martínez Gadea
    Nov 21 '18 at 11:18











  • Looks good @CarlosAlbertoMartínezGadea, but the implementation in my answer current fits my needs for an existing production app, so I haven't experimented with porting over to yours. If I do one day I'll mark yours as the preferred answer! Thanks!

    – swooby
    Nov 27 '18 at 21:07



















2














This TopSheetBehavior implementation ( https://github.com/MedveDomg/AndroidTopSheet/blob/master/library/src/main/java/com/github/techisfun/android/topsheet/TopSheetBehavior.java ) has proved to work pretty well in my case. I found many other TopSheetBehavior that were incomplete or that crashed, but this one doesn't crash and works out of the box by only replacing the behavior parameter:



<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:behavior_hideable="true"
app:behavior_peekHeight="56dp"
app:layout_behavior="your.package.components.TopSheetBehavior">

<!-- Your content goes here -->

</LinearLayout>





share|improve this answer


























  • That's the perfect way to do that. It's working smoothly and fine.

    – Dheeraj Rijhwani
    Nov 20 '18 at 18:05











  • Can I use this exact solution in closed source project? Or should I provide some references?

    – Viktor Vostrikov
    Dec 23 '18 at 15:08











  • @ViktorVostrikov yes, you can. It's under the Apache license. Here you have a few questions answered about the usage of code under the Apache license: resources.whitesourcesoftware.com/blog-whitesource/…

    – Carlos Alberto Martínez Gadea
    Dec 24 '18 at 11:01











  • @CarlosAlbertoMartínezGadea however it is stated that I need to still write somehow the owner of the library.. Don't know there should I provide credentials..

    – Viktor Vostrikov
    Dec 24 '18 at 11:17











  • @ViktorVostrikov to me, the phrase "If you redistribute software with any Apache licensed components, you must include a copy of the license, provide a clear Apache License attribution, and add modification notices to all the files that you modify." explains the situation quite clearly. You don't need to contact the author of the code but you must show that you are using the Apache License, with a link to that license.

    – Carlos Alberto Martínez Gadea
    Dec 24 '18 at 12:32











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f39088269%2fandroid-top-sheet-equivalent-of-bottom-sheet%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









2














Here is the basis of my solution that I commented about above.
I will come back and flesh it out later.



@Override
protected void onCreate(
@Nullable
Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if (isFinishing())
{
return;
}


setContentView(R.layout.activity_home);

...

mGroupBottomSheetFiller = (ViewGroup) findViewById(R.id.groupBottomSheetFiller);

final NestedScrollView bottomSheetMap = (NestedScrollView) findViewById(R.id.bottomSheetMap);
mBottomSheetMapBehavior = BottomSheetBehavior.from(bottomSheetMap);
mBottomSheetMapBehavior.setBottomSheetCallback(new BottomSheetCallback()
{
@Override
public void onStateChanged(
@NonNull
View bottomSheet,
int newState)
{
//Log.e(TAG, "mBottomSheetMapBehavior.onStateChanged(bottomSheet, newState=" +
// bottomSheetBehaviorStateToString(newState) + ')');
int visibility = isBottomSheetExpanded(mBottomSheetMapBehavior) ? View.VISIBLE : View.GONE;
mImageBottomSheetMapClose.setVisibility(visibility);
}

@Override
public void onSlide(
@NonNull
View bottomSheet,
float slideOffset)
{
//Log.e(TAG, "mBottomSheetMapBehavior.onStateChanged(bottomSheet, slideOffset=" + slideOffset + ')');
resizeMap();
}
});
bottomSheetMap.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener()
{
@Override
public void onGlobalLayout()
{
//Log.e(TAG, "onGlobalLayout()");
bottomSheetMap.getViewTreeObserver().removeOnGlobalLayoutListener(this);
resizeMap();
}
});

...
}

private void resizeMap()
{
int screenHeightPixels = PbPlatformUtils.getScreenHeightPixels();
//Log.e(TAG, "resizeMap: screenHeightPixels=" + screenHeightPixels);

int location = new int[2];
mGroupMap.getLocationInWindow(location);
//Log.e(TAG, "resizeMap: getLocationInWindow=" + Arrays.toString(location));

LayoutParams groupMapLayoutParams = mGroupMap.getLayoutParams();
groupMapLayoutParams.height = screenHeightPixels - location[1];
mGroupMap.requestLayout();
}

public static String bottomSheetBehaviorStateToString(int state)
{
String s;
switch (state)
{
case BottomSheetBehavior.STATE_COLLAPSED:
s = "STATE_COLLAPSED";
break;
case BottomSheetBehavior.STATE_DRAGGING:
s = "STATE_DRAGGING";
break;
case BottomSheetBehavior.STATE_EXPANDED:
s = "STATE_EXPANDED";
break;
case BottomSheetBehavior.STATE_HIDDEN:
s = "STATE_HIDDEN";
break;
case BottomSheetBehavior.STATE_SETTLING:
s = "STATE_SETTLING";
break;
default:
s = "UNKNOWN";
break;
}
return s + '(' + state + ')';
}

private static boolean isBottomSheetExpanded(
@NonNull
BottomSheetBehavior bottomSheetBehavior)
{
return bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED;
}

private void bottomSheetMapExpand()
{
mGroupBottomSheetFiller.setVisibility(View.VISIBLE);
int peekHeightPx = getResources().getDimensionPixelSize(R.dimen.home_bottom_sheet_map_peek_height);
mBottomSheetMapBehavior.setPeekHeight(peekHeightPx);
mBottomSheetMapBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
mBottomSheetMapBehavior.setHideable(false);
}

private void bottomSheetMapCollapse()
{
mGroupBottomSheetFiller.setVisibility(View.VISIBLE);
int peekHeightPx = getResources().getDimensionPixelSize(R.dimen.home_bottom_sheet_map_peek_height);
mBottomSheetMapBehavior.setPeekHeight(peekHeightPx);
mBottomSheetMapBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
mBottomSheetMapBehavior.setHideable(false);
}

private void bottomSheetMapHide()
{
mBottomSheetMapBehavior.setHideable(true);
mBottomSheetMapBehavior.setPeekHeight(0);
mBottomSheetMapBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
mGroupBottomSheetFiller.setVisibility(View.GONE);
}





share|improve this answer



















  • 1





    did you encounter compatibility issues with this solution? in case you have a working app in the playstore using this functionality it'd be great to check it out :)

    – carlosavoy
    May 29 '17 at 15:33













  • You can check my answer @swooby , perhaps it's nearer to what you were looking for. At least, it behaves exactly as I imagined a TopSheet to be equivalent to a BottomSheetBehavior.

    – Carlos Alberto Martínez Gadea
    Nov 21 '18 at 11:18











  • Looks good @CarlosAlbertoMartínezGadea, but the implementation in my answer current fits my needs for an existing production app, so I haven't experimented with porting over to yours. If I do one day I'll mark yours as the preferred answer! Thanks!

    – swooby
    Nov 27 '18 at 21:07
















2














Here is the basis of my solution that I commented about above.
I will come back and flesh it out later.



@Override
protected void onCreate(
@Nullable
Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if (isFinishing())
{
return;
}


setContentView(R.layout.activity_home);

...

mGroupBottomSheetFiller = (ViewGroup) findViewById(R.id.groupBottomSheetFiller);

final NestedScrollView bottomSheetMap = (NestedScrollView) findViewById(R.id.bottomSheetMap);
mBottomSheetMapBehavior = BottomSheetBehavior.from(bottomSheetMap);
mBottomSheetMapBehavior.setBottomSheetCallback(new BottomSheetCallback()
{
@Override
public void onStateChanged(
@NonNull
View bottomSheet,
int newState)
{
//Log.e(TAG, "mBottomSheetMapBehavior.onStateChanged(bottomSheet, newState=" +
// bottomSheetBehaviorStateToString(newState) + ')');
int visibility = isBottomSheetExpanded(mBottomSheetMapBehavior) ? View.VISIBLE : View.GONE;
mImageBottomSheetMapClose.setVisibility(visibility);
}

@Override
public void onSlide(
@NonNull
View bottomSheet,
float slideOffset)
{
//Log.e(TAG, "mBottomSheetMapBehavior.onStateChanged(bottomSheet, slideOffset=" + slideOffset + ')');
resizeMap();
}
});
bottomSheetMap.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener()
{
@Override
public void onGlobalLayout()
{
//Log.e(TAG, "onGlobalLayout()");
bottomSheetMap.getViewTreeObserver().removeOnGlobalLayoutListener(this);
resizeMap();
}
});

...
}

private void resizeMap()
{
int screenHeightPixels = PbPlatformUtils.getScreenHeightPixels();
//Log.e(TAG, "resizeMap: screenHeightPixels=" + screenHeightPixels);

int location = new int[2];
mGroupMap.getLocationInWindow(location);
//Log.e(TAG, "resizeMap: getLocationInWindow=" + Arrays.toString(location));

LayoutParams groupMapLayoutParams = mGroupMap.getLayoutParams();
groupMapLayoutParams.height = screenHeightPixels - location[1];
mGroupMap.requestLayout();
}

public static String bottomSheetBehaviorStateToString(int state)
{
String s;
switch (state)
{
case BottomSheetBehavior.STATE_COLLAPSED:
s = "STATE_COLLAPSED";
break;
case BottomSheetBehavior.STATE_DRAGGING:
s = "STATE_DRAGGING";
break;
case BottomSheetBehavior.STATE_EXPANDED:
s = "STATE_EXPANDED";
break;
case BottomSheetBehavior.STATE_HIDDEN:
s = "STATE_HIDDEN";
break;
case BottomSheetBehavior.STATE_SETTLING:
s = "STATE_SETTLING";
break;
default:
s = "UNKNOWN";
break;
}
return s + '(' + state + ')';
}

private static boolean isBottomSheetExpanded(
@NonNull
BottomSheetBehavior bottomSheetBehavior)
{
return bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED;
}

private void bottomSheetMapExpand()
{
mGroupBottomSheetFiller.setVisibility(View.VISIBLE);
int peekHeightPx = getResources().getDimensionPixelSize(R.dimen.home_bottom_sheet_map_peek_height);
mBottomSheetMapBehavior.setPeekHeight(peekHeightPx);
mBottomSheetMapBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
mBottomSheetMapBehavior.setHideable(false);
}

private void bottomSheetMapCollapse()
{
mGroupBottomSheetFiller.setVisibility(View.VISIBLE);
int peekHeightPx = getResources().getDimensionPixelSize(R.dimen.home_bottom_sheet_map_peek_height);
mBottomSheetMapBehavior.setPeekHeight(peekHeightPx);
mBottomSheetMapBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
mBottomSheetMapBehavior.setHideable(false);
}

private void bottomSheetMapHide()
{
mBottomSheetMapBehavior.setHideable(true);
mBottomSheetMapBehavior.setPeekHeight(0);
mBottomSheetMapBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
mGroupBottomSheetFiller.setVisibility(View.GONE);
}





share|improve this answer



















  • 1





    did you encounter compatibility issues with this solution? in case you have a working app in the playstore using this functionality it'd be great to check it out :)

    – carlosavoy
    May 29 '17 at 15:33













  • You can check my answer @swooby , perhaps it's nearer to what you were looking for. At least, it behaves exactly as I imagined a TopSheet to be equivalent to a BottomSheetBehavior.

    – Carlos Alberto Martínez Gadea
    Nov 21 '18 at 11:18











  • Looks good @CarlosAlbertoMartínezGadea, but the implementation in my answer current fits my needs for an existing production app, so I haven't experimented with porting over to yours. If I do one day I'll mark yours as the preferred answer! Thanks!

    – swooby
    Nov 27 '18 at 21:07














2












2








2







Here is the basis of my solution that I commented about above.
I will come back and flesh it out later.



@Override
protected void onCreate(
@Nullable
Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if (isFinishing())
{
return;
}


setContentView(R.layout.activity_home);

...

mGroupBottomSheetFiller = (ViewGroup) findViewById(R.id.groupBottomSheetFiller);

final NestedScrollView bottomSheetMap = (NestedScrollView) findViewById(R.id.bottomSheetMap);
mBottomSheetMapBehavior = BottomSheetBehavior.from(bottomSheetMap);
mBottomSheetMapBehavior.setBottomSheetCallback(new BottomSheetCallback()
{
@Override
public void onStateChanged(
@NonNull
View bottomSheet,
int newState)
{
//Log.e(TAG, "mBottomSheetMapBehavior.onStateChanged(bottomSheet, newState=" +
// bottomSheetBehaviorStateToString(newState) + ')');
int visibility = isBottomSheetExpanded(mBottomSheetMapBehavior) ? View.VISIBLE : View.GONE;
mImageBottomSheetMapClose.setVisibility(visibility);
}

@Override
public void onSlide(
@NonNull
View bottomSheet,
float slideOffset)
{
//Log.e(TAG, "mBottomSheetMapBehavior.onStateChanged(bottomSheet, slideOffset=" + slideOffset + ')');
resizeMap();
}
});
bottomSheetMap.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener()
{
@Override
public void onGlobalLayout()
{
//Log.e(TAG, "onGlobalLayout()");
bottomSheetMap.getViewTreeObserver().removeOnGlobalLayoutListener(this);
resizeMap();
}
});

...
}

private void resizeMap()
{
int screenHeightPixels = PbPlatformUtils.getScreenHeightPixels();
//Log.e(TAG, "resizeMap: screenHeightPixels=" + screenHeightPixels);

int location = new int[2];
mGroupMap.getLocationInWindow(location);
//Log.e(TAG, "resizeMap: getLocationInWindow=" + Arrays.toString(location));

LayoutParams groupMapLayoutParams = mGroupMap.getLayoutParams();
groupMapLayoutParams.height = screenHeightPixels - location[1];
mGroupMap.requestLayout();
}

public static String bottomSheetBehaviorStateToString(int state)
{
String s;
switch (state)
{
case BottomSheetBehavior.STATE_COLLAPSED:
s = "STATE_COLLAPSED";
break;
case BottomSheetBehavior.STATE_DRAGGING:
s = "STATE_DRAGGING";
break;
case BottomSheetBehavior.STATE_EXPANDED:
s = "STATE_EXPANDED";
break;
case BottomSheetBehavior.STATE_HIDDEN:
s = "STATE_HIDDEN";
break;
case BottomSheetBehavior.STATE_SETTLING:
s = "STATE_SETTLING";
break;
default:
s = "UNKNOWN";
break;
}
return s + '(' + state + ')';
}

private static boolean isBottomSheetExpanded(
@NonNull
BottomSheetBehavior bottomSheetBehavior)
{
return bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED;
}

private void bottomSheetMapExpand()
{
mGroupBottomSheetFiller.setVisibility(View.VISIBLE);
int peekHeightPx = getResources().getDimensionPixelSize(R.dimen.home_bottom_sheet_map_peek_height);
mBottomSheetMapBehavior.setPeekHeight(peekHeightPx);
mBottomSheetMapBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
mBottomSheetMapBehavior.setHideable(false);
}

private void bottomSheetMapCollapse()
{
mGroupBottomSheetFiller.setVisibility(View.VISIBLE);
int peekHeightPx = getResources().getDimensionPixelSize(R.dimen.home_bottom_sheet_map_peek_height);
mBottomSheetMapBehavior.setPeekHeight(peekHeightPx);
mBottomSheetMapBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
mBottomSheetMapBehavior.setHideable(false);
}

private void bottomSheetMapHide()
{
mBottomSheetMapBehavior.setHideable(true);
mBottomSheetMapBehavior.setPeekHeight(0);
mBottomSheetMapBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
mGroupBottomSheetFiller.setVisibility(View.GONE);
}





share|improve this answer













Here is the basis of my solution that I commented about above.
I will come back and flesh it out later.



@Override
protected void onCreate(
@Nullable
Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if (isFinishing())
{
return;
}


setContentView(R.layout.activity_home);

...

mGroupBottomSheetFiller = (ViewGroup) findViewById(R.id.groupBottomSheetFiller);

final NestedScrollView bottomSheetMap = (NestedScrollView) findViewById(R.id.bottomSheetMap);
mBottomSheetMapBehavior = BottomSheetBehavior.from(bottomSheetMap);
mBottomSheetMapBehavior.setBottomSheetCallback(new BottomSheetCallback()
{
@Override
public void onStateChanged(
@NonNull
View bottomSheet,
int newState)
{
//Log.e(TAG, "mBottomSheetMapBehavior.onStateChanged(bottomSheet, newState=" +
// bottomSheetBehaviorStateToString(newState) + ')');
int visibility = isBottomSheetExpanded(mBottomSheetMapBehavior) ? View.VISIBLE : View.GONE;
mImageBottomSheetMapClose.setVisibility(visibility);
}

@Override
public void onSlide(
@NonNull
View bottomSheet,
float slideOffset)
{
//Log.e(TAG, "mBottomSheetMapBehavior.onStateChanged(bottomSheet, slideOffset=" + slideOffset + ')');
resizeMap();
}
});
bottomSheetMap.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener()
{
@Override
public void onGlobalLayout()
{
//Log.e(TAG, "onGlobalLayout()");
bottomSheetMap.getViewTreeObserver().removeOnGlobalLayoutListener(this);
resizeMap();
}
});

...
}

private void resizeMap()
{
int screenHeightPixels = PbPlatformUtils.getScreenHeightPixels();
//Log.e(TAG, "resizeMap: screenHeightPixels=" + screenHeightPixels);

int location = new int[2];
mGroupMap.getLocationInWindow(location);
//Log.e(TAG, "resizeMap: getLocationInWindow=" + Arrays.toString(location));

LayoutParams groupMapLayoutParams = mGroupMap.getLayoutParams();
groupMapLayoutParams.height = screenHeightPixels - location[1];
mGroupMap.requestLayout();
}

public static String bottomSheetBehaviorStateToString(int state)
{
String s;
switch (state)
{
case BottomSheetBehavior.STATE_COLLAPSED:
s = "STATE_COLLAPSED";
break;
case BottomSheetBehavior.STATE_DRAGGING:
s = "STATE_DRAGGING";
break;
case BottomSheetBehavior.STATE_EXPANDED:
s = "STATE_EXPANDED";
break;
case BottomSheetBehavior.STATE_HIDDEN:
s = "STATE_HIDDEN";
break;
case BottomSheetBehavior.STATE_SETTLING:
s = "STATE_SETTLING";
break;
default:
s = "UNKNOWN";
break;
}
return s + '(' + state + ')';
}

private static boolean isBottomSheetExpanded(
@NonNull
BottomSheetBehavior bottomSheetBehavior)
{
return bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_EXPANDED;
}

private void bottomSheetMapExpand()
{
mGroupBottomSheetFiller.setVisibility(View.VISIBLE);
int peekHeightPx = getResources().getDimensionPixelSize(R.dimen.home_bottom_sheet_map_peek_height);
mBottomSheetMapBehavior.setPeekHeight(peekHeightPx);
mBottomSheetMapBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
mBottomSheetMapBehavior.setHideable(false);
}

private void bottomSheetMapCollapse()
{
mGroupBottomSheetFiller.setVisibility(View.VISIBLE);
int peekHeightPx = getResources().getDimensionPixelSize(R.dimen.home_bottom_sheet_map_peek_height);
mBottomSheetMapBehavior.setPeekHeight(peekHeightPx);
mBottomSheetMapBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
mBottomSheetMapBehavior.setHideable(false);
}

private void bottomSheetMapHide()
{
mBottomSheetMapBehavior.setHideable(true);
mBottomSheetMapBehavior.setPeekHeight(0);
mBottomSheetMapBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
mGroupBottomSheetFiller.setVisibility(View.GONE);
}






share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 21 '16 at 20:18









swoobyswooby

1,7712431




1,7712431








  • 1





    did you encounter compatibility issues with this solution? in case you have a working app in the playstore using this functionality it'd be great to check it out :)

    – carlosavoy
    May 29 '17 at 15:33













  • You can check my answer @swooby , perhaps it's nearer to what you were looking for. At least, it behaves exactly as I imagined a TopSheet to be equivalent to a BottomSheetBehavior.

    – Carlos Alberto Martínez Gadea
    Nov 21 '18 at 11:18











  • Looks good @CarlosAlbertoMartínezGadea, but the implementation in my answer current fits my needs for an existing production app, so I haven't experimented with porting over to yours. If I do one day I'll mark yours as the preferred answer! Thanks!

    – swooby
    Nov 27 '18 at 21:07














  • 1





    did you encounter compatibility issues with this solution? in case you have a working app in the playstore using this functionality it'd be great to check it out :)

    – carlosavoy
    May 29 '17 at 15:33













  • You can check my answer @swooby , perhaps it's nearer to what you were looking for. At least, it behaves exactly as I imagined a TopSheet to be equivalent to a BottomSheetBehavior.

    – Carlos Alberto Martínez Gadea
    Nov 21 '18 at 11:18











  • Looks good @CarlosAlbertoMartínezGadea, but the implementation in my answer current fits my needs for an existing production app, so I haven't experimented with porting over to yours. If I do one day I'll mark yours as the preferred answer! Thanks!

    – swooby
    Nov 27 '18 at 21:07








1




1





did you encounter compatibility issues with this solution? in case you have a working app in the playstore using this functionality it'd be great to check it out :)

– carlosavoy
May 29 '17 at 15:33







did you encounter compatibility issues with this solution? in case you have a working app in the playstore using this functionality it'd be great to check it out :)

– carlosavoy
May 29 '17 at 15:33















You can check my answer @swooby , perhaps it's nearer to what you were looking for. At least, it behaves exactly as I imagined a TopSheet to be equivalent to a BottomSheetBehavior.

– Carlos Alberto Martínez Gadea
Nov 21 '18 at 11:18





You can check my answer @swooby , perhaps it's nearer to what you were looking for. At least, it behaves exactly as I imagined a TopSheet to be equivalent to a BottomSheetBehavior.

– Carlos Alberto Martínez Gadea
Nov 21 '18 at 11:18













Looks good @CarlosAlbertoMartínezGadea, but the implementation in my answer current fits my needs for an existing production app, so I haven't experimented with porting over to yours. If I do one day I'll mark yours as the preferred answer! Thanks!

– swooby
Nov 27 '18 at 21:07





Looks good @CarlosAlbertoMartínezGadea, but the implementation in my answer current fits my needs for an existing production app, so I haven't experimented with porting over to yours. If I do one day I'll mark yours as the preferred answer! Thanks!

– swooby
Nov 27 '18 at 21:07













2














This TopSheetBehavior implementation ( https://github.com/MedveDomg/AndroidTopSheet/blob/master/library/src/main/java/com/github/techisfun/android/topsheet/TopSheetBehavior.java ) has proved to work pretty well in my case. I found many other TopSheetBehavior that were incomplete or that crashed, but this one doesn't crash and works out of the box by only replacing the behavior parameter:



<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:behavior_hideable="true"
app:behavior_peekHeight="56dp"
app:layout_behavior="your.package.components.TopSheetBehavior">

<!-- Your content goes here -->

</LinearLayout>





share|improve this answer


























  • That's the perfect way to do that. It's working smoothly and fine.

    – Dheeraj Rijhwani
    Nov 20 '18 at 18:05











  • Can I use this exact solution in closed source project? Or should I provide some references?

    – Viktor Vostrikov
    Dec 23 '18 at 15:08











  • @ViktorVostrikov yes, you can. It's under the Apache license. Here you have a few questions answered about the usage of code under the Apache license: resources.whitesourcesoftware.com/blog-whitesource/…

    – Carlos Alberto Martínez Gadea
    Dec 24 '18 at 11:01











  • @CarlosAlbertoMartínezGadea however it is stated that I need to still write somehow the owner of the library.. Don't know there should I provide credentials..

    – Viktor Vostrikov
    Dec 24 '18 at 11:17











  • @ViktorVostrikov to me, the phrase "If you redistribute software with any Apache licensed components, you must include a copy of the license, provide a clear Apache License attribution, and add modification notices to all the files that you modify." explains the situation quite clearly. You don't need to contact the author of the code but you must show that you are using the Apache License, with a link to that license.

    – Carlos Alberto Martínez Gadea
    Dec 24 '18 at 12:32
















2














This TopSheetBehavior implementation ( https://github.com/MedveDomg/AndroidTopSheet/blob/master/library/src/main/java/com/github/techisfun/android/topsheet/TopSheetBehavior.java ) has proved to work pretty well in my case. I found many other TopSheetBehavior that were incomplete or that crashed, but this one doesn't crash and works out of the box by only replacing the behavior parameter:



<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:behavior_hideable="true"
app:behavior_peekHeight="56dp"
app:layout_behavior="your.package.components.TopSheetBehavior">

<!-- Your content goes here -->

</LinearLayout>





share|improve this answer


























  • That's the perfect way to do that. It's working smoothly and fine.

    – Dheeraj Rijhwani
    Nov 20 '18 at 18:05











  • Can I use this exact solution in closed source project? Or should I provide some references?

    – Viktor Vostrikov
    Dec 23 '18 at 15:08











  • @ViktorVostrikov yes, you can. It's under the Apache license. Here you have a few questions answered about the usage of code under the Apache license: resources.whitesourcesoftware.com/blog-whitesource/…

    – Carlos Alberto Martínez Gadea
    Dec 24 '18 at 11:01











  • @CarlosAlbertoMartínezGadea however it is stated that I need to still write somehow the owner of the library.. Don't know there should I provide credentials..

    – Viktor Vostrikov
    Dec 24 '18 at 11:17











  • @ViktorVostrikov to me, the phrase "If you redistribute software with any Apache licensed components, you must include a copy of the license, provide a clear Apache License attribution, and add modification notices to all the files that you modify." explains the situation quite clearly. You don't need to contact the author of the code but you must show that you are using the Apache License, with a link to that license.

    – Carlos Alberto Martínez Gadea
    Dec 24 '18 at 12:32














2












2








2







This TopSheetBehavior implementation ( https://github.com/MedveDomg/AndroidTopSheet/blob/master/library/src/main/java/com/github/techisfun/android/topsheet/TopSheetBehavior.java ) has proved to work pretty well in my case. I found many other TopSheetBehavior that were incomplete or that crashed, but this one doesn't crash and works out of the box by only replacing the behavior parameter:



<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:behavior_hideable="true"
app:behavior_peekHeight="56dp"
app:layout_behavior="your.package.components.TopSheetBehavior">

<!-- Your content goes here -->

</LinearLayout>





share|improve this answer















This TopSheetBehavior implementation ( https://github.com/MedveDomg/AndroidTopSheet/blob/master/library/src/main/java/com/github/techisfun/android/topsheet/TopSheetBehavior.java ) has proved to work pretty well in my case. I found many other TopSheetBehavior that were incomplete or that crashed, but this one doesn't crash and works out of the box by only replacing the behavior parameter:



<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:behavior_hideable="true"
app:behavior_peekHeight="56dp"
app:layout_behavior="your.package.components.TopSheetBehavior">

<!-- Your content goes here -->

</LinearLayout>






share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 21 '18 at 11:15

























answered Aug 29 '18 at 17:41









Carlos Alberto Martínez GadeaCarlos Alberto Martínez Gadea

1,23411424




1,23411424













  • That's the perfect way to do that. It's working smoothly and fine.

    – Dheeraj Rijhwani
    Nov 20 '18 at 18:05











  • Can I use this exact solution in closed source project? Or should I provide some references?

    – Viktor Vostrikov
    Dec 23 '18 at 15:08











  • @ViktorVostrikov yes, you can. It's under the Apache license. Here you have a few questions answered about the usage of code under the Apache license: resources.whitesourcesoftware.com/blog-whitesource/…

    – Carlos Alberto Martínez Gadea
    Dec 24 '18 at 11:01











  • @CarlosAlbertoMartínezGadea however it is stated that I need to still write somehow the owner of the library.. Don't know there should I provide credentials..

    – Viktor Vostrikov
    Dec 24 '18 at 11:17











  • @ViktorVostrikov to me, the phrase "If you redistribute software with any Apache licensed components, you must include a copy of the license, provide a clear Apache License attribution, and add modification notices to all the files that you modify." explains the situation quite clearly. You don't need to contact the author of the code but you must show that you are using the Apache License, with a link to that license.

    – Carlos Alberto Martínez Gadea
    Dec 24 '18 at 12:32



















  • That's the perfect way to do that. It's working smoothly and fine.

    – Dheeraj Rijhwani
    Nov 20 '18 at 18:05











  • Can I use this exact solution in closed source project? Or should I provide some references?

    – Viktor Vostrikov
    Dec 23 '18 at 15:08











  • @ViktorVostrikov yes, you can. It's under the Apache license. Here you have a few questions answered about the usage of code under the Apache license: resources.whitesourcesoftware.com/blog-whitesource/…

    – Carlos Alberto Martínez Gadea
    Dec 24 '18 at 11:01











  • @CarlosAlbertoMartínezGadea however it is stated that I need to still write somehow the owner of the library.. Don't know there should I provide credentials..

    – Viktor Vostrikov
    Dec 24 '18 at 11:17











  • @ViktorVostrikov to me, the phrase "If you redistribute software with any Apache licensed components, you must include a copy of the license, provide a clear Apache License attribution, and add modification notices to all the files that you modify." explains the situation quite clearly. You don't need to contact the author of the code but you must show that you are using the Apache License, with a link to that license.

    – Carlos Alberto Martínez Gadea
    Dec 24 '18 at 12:32

















That's the perfect way to do that. It's working smoothly and fine.

– Dheeraj Rijhwani
Nov 20 '18 at 18:05





That's the perfect way to do that. It's working smoothly and fine.

– Dheeraj Rijhwani
Nov 20 '18 at 18:05













Can I use this exact solution in closed source project? Or should I provide some references?

– Viktor Vostrikov
Dec 23 '18 at 15:08





Can I use this exact solution in closed source project? Or should I provide some references?

– Viktor Vostrikov
Dec 23 '18 at 15:08













@ViktorVostrikov yes, you can. It's under the Apache license. Here you have a few questions answered about the usage of code under the Apache license: resources.whitesourcesoftware.com/blog-whitesource/…

– Carlos Alberto Martínez Gadea
Dec 24 '18 at 11:01





@ViktorVostrikov yes, you can. It's under the Apache license. Here you have a few questions answered about the usage of code under the Apache license: resources.whitesourcesoftware.com/blog-whitesource/…

– Carlos Alberto Martínez Gadea
Dec 24 '18 at 11:01













@CarlosAlbertoMartínezGadea however it is stated that I need to still write somehow the owner of the library.. Don't know there should I provide credentials..

– Viktor Vostrikov
Dec 24 '18 at 11:17





@CarlosAlbertoMartínezGadea however it is stated that I need to still write somehow the owner of the library.. Don't know there should I provide credentials..

– Viktor Vostrikov
Dec 24 '18 at 11:17













@ViktorVostrikov to me, the phrase "If you redistribute software with any Apache licensed components, you must include a copy of the license, provide a clear Apache License attribution, and add modification notices to all the files that you modify." explains the situation quite clearly. You don't need to contact the author of the code but you must show that you are using the Apache License, with a link to that license.

– Carlos Alberto Martínez Gadea
Dec 24 '18 at 12:32





@ViktorVostrikov to me, the phrase "If you redistribute software with any Apache licensed components, you must include a copy of the license, provide a clear Apache License attribution, and add modification notices to all the files that you modify." explains the situation quite clearly. You don't need to contact the author of the code but you must show that you are using the Apache License, with a link to that license.

– Carlos Alberto Martínez Gadea
Dec 24 '18 at 12:32


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f39088269%2fandroid-top-sheet-equivalent-of-bottom-sheet%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

MongoDB - Not Authorized To Execute Command

How to fix TextFormField cause rebuild widget in Flutter

in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith