How to hide navigation bar in LibGDX? - libgdx

Basically that's the question. What can I do to hide the navigation bar when I run an app in a phone that does not have physical home buttons? By the way I'm running android 5 (I don't know if that changes anything.)
If you know how to do it please answer :)

I know it's an old question, but to anyone who finds their way here, libGDX now has a very easy way to do this. Simply set this field in the AndroidLauncher class.
config.useImmersiveMode = true;

As of date, LibGDX does not have an abstraction for hiding the navigation bar unlike the status bar. (It has a control for status bar in the AndroidApplicationConfiguration class.) You should do the hiding in your wrapper application for Android.
Here you go with the link: Hiding the Navigation Bar

The PixNB Blog has your answer.
The steps are :
Add hideVirtualButtons() method to AndroidLauncher.java :
#TargetApi(19)
private void hideVirtualButtons() {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
}
call hideVirtualButtons from onCreate() in AndroidLauncher.java:
public void onCreate() {
....
// In KITKAT (4.4) and next releases, hide the virtual buttons
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
hideVirtualButtons();
}
}
And override the function onWindowFocusChanged() within AndroidLauncher.java:
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
// In KITKAT (4.4) and next releases, hide the virtual buttons
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
hideVirtualButtons();
}
}
}
Visit the blog if you need some explaination.

Related

android lollipop toolbar: how to hide/show the toolbar while scrolling?

I'm using the new toolbar widget introduced in the appcompat / support-v7. I would like to hide/show the toolbar depending on if the user is scrolling up/down the page, just like in the new Google's playstore app or NewsStand app. Is there something built into the toolbar widget for this or should I be using it in conjunction with FrameLayout and ObservableScrollView?
As far as I know there is nothing build in that does this for you. However you could have a look at the Google IO sourcecode, especially the BaseActivity. Search for "auto hide" or look at onMainContentScrolled
In order to hide the Toolbar your can just do something like this:
toolbar.animate().translationY(-toolbar.getBottom()).setInterpolator(new AccelerateInterpolator()).start();
If you want to show it again you call:
toolbar.animate().translationY(0).setInterpolator(new DecelerateInterpolator()).start();
For hiding the toolbar you can just do :
getSupportActionBar().hide();
So you just have to had a scroll listener and hide the toolbar when the user scroll !
Hide:
getSupportActionBar().hide();
Show:
getSupportActionBar().show();
The answer is straightforward. Just implement OnScrollListenerand hide/show your toolbar in the listener. For example, if you have listview/recyclerview/gridview, then follow the example.
In your MainActivity Oncreate method, initialize the toolbar.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
if (toolbar != null) {
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
}
And then implement the OnScrollListener
public RecyclerView.OnScrollListener onScrollListener = new RecyclerView.OnScrollListener() {
boolean hideToolBar = false;
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (hideToolBar) {
((ActionBarActivity)getActivity()).getSupportActionBar().hide();
} else {
((ActionBarActivity)getActivity()).getSupportActionBar().show();
}
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy > 20) {
hideToolBar = true;
} else if (dy < -5) {
hideToolBar = false;
}
}
};
I got the idea from: https://stackoverflow.com/a/27063901/1079773
Android Design Support Library can be used to show/hide toolbar.
See this.
http://android-developers.blogspot.kr/2015/05/android-design-support-library.html
And there are detail samples here.
http://inthecheesefactory.com/blog/android-design-support-library-codelab/en
There are actually quite a number of ways to hide/show the toolbar while you are scrolling the content. One of the ways is to do it via the Android Design Support Library or more specifically the Coordinator layout aka. super-powered frame layout.
Basically all you need to do is to have the following structure in your layout file and you should be able to achieve the result that you want.
<CoordinatorLayout>
<AppBarLayout>
</AppBarLayout>
<NestedScrollView>
</NestedScrollView>
</CoordinatorLayout>
I have actually made a video to explain how it can be done in a step by step manner. Feel free to check it out and let me know if it helps. Thanks! :)
https://youtu.be/mEGEVeZK7Nw
Just add this property inside your toolbar and its done
app:layout_scrollFlags="scroll|enterAlways"
Isn't is awesome
I've been trying to implement the same behavior, here is the brunt of code showing and hiding the toolbar (put in whatever class containing your RecyclerView):
int toolbarMarginOffset = 0
private int dp(int inPixels){
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, inPixels, getApplicationContext().getResources().getDisplayMetrics());
}
public RecyclerView.OnScrollListener onScrollListenerToolbarHide = new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
toolbarMarginOffset += dy;
if(toolbarMarginOffset>dp(48)){
toolbarMarginOffset = dp(48);
}
if(toolbarMarginOffset<0){
toolbarMarginOffset = 0;
}
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams)toolbar.getLayoutParams();
params.topMargin = -1*toolbarMarginOffset;
toolbar.setLayoutParams(params);
}
};
I've included the dp function to convert from pixels to dp but obviously set it to whatever your toolbar height is. (replace dp(48) with your toolbar height)
Where-ever you setup your RecyclerView include this:
yourListView.setOnScrollListener(onScrollListenerToolbarHide);
However, there are a couple additional issues if you are also using a SwipeRefreshLayout.
I've had to set the marginTop of the first element in the adapter for the RecyclerView to the Toolbar's height plus original offset. (A bit of a hack I know). The reason for this is I found that if I changed my above code to include changing the marginTop of the recyclerView while scrolling it was a jittery experience. So that's how I overcame it. So basically setup your layout so that your toolbar is floating on top of the RecyclerView (clipping it) Something like this (in onBindViewHolder of your custom RecyclerView adapter) :
if(position==0){
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams)holder.card.getLayoutParams();
// params.height = ViewGroup.LayoutParams.WRAP_CONTENT;
params.topMargin = dp(10+48);
}
And lastly, since there is a large offset the RecyclerViews refresh circle will be clipped, so you'll need to offset it (back in onCreate of your class holding your RecyclerView):
swipeLayout.setProgressViewOffset(true,dp(48),dp(96));
I hope this helps someone. Its my first detailed answer so I hope I was detailed enough.
To hide the menu for a particular fragment:
setHasOptionsMenu(true); //Inside of onCreate in FRAGMENT:
#Override
public void onPrepareOptionsMenu(Menu menu) {
menu.findItem(R.id.action_search).setVisible(false);
}
I implemented a utility class to do the whole hide/show Toolbar animation when scrolling. You can see the article here http://rylexr.tinbytes.com/2015/04/27/how-to-hideshow-android-toolbar-when-scrolling-google-play-musics-behavior/. Source code is here https://github.com/rylexr/android-show-hide-toolbar.
A library and demo with the complete source code for scrolling toolbars or any type of header can be downloaded here:
https://github.com/JohannBlake/JBHeaderScroll
Headers can be Toolbars, LinearLayouts, RelativeLayouts, or whatever type of view you use to create a header.
The scrollable area can be any type of scroll content including ListView, ScrollView, WebView, RecyclerView, RelativeLayout, LinearLayout or whatever you want.
There's even support for nested headers.
It is indeed a complex undertaking to synchronize headers (toolbars) and scrollable content the way it's done in Google Newsstand.
This library doesn't require implementing any kind of onScrollListener.
The solutions listed above by others are only half baked solutions that don't take into consideration that the top edge of the scrollable content area beneath the toolbar has to initially be aligned to the bottom edge of the toolbar and then during scrolling the content area needs to be repositioned and possibly resized. The JBHeaderScroll handles all these issues.
There is an Android library called Android Design Support Library that's a handy library where you can find of all of those Material fancy design things that the Material documentation presents without telling you how to do them.
It's well presented in this Android Blog post. The "Collapsing Toolbar" in particular is what you're looking for.

