I have a rather trivial question, but I thought I'd give it a shot. I'm writing an android app and I have a viewgroup form that is loaded from a web server. While the internet access is running, I used to pop up a dialog box with a progress bar. I decided it would look less clunky if I swtiched to the nice small indeterminate progress bar in the title bar.
The title bar option does look less busy, except that the form items (textviews, buttons etc) are all enabled during the retrieval. I then used a recursive routine to disable all the views in the viewgroup, but that again looks ugly - the greyed out textviews (2.3.3) look gross, especially the one with the focus with the orange bar around it. If I pop up a progress bar, the underlying view looks nicely disabled - the window behind is simply slowly dimmed down. From a visual point of view, it much more obvious that we're waiting for something to occur when the entire window is dimmed rather than being faced with a bunch of disabled controls.
Is there a call I can make to disable a view in a similar way the OS does when a progress bar or other window is overlapped on top? This would give me the best of both worlds.
I guess the other option is to set the view to invisible during the access, but I got curious because I can see the OS doing exactly what I want when I use the popup.
I figured out how to do this using a relative layout with a progress dialog wrapped in a frame layout overlapping the main view. When I do my network get, I set the visibility of the frame layout to visible with the background set to translucent, and disable the controls in the underlying view. Works pretty well.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<ScrollView
android:id="#+id/itemView"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
</ScrollView>
<FrameLayout
android:id="#+id/itemProgress"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#55000000"
android:visibility="gone"
>
<ProgressBar
style="?android:attr/progressBarStyleLarge"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center|center_vertical"
android:indeterminateOnly="true"
/>
</FrameLayout>
</RelativeLayout>
Related
I would like to remove paddingTop/marginTop from the navigation view in Multi-Window mode of Android N. Like Gmail already does.
If you see the image below, I'm talking about the normal padding with size equals to the status bar at the beginning of the navigation view.
So basically in Multi-Window mode (see the image below) I have to remove that padding when my app is in the second part of the screen.
Unfortunately from the new api 24 you have isInMultiWindowMode() but it's not possible to know in which part of the screen is your app.
Instead of trying to figure out if you're in multi-window mode and on which part of the screen, you need to make your navigation view header respect system windows insets.
Normally you care about just one window - the one your app is drawn in. Usually you don't even think there are any windows. Isn't your app drawn fullscreen? Well, actually no. Usually there is some space reserved for system bars, like status bar at the top and navigation bar at the bottom. They are drawn in separate windows - system windows. (Oh, and now we've got multi-window mode in N. More like multi-app-window mode, because if you count system windows then multi-window has been around for a while.)
You can make your navigation view header adjust its insets depending on whether it is under a system window (in this case: status bar) or not with just a few simple tweaks.
Assuming the navigation view is defined like that:
<android.support.design.widget.NavigationView
...
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
... />
and there is a simple header layout in nav_header_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="#dimen/nav_header_height"
android:background="#drawable/nav_header_background"
android:orientation="vertical"
android:paddingBottom="16dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="32dp">
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#android:drawable/default_profile_picture" />
...
</LinearLayout>
you just need change it like that:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="#dimen/nav_header_height"
android:background="#drawable/nav_header_background"
android:fitsSystemWindows="true"
android:orientation="vertical">
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#android:drawable/sym_def_app_icon"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="8dp"/>
...
</LinearLayout>
First you need to add android:fitsSystemWindows="true" to the layout.
Now you need to make top padding smaller, as fitsSystemWindows will automatically add padding the size of status bar. So previously your top padding was from the top of your header, now it is only from the bottom of the status bar.
And you have to move all your paddings from the layout somewhere else (for example I moved them to margins on child views), because fitsSystemWindows will overwrite those paddings.
After this if your app is in the bottom part of multi-window split then the padding for status bar will not be added. It will also make your navigation view look properly in any other cases where it's not under the status bar or if the status bar changes size in any future version of Android or some crazy custom ROM.
For me nothing was working so I ended up going this route and it got the job done:
<android.support.design.widget.NavigationView
...
app:insetForeground="#null"/>
Technically, the insets are still present but since the insetForeground resource used to draw on them is now null, that logic is skipped in ScrimInsetsFrameLayout's onDraw method (which is the parent class of NavigationView).
So when all else fails, this is a fairly efficient route.
I have a situation where I need a scrollview to have a background image that shouldn't scroll along with it's parent when moving. Before any of you suggest me the links for setting background image and this that, I have already tried and it's not working.
The whole story goes like: I have an activity with fragments which have their own backgrounds with some input fields. When focusing over input fields, keyboard appears and background image squeezes. For that I put an image on background of scrollview that fixed my issue of squeezing background but raised another concern that background Image should stay static while scrolling the parent scrollview.
The second solution any of you may suggest is setting background of my activity rather playing with scrollview. That's right, but for that I had to make a style element with background of theme which appears odd while transitioning different fragments plus it adds overhead when I have a lot of code and fragments to move forward and back.
That's the point where I am stuck. I have gone through links below, if you just need to know that I tried it or not.
link1
link2
link3
... and so on
below is the layout I am using for my fragments (it's all being done programmatically)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/top_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:scrollbars="none" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<ImageView
android:id="#+id/backgroundView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="#string/app_name"
android:scaleType="fitXY" />
<LinearLayout
android:id="#+id/parent_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>
</FrameLayout>
</ScrollView>
</LinearLayout>
So if you guys have any better solution keeping in mind the situation I have, will be warmly welcomed. Thank you
None of the above works for me with some reason but this things works.
getWindow().setBackgroundDrawableResource(R.mipmap.img_reg_bg);
put it in oncreate method hope it will help.
If I guess right you try to fix your hotfix to get it working propperly. If I'm right you sould go back to scratch and do it without your scrollview.
If you have a look at following Link:
http://developer.android.com/guide/topics/manifest/activity-element.html#wsoft
you'll see softkeyboard mode can be adjusted. "adjustPan" should solve your problem.
"adjustPan"
The activity's main window is not resized to make room for the soft keyboard. Rather, the contents of the window are automatically panned so that the current focus is never obscured by the keyboard and users can always see what they are typing. This is generally less desirable than resizing, because the user may need to close the soft keyboard to get at and interact with obscured parts of the window.
Add someimgage to your drawable folderes, like drawable-mdpi, drawable-hdpi.
In your LinearLayout "#+id/top_layout" add attribute:
android:background="#drawable/someimage"
I'm working on an Android app with a slightly complex layout and I'm having nightmares to make it work the way I want.
My main layout is defined like this:
<RelativeLayout 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="#000000"
tools:context=".MainLayout" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<RelativeLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:scrollbars="none" />
<LinearLayout
android:id="#+id/menudown"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
... buttons ...
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="#+id/header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerInParent="true" >
... header content ...
</LinearLayout>
</RelativeLayout>
The idea of the layout is having a content frame(content), a footer menu (menudown) and a header (header) hovering over the content, aligned to the top of the screen. - Sorry guys, no image, confidential project.
The content is inflated with other layouts, depending on the section the user is, and some of them are forms to be filled. So, i just used the adjustPan and everything worked fine.
The problem here is: the client asked me to make the content scrollable while there's a soft keyboard showing, so that the user can view whatever he wrote on the other fields.
And it's painful because: the form fits the screen, so using content as a scrollview won't help, unless it gets resized.
And simply changing to adjustResize does not work because: the menudown goes up with the soft keyboard, which should not heappen. Also, the visual effect is terrible.
The app was already made for iPad (by someone else), and what heappens there is: the menudown remains aligned to the bottom of the screen, under the soft keyboard, which pushes only the content view up. Then, the content becomes scrollable, so that the user is able to see it entirely.
I have this same issue too, making keyboard behave the same way as it does on iOS. The best thing I can get from all the other posts is manually detecting the soft keyboard and moving the view up the difference.
This seems to be the best: How to check visibility of software keyboard in Android?
I have an activity that loads a fragments at runtime. When I start the application, the activity loads a fragment with an EditText. I use ActionBarSherlock with splitActionBarWhenNarrow so I have a split bar (an action bar at the botton of the screen). When the EditText get focus and the soft keyboard is loaded, it goes on top of the split bar, hiding it. On the action bar I also use NAVIGATION_MODE_LIST and I use the dropdown menu to load another fragment. When I load the other fragment, the lower action bar appears correctly on top of the soft keyboard, even if I go to the other fragment, at it keeps working correctly. I'll add some screenshot to clear it up:
First fragment loader, split bar not visibile with soft keyboard
After loading the second fragment using action bar navigation
Reloading another fragment, action bar still visibile
I tried with a test project with minimal code just to load the fragment and the behavior is the same, the split bar is hidden by the soft keyboard.
How can I make it show the split bar from the beginning?
Edit: android:windowSoftInputMode="adjustResize" doesn't change anything in this behavior
Activity layout:
<it.bem.remailr.MyFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_container"
android:orientation="horizontal"
android:background="#drawable/bg_no_repeat"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
Fragment layout:
<it.bem.remailr.MyRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<EditText
android:id="#+id/editText1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="top|left"
android:inputType="textMultiLine|textNoSuggestions"
android:windowSoftInputMode="adjustPan"
android:background="#00000000"
android:hint="#string/text_hint"
android:scrollHorizontally="false" >
</EditText>
<ProgressBar
android:id="#+id/progressBar1"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />
Have you tried posting a layout request to the main thread immediately following the input method being shown? You can determine whether the input method is shown/hidden by overriding the onSizeChanged() callback in your root View. As a dirty proof of concept, you could just post that layout request after a given duration (ensuring that you show the input method beforehand).
You could also use the ViewServer to run hierarchyviewer on your device, not emulator in order to determine what Views are present (that is, if the candidates are covering the split Action Bar). From what I remember though, the candidate views are added to the root Dialog that contains the KeyboardView anyway, so it's likely the split Action Bar is just under the space bar, as it were, rather than under the candidate view.
In order to implement onSizeChanged() you must extend the ViewGroup class that is at the root of your View hierachy. For example, you may have a LinearLayout as your root ViewGroup and all your Views are children of this. What you do then is create a new class called MyLinearLayout that extends LinearLayout, put MyLinearLayout as your root View in the xml file, and then implement the onSizeChanged() callback. It will then be called by the System when the input method is shown.
I recently updated my phone to gingerbread and to my horror one of my apps stopped working!
The app consists of a SurfaceView and a layout (view) that shows up as an overlay over this SurfaceView.
THe xml looks like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<com.mycompany.MySurfaceView
android:id="#+id/myview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
<include layout="#layout/settings"
android:layout_alignTop="#id/myview"
android:visibility="invisible"
android:id="#+id/settings"
/>
</RelativeLayout>
When the user press the menu button I use this code to show the view:
View settings = (View)findViewById(R.id.settings);
settings.setVisibility(View.VISIBLE);
This worked flawlessy on versions earlier than 2.3 but now the behaviour is very random.
Observations
Very rarely everything works.
Sometimes the view shows up after hiding / unhiding it.
Sometimes you can press the buttons on the view (even though it's invisible) this makes the view show up for the rest of the application lifetime.
The getVisibility method always report the correct value.
What I've tried
Rebuilding draw cache
Using BringToFront method
Post invalidate
Setting the initial value of the view to "visible", this makes everything work, but I really want it to be initially invisible!
If anyone wants to check the problem you can try it for yourself in my app (it's on market, search for "chainparticles").
Thanks!
Solved it by changing the views initial state to "gone". WTF?!