Navigation Drawer and SurfaceView in fragment - android

I want to use SurfeceView to make simple painting app like MS Paint.
I created main activity with navigation drawer as toolbox for painting tools.
I assumed that user I can operate on many surfaces (pages) so I made for each page separate fragment with SurfaceView inside.
In main activity I made customized button to open drawer.
In fragment I set mSurfaceView.setZOrderOnTop(true) for SurfaveView and in SurfaceView mHolder.setFormat(PixelFormat.TRANSLUCENT)
Fragment layout:
<?xml version="1.0" encoding="utf-8"?>
<it.controls.PaintPageLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="20dp"
android:background="#e0aa66cc"
android:visibility="visible">
<Button
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Sv"
android:textSize="12sp"
android:padding="0dp"
android:background="#ffff4444"
android:textColor="#android:color/black"
android:minWidth="40dp"
android:id="#+id/surface_fragment_debug_save" />
<TextView
android:id="#+id/surface_fragment_debug_info"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="end"
android:text="debug_info"
android:textColor="#android:color/white"
android:background="#android:color/transparent"
android:visibility="visible"
android:layout_toEndOf="#+id/surface_fragment_debug_save" />
</RelativeLayout>
<it.controls.PaintSurfaceView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/surface_fragment_surface"
/>
Main layout is almost standard template generated from Android Studio, expect that my app is full screen (doesn't have Toolbar)
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<!-- The main content view -->
<android.support.design.widget.CoordinatorLayout
android:id="#+id/main_coordinate_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<!-- button to show left menu -->
<android.support.v7.widget.AppCompatImageButton
android:id="#+id/toolbox_toggle_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/toolbox_show_margin"
android:layout_marginLeft="#dimen/toolbox_show_margin"
android:contentDescription="#string/menu_show_hide_menu"
android:src="#drawable/ic_menu_black_48dp"
android:minWidth="#dimen/toolbox_show_button_size"
android:minHeight="#dimen/toolbox_show_button_size"
android:scaleType="fitCenter"
android:background="#drawable/toolbox_new_page_button_border"
/>
</android.support.design.widget.CoordinatorLayout>
<!-- The navigation drawer -->
<FrameLayout
android:id="#+id/menu_container"
android:layout_width="#dimen/nav_drawer_width"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="horizontal"
android:layout_gravity="start"
tools:ignore="UselessParent">
</FrameLayout>
</android.support.v4.widget.DrawerLayout>
When I coded that I made simple drawing mechanism to draw path in SurfaceView and there is a problem.
My problem is that after I draw path I would like to change color so I must open toolbox (drawer). After I open drawer I saw that path is painted ON drawer as on screen below.
What I made wrong? How to hide SurfaceView behind drawer?

Your app has two distinct layers: the View UI layer, and the SurfaceView Surface layer. One of them is entirely on top of the other. You can't put one partially under the other. You put the SurfaceView Surface on top, so it's in front of all of your Views.
You might be better off with a custom View, rather than a SurfaceView. It'll mix in with your other Views, and for Canvas rendering it can be more efficient because it'll take advantage of hardware-accelerated rendering.

Related

Sliding Up Panel (Umano) facing some problems

I successfully created the Sliding up panel in my first screen of app(music player),also i have a navigation drawer. Now the problem is this sliding up panel is only available on the first screen. I want it for all my screens (downloads, etc).I want the same way as in apps like Gaana and Google Play Music.
I refered this while creating sliding up panel
https://www.numetriclabz.com/implementation-of-sliding-up-panel-using-androidslidinguppanel-in-android-tutorial/
please help,Thanks!
Explaination:-
<com.sothree.slidinguppanel.SlidingUpPanelLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/frag_product_list_panel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:gravity="bottom"
android:orientation="vertical"
app:umanoDragView="#+id/dragView"
app:umanoOverlay="true"
app:umanoPanelHeight="0dp"
app:umanoParallaxOffset="0dp"
app:umanoShadowHeight="#dimen/2dp">
<!-- Main content, Use this container to transact fragments -->
<FrameLayout
android:id="#+id/dragView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- Sliding content -->
<LinearLayout
android:id="#+id/dragView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
android:background="#android:color/white"
android:clickable="true"
android:focusable="false"
android:orientation="vertical">
<!-- content of sliding panel goes here -->
</LinearLayout>
</com.sothree.slidinguppanel.SlidingUpPanelLayout>
If you're wondering about Fragment, follow this link -
How to do FragmentTransaction
Official guide
Happy coding!

Android bottom toolbar disappears when fragment fills screen

I'm working on an android app and am using a toolbar at the top of the screen and a navigation bar at the bottom of the screen. I'm using a single activity to create the top and bottom toolbars and fragments to change the content between the toolbars. However, when the contents in the fragment go beyond the size of the screen, the bottom bar disappears.
Here is my home activity xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_home"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.rentables.testcenter.HomeActivity">
<include
android:id="#+id/toolbar_main"
layout="#layout/toolbar_main"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<fragment android:name="com.rentables.testcenter.HomeFragment"
android:id="#+id/fragment_place"
android:layout_weight="0"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:layout="#layout/fragment_home" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="bottom">
<include
android:id="#+id/toolbar_navigate"
layout="#layout/toolbar_navigate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center|bottom"/>
</LinearLayout>
</LinearLayout>
Im guessing it's because of the inner linear layout I have, but I wasn't sure how else to get the nav bar to stay static at the bottom. Any help would be awesome. Thanks
Figured it out. I just changed the whole thing to a relative layout, got rid of the inner linear layout, and instead of gravity I used alignParentBottom="true".

Android: Adjusting MediaController to fit system UI doesn't work with Action Bar

I have an Activity that shows a video using VideoView with a custom MediaController. The system UI is hidden until the user taps the screen to show the MediaController (just like in YouTube or Photos app).
The following method takes care of hiding the system UI:
private void hideSystemUi() {
int flags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
View.SYSTEM_UI_FLAG_FULLSCREEN |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
getWindow().getDecorView().setSystemUiVisibility(flags);
}
And the layout of the Activity:
<FrameLayout android:id="#+id/root"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true"
android:keepScreenOn="true">
<com.google.android.exoplayer.AspectRatioFrameLayout
android:id="#+id/video_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center">
<SurfaceView
android:id="#+id/surface_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"/>
</com.google.android.exoplayer.AspectRatioFrameLayout>
</FrameLayout>
I then add the MediaController to video_frame via code like so:
mMediaController.setAnchorView(findViewById(R.id.video_frame));
Testing with Nexus 5, I noticed that when showing the MediaController, the soft navigation bar is overlapping the MediaController UI. I managed to fix it by adding the following attribute to the root of MediaController layout:
android:fitsSystemWindows="true"
So far so good. This worked perfectly fine as long as my Activity theme was Theme.AppCompat.NoActionBar. Now that I'm refactoring the app, getting it as per Material design guidelines for featuring, I have to show the ActionBar.
So I changed the theme to Theme.AppCompat and guess what? The system UI once again overlaps the MediaController. It seems that android:fitsSystemWindows="true" has absolutely no affect anymore.
I've tried to set android:fitsSystemWindows="true" directly to the Activity theme itself and it seemed to solve the overlapping issue, but then I got another issue where the VideoView was padded in a totally weird way from random direction, instead of scaling to fit the screen as it used to be.
I've spent hours on that and still can't figure out a clean solution.
Please note that I need a solution that works for Tablets and Phones together.
And as you probably know, on tablets, the soft navigation bar appears at the bottom of the screen while in landscape mode.
I prefer to solve the issue via XML if possible.
After examining Android Studio's Fullscreen Activity template, I noticed that in the FullscreenActivity layout they are using android:fitsSystemWindows="true" in a little bit different way than me.
Here's the layout that comes with the template (activity_fullscreen.xml):
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0099cc"
tools:context=".FullscreenActivity">
<!-- The primary full-screen view. This can be replaced with whatever view
is needed to present your content, e.g. VideoView, SurfaceView,
TextureView, etc. -->
<TextView android:id="#+id/fullscreen_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true"
android:textColor="#33b5e5"
android:textStyle="bold"
android:textSize="50sp"
android:gravity="center"
android:text="#string/dummy_content"/>
<!-- This FrameLayout insets its children based on system windows using
android:fitsSystemWindows. -->
<FrameLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<LinearLayout android:id="#+id/fullscreen_content_controls"
style="?metaButtonBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:background="#color/black_overlay"
android:orientation="horizontal"
tools:ignore="UselessParent">
<Button android:id="#+id/dummy_button"
style="?metaButtonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/dummy_button"/>
</LinearLayout>
</FrameLayout>
</FrameLayout>
I noticed that they have an additional FrameLayout container set with android:fitsSystemWindows="true" that wraps the actual layout container (in my case this was the MediaController) at the bottom of the screen.
Once I added a FrameLayout to wrap my MediaController layout as shown in the above code snippet my problem is gone! Really weird that I need to have additional layout container to solve this issue. Especially when Android Studio is saying now that I have "Useless Parent".
So to summarize, here is the fully working solution of how my Activity layout looks like:
<FrameLayout android:id="#+id/root"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true"
android:keepScreenOn="true">
<com.google.android.exoplayer.AspectRatioFrameLayout
android:id="#+id/video_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center">
<SurfaceView
android:id="#+id/surface_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"/>
</com.google.android.exoplayer.AspectRatioFrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<LinearLayout android:id="#+id/controller_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:orientation="horizontal">
</LinearLayout>
</FrameLayout>
</FrameLayout>
and I hook up the MediaController to controller_frame instead of video_frame as I did previously:
mMediaController.setAnchorView(findViewById(R.id.controller_frame));

DrawerLayout with two drawers: Right one "jumping" when left one is opened?

My application has a DrawerLayout with two drawers in it, one on the left for nav and one on the right for notifications. When the application goes through a cold start and I swipe the left drawer open, the right drawer jumps from the far left of the screen to the right.
It looks like this: http://i.imgur.com/mhoJ7MZ.gifv
As shown in the video, I've tried using DrawerLayout's isDrawerOpen and isDrawerVisible methods to try to see if it actually thinks the right drawer is open when it's not (since it seems to be "closing" the drawer when the left one is opened), but I didn't get anything useful from that.
What's causing the weird jump?
My activity's XML is below, the full code is here.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
...
</LinearLayout>
<LinearLayout
android:id="#+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#ACFF0000"
android:gravity="center"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LEFT DRAWER"
android:textSize="24sp" />
</LinearLayout>
<LinearLayout
android:id="#+id/right_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="end"
android:background="#AC00FF00"
android:gravity="center"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="RIGHT DRAWER"
android:textSize="24sp" />
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
The issue comes from the android:visibility="gone" element on the LinearLayouts -- For some reason having visibility set to gone conflicts with the DrawerLayout's logic for if the view is showing or not, so it tries to hide it.
Taking that out of the XML causes everything to look the same (since DrawerLayout looks at the layout_gravity to decide which child views are drawers and hides them itself) and not have the weird jump.

ScrollView in content of DrawerLayout prevents the drawer to be opened by swiping

When I put ScrollView into the content of a DrawerLayout, I am nolonger able to open the drawer by swiping from the side.
Activity layout:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The menu_main content view -->
<FrameLayout
android:id="#android:id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<!-- The navigation drawer -->
<ListView
android:name="com.gumtree.androidapp.DrawerFragment"
android:id="#+id/drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start" />
</android.support.v4.widget.DrawerLayout>
In Activity's onCreate I add a fragment which has following layout:
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_height="160dp"
android:layout_width="match_parent"/>
<TextView
android:id="#+id/headline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="#dimen/headline_text_size"
android:padding="#dimen/detail_text_padding"
android:textIsSelectable="false"/>
<TextView
android:id="#+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="#dimen/description_text_size"
android:padding="#dimen/detail_text_padding"
android:textIsSelectable="false"/>
</LinearLayout>
</ScrollView>
Without the ScrollView everything works fine and I am able to open the drawer by swiping from the side. However when I add the ScrollView, it stops working.
The problem here was silly named ID of FrameLayout used as content container of DrawerLayout. I used system ID (android.R.id.content) which caused that the content fragment was put on the top of all other views - even the drawer.
It also caused fragment's layout to overlap the drawer and - related to this question - blocked the drawer from receiving touch events. The touch events were taken by fragment's ScrollView.
Conclusion: DO NOT USE SYSTEM IDs (android.R.*) WHERE IT IS NOT NEEDED.
I just wanted it to look nice and clean.. Silly me :)

Categories

Resources