GameStateManager LibGDX

I started a project with libgdx and I have a GameStateManager for my GameStates Menu and Play.
If I run the project it shows the Menu and then I can click a button to open the Play GameState.
The Problem is, that when I ended the Game it should show the Menu State again, but I get a black screen. I tested if the render() method is started (with System.out...) and the render() method in Menu is starting.
I am not shure why I get a black screen when I "reopen" the Menu state. Maybe its not working because I use Box2D in Play but I dont know.
Here some code:
This is the method in Play which should open the Menu if the player is at the end:
public void playerEnded() {
gsm.setState(GameStateManager.MENU);
}
Maybe you can tell me, if I have to end box2d things or so.
I hope someone can help me, and if you want more code - no problem.
Your custom GameStateManager should extend this class:
http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/Game.html
To change screens you should be using Game.setScreen(Screen screen)
Each different screen should be an implementation of Screen.
So the way it works in my libGDX projects is such that GameScreen extends Screen, and MenuScreen extends Screen. That way I can change what draws on what screen.
This all goes back to interfaces and polymorphism, so if you don't get those concepts, just give it a quick google and you'll get an idea what you need to do.
Chances are that your are defining a
Stack<GameState> gameStates
in your GameStateManager to manage your GameStates.
If so, you could do some reading on using a Stack. Anyway, here's what could do to solve your problem:
I'm assuming you have the following structure in your GamestateManager;
public void setState(int state){
popState();
pushState(state);
}
public void pushState(int state){
gameStates.push(getState(state));
}
public void popState(){
GameState g = gameStates.pop();
g.dispose();
}
private GameState getState(int state){
if(state == MENU) return new Menu(this);
if(state == PLAY) return new Play(this);
return null;
}
When you click your start button in your Menu-GameState, you'll want to launch the Play-GameState.
Now, instead of using the setState method, which removes the top state (pop) and then pushes the new state. Try using only the pushState method. This will put your new Play-GameState on top of your Menu-GameState in the GameState-Stack.
When you're done playing, you can pop your Play-GameState and the Menu-GameState should reappear. But this time it won't instantiate a new Object, but reuse the one you used when you started the game.
// in the Menu-GameState:
public void startPlay() {
gsm.pushState(GameStateManager.PLAY);
}
// in the Play-GameState:
public void playerEnded() {
gsm.popState();
}
This won't affect gameplay performance as you would render and update your game with only the GameState that is on top of the Stack, like this:
public void update(float dt) {
gameStates.peek().update(dt);
}
public void render() {
gameStates.peek().render();
}
The peek method takes the GameState from the top of the Stack, but leaves it there.
The only downside is that the Menu-Gamestate would stay in-memory during your Play-State.
Also, if this method works, you could still do it your way, but you should check the way your Menu-GameState is instantiated and identify problems when it's instantiated twice.
I implemented a similar StageManager in my game. If you are using viewports/cameras in your game, then it is likely that when you go back to your menu state, the viewport is still set to the Game state's viewport.
For my app, I had my State class have an activate() method which would be called whenever a state became the active state:
public void activate(){
stage.getViewport().update(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
}

Create custom presenter for my mvvmcross project

I'm working on a project for iOS using mvvmcross.
App navigation goes like this: first it starts from the splash screen (1), them it navigates to (2), a view to select between 3 options, in view (3) and (4) you get a list and also could navigate back to (2), if you select an item in (3) you navigate to (5) in a modal way.
Lastly, all navigation end up in (6), a view with an hamburger menu.
So I have traditional navigation(with back button), modal views and a hamburger menu at the end.
It would be great if someone could help me or guide me to see how to create a custom presenter for this navigation scheme.
I'm using MvxModalNavSupportTouchViewPresenter and a SlidingPanelsNavigationViewController, but don't know how to swap them when I navigate from (2,4,5) to (6)
A presenter is just something that implements https://github.com/MvvmCross/MvvmCross/blob/develop/MvvmCross/Core/Core/Views/IMvxViewPresenter.cs
public interface IMvxViewPresenter
{
void Show(MvxViewModelRequest request);
void ChangePresentation(MvxPresentationHint hint);
}
This is are really simple interface and it allows shared portable code like ViewModels to request changes in the display.
For the case where you want a Show request to change the entire UI from one display paradigm (modal navigation controller) to another (sliding panels), then one way to do this is to implement a presenter which has two child presenters and which simply switches them over.
In pseudo code this might look like:
public class MyPresenter : IMvxViewPresenter
{
private IMvxViewPresenter _currentPresenter;
private ModalPresenter _modalPresenter;
private SlidingPresenter _slidingPresenter;
private enum Style
{
Modal, Panels
}
private Style _currentStyle;
public MyPresenter()
{
// do whatever you need to do here to:
// - construct _modalPresenter and _slidingPresenter
// - make _modalPresenter attached to the window (via root view controller)
// - make _slidingPresenter hidden/unattached
_currentStyle = Style.Modal;
_currentPresenter = _modalPresenter;
}
public void Show(MvxViewModelRequest request)
{
if (_currentStyle == Style.Modal &&
request.ViewModelType == typeof(WhateverViewModelIndicatesTheSwitchIsNeeded))
{
DoSwitch(request);
return;
}
_currentPresenter.Show(request);
}
public void ChangePresentation(MvxPresentationHint hint)
{
_currentPresenter.ChangePresentation(hint);
}
private void DoSwitch(MvxViewModelRequest request)
{
// do whatever is necessary to:
// - remove _modalPresenter from the window
// - add _panelPresenter to the window
// - show `request` within _panelPresenter
_currentPresenter = _panelPresenter;
_currentStyle = Style.Panelsl
}
}
Obviously, there are some details to fill in within this pseudo-code - e.g. there are some viewcontrollers to be added and removed from the window - but this is just standard iOS manipulation - e.g. see lots of questions and answers like Changing root view controller of a iOS Window and Change rootViewController from uiviewcontroller to uinavigationcontroller

How to add a JPopupMenu to a JMenuBar?

I have an application with a popup menu. I'd like to use the popup in the usual way (i.e., it should appear when the user right-clicks anywhere in the window), but I'd also like to attach it to the main MenuBar at the top of the window. I'm not sure how to do this.
I'd thought it would as simple as calling
myJMenuBar.add(myPopupMenu)
but this doesn't work.
JMenuBar.add() wants a JMenu parameter, not a JPopupMenu.
Does anyone have any suggestions?
Instead of trying to reuse the JPopupMenu object, the best approach would be to encapsulate the actions that the menus perform, and reuse those. The popup would trigger those actions, as would the menu items.
From the Action JavaDoc:
In addition to the actionPerformed method defined by the ActionListener interface, this interface allows the application to define, in a single place:
One or more text strings that describe the function. These strings can be used, for example, to display the flyover text for a button or to set the text in a menu item.
One or more icons that depict the function. These icons can be used for the images in a menu control, or for composite entries in a more sophisticated user interface.
The enabled/disabled state of the functionality. Instead of having to separately disable the menu item and the toolbar button, the application can disable the function that implements this interface. All components which are registered as listeners for the state change then know to disable event generation for that item and to modify the display accordingly.
and
JPopupMenu, JToolBar and JMenu all provide convenience methods for creating a component and setting the Action on the corresponding component. Refer to each of these classes for more information.
I had the same issue. A right-mouse-click as well as a top menu with exactly the same (complicated) set of menu items. The 'Action' class is something to consider if you are talking about enablement choices, but it's not dealing with visibility and in my case there was also a dynamic list of entries based on a current selection that I wanted to reuse.
So I ended up implementing a 'Bridge' design pattern (I think) for the methods I actually use (add() and addSeparator()):
public static class MenuBridge
{
private JPopupMenu popupMenu;
private JMenu menu;
public MenuBridge(JPopupMenu popupMenu)
{
this.popupMenu = popupMenu;
}
public MenuBridge(JMenu menu)
{
this.menu = menu;
}
public void addSeparator()
{
if(popupMenu!=null) popupMenu.addSeparator();
else menu.addSeparator();
}
public void add(JMenuItem item)
{
if(popupMenu!=null) popupMenu.add(item);
else menu.add(item);
}
}
So then I can write a reusable method that computes the menu items and synchronize my right mouse click with the top-level menu:
public void addTaskMenuItems(DefaultMenu menu, List<MDProcTask> taskList)
{
...
menu.add()/menu.addSeparator()
...
}
addTaskMenuItems(new DefaultMenu(popupMenu),taskList);
...
taskMenu.addMenuListener( new MenuListener() {
public void menuCanceled(MenuEvent menuevent)
{
}
public void menuDeselected(MenuEvent menuevent)
{
}
public void menuSelected(MenuEvent menuevent)
{
taskMenu.removeAll();
addTaskMenuItems( new DefaultMenu(taskMenu),getSelectedTasks());
taskMenu.revalidate();
}});

How to prevent JPopUpMenu disappearing when checking checkboxes in it?

I want to use JCheckBoxMenuItems in a JPopupMenu. It works, but the problem is that the popup menu disappears when a checkbox item has been checked or unchecked. So if one wants to check/uncheck several items, the popup needs to be launched repeatedly, which is irritating.
Curiously, if I use just plain JCheckBox items in the menu (instead of JCheckBoxMenuItems), the behavior is just as it should be: the popup stays there and the checkboxes can be checked/unchecked. Once done, the popup can be closed just by clicking outside it.
How do I make the popup to behave like that when the items there are JCheckBoxMenuItems? I would prefer using JCheckBoxMenuItems because of their looks.
Well, found working answer from http://forums.sun.com/thread.jspa?threadID=5432911. Basically, create a custom UI:
public class StayOpenCheckBoxMenuItemUI extends BasicCheckBoxMenuItemUI {
#Override
protected void doClick(MenuSelectionManager msm) {
menuItem.doClick(0);
}
public static ComponentUI createUI(JComponent c) {
return new StayOpenCheckBoxMenuItemUI();
}
}
And set it in the JCheckBoxMenuItem:
myJCheckBoxMenuItem.setUI(new StayOpenCheckBoxMenuItemUI());
Don't know if this is the most elegant possible solution, but works perfectly.
I ran into an issue with the nice Joonas Pulakka's answer because the "UIManager lookandFeel" was ignored.
I found the nice trick below on http://tips4java.wordpress.com/2010/09/12/keeping-menus-open/
The point is to reopen immediatly the menu after it has been closed, it's invisible and keep the application look and feel and behavior.
public class StayOpenCBItem extends JCheckBoxMenuItem {
private static MenuElement[] path;
{
getModel().addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
if (getModel().isArmed() && isShowing()) {
path = MenuSelectionManager.defaultManager().getSelectedPath();
}
}
});
}
public StayOpenCBItem(String text) {
super(text);
}
#Override
public void doClick(int pressTime) {
super.doClick(pressTime);
MenuSelectionManager.defaultManager().setSelectedPath(path);
}
}
I found a much easier solution for this problem
JCheckBoxMenuItem menuItem = new JCheckBoxMenuItem("sample");
menuItem.putClientProperty("CheckBoxMenuItem.doNotCloseOnMouseClick", Boolean.TRUE);
I found this solution while reading the code from
BasicMenuItemUI.doNotCloseOnMouseClick()