I have many layouts that have different ViewGroup roots (LinearLayouts, RelativeLayouts, etc). These views all work as I expect, but now I am trying to add a top navigation bar. The problem is that the roots can have different paddings, and if I simply include my layout within each of these layouts, the navigation bar is limited in width by the parent's padding. I'd like this navigation bar to ignore the root's left/right/top padding and be completely full width at the very top of the layout. Is there anything I can do within the navigation bar's layout to achieve this, or am I doomed to have to modify all of the existing layouts to accommodate this?
While this seems like a pretty bad idea to begin with, you might be able to accomplish what you're looking for by setting the clipToPadding attribute of the parent ViewGroup to false and then set negative margins on the child view.
Example:
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="#EEE"
android:clipToPadding="false">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello"
android:background="#333"
android:layout_marginLeft="-10dp"
android:layout_marginRight="-10dp"
android:layout_marginTop="-10dp"/>
</LinearLayout>
The above example works, but I would suggest that you should just put your top navigation bar outside of these ViewGroup that contain the paddings you're trying to avoid.
Why would you need to change all of your layouts? If it's only your navigation bar that needs to ignore the padding, you could just take the nav bar out of it's current parent layout, and then put both layouts inside another layout that has no padding.
Related
I'm trying to insert a fragment into my application and it's essentially a coloured bar with a few buttons on it. However, whenever I put the fragment onto the main xml file, there's always a bit of a white margin regardless of whatever I do. Here's an sample of some of the fragment code I have in my main xml:
<fragment
android:layout_width="fill_parent"
android:layout_height="50dp"
android:name="sample"
android:id="#+id/sample"
tools:layout="#layout/sample"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_margin="0dp" />
Even though I set the margin to 0dp and the width to fill_parent, there's still a white margin/border on the outside. Is there any way to make a fragment fill the screen widthwise entirely? Thank you!
You have padding and/or margin defined in your parent's ViewGroup that is causing the Fragment's extra spacing. Check the Parent who contains the Fragment and remove the padding :)
As the title says, I'm setting using setActionView on a MenuItem, here's the layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_margin="4dp"
android:layout_centerInParent="true"/>
</RelativeLayout>
The issue is that the ProgressBar appears aligned to the right. (It should be aligned to the center, same as the MenuItem icon. Icons are 32dp
How can I achieve this?
I faced similar issue today and coudn't find any good QA on SO. Hence I did some research. Here are my findings on the matter:
Android Menu is implemented in this way:
If you have inflated an actionView to have:
icon (optional)
title (optional, or to say it can be made optional by setting it as "")
a custom view
and you don't set icon, set title as "" and set actionView to make the menuItem appear to contain only the custom view which you inflated using setActionView, then:
Android forces the custom view's width to be wrap_content and remaining area gets occupied by icon+title of the menuItem.
We can think of this implementation as:
Think of the entire view after margin as ParentLinearLayout which is divided into LinearLayout1 and LinearLayout2 (depicted in the image above as Layout 1 and Layout 2 respectively)
Now LinearLayout1 has width=0dp and weight=1
And LinearLayout2 has width=wrap_content
Hence no matter what we set, currently, we cannot right align the inflated custom view (action view) in menu.
To be technically accurate, you can right align if you really need this done by checking out the internal implementation code for the navigation menu by Android. But not really worth the effort. Any feature is a tradeoff of time required vs outcome.
Try this android:layout_gravity="center"
You should try android:gravity="center" in RelativeLayout.
I want to align two items next to eachother using a RelativeLayout, where the vertical center of both items are equal.
For example, if I want this layout:
****
**** *******
****
************
I'd build something like:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View
android:id="#+id/view1"
android:layout_width="100dp"
android:layout_height="100dp"/>
<View
android:id="#+id/view2"
android:layout_width="match_parent"
android:layout_height="20dp"
android:toRightOf="#id/view1"/>
<View
android:id="#+id/view3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/view1"/>
</RelativeLayout>
However, the only options I seem to have is alignBottom, alignTop and alignBaseline. Neither obviously give the desired effect.
Is it possible to get the vertical center of view2 to match the vertical center of view1 without using a nested layout?
Try using android:gravity="centerVertical" as an attribute in your RelativeLayout. This should center your child views in the vertical center of the RelativeLayout.
You can also try android:layout_centerVertical="true" as an attribute of the two Views that you want to align.
However, the best solution for this would probably be to create a custom ViewGroup. Then in onLayout of your custom ViewGroup, position your child Views exactly as meets your specifications.
I've done something similar, where the easiest "hack" was to create an invisible view, place it where ever I wanted, and then placed item A to the left of and item B to the right of this invisible view.
I originally got this idea from Stackoverflow, but don't have the link I used. This discusses the same idea.
I'm fairly new to Android development. I'm wondering what are the different ways that are used to design XML layouts. Ive been using the eclipse drag and drop interface and I've seen http://droiddraw.org/ while doing some searching. Just wondering if there are any other possibly better ways out there to design layouts that professions use because I'm having a hard time with the eclipse interface making complex designs?
First of all check out the android developer site user interface page
http://developer.android.com/guide/topics/ui/index.html
There are basically three different ways you can make an android layout:
XML
http://developer.android.com/guide/topics/ui/declaring-layout.html
You can define a static layout using XML. Perhaps a good way to think of it is a sort of shorthand. It is very easy to declare Views and attributes, and the hierarchical format of XML makes it a bit easier to visualize.
This is a typical layout
<?xml version="1.0" encoding="utf-8"?>
<ViewGroup xmlns:android="http://schemas.android.com/apk/res/android"
android:attribute="value" >
<ViewGroup android:attribute="value" >
<View android:attribute="value" />
</ViewGroup>
<View android:attribute="value" />
</ViewGroup>
Then you use setContentView(R.layout.layout) in your activity and go about your business.
Java
You can do everything you would do in XML, plus add things like listeners, or do other dynamic things that you cannot in XML. Here is how you might declare a typical layout (ViewGroup is abstract so you would have to use a subclass. The same goes for XML)
ViewGroup parent = new ViewGroup(this);
ViewGroup vg1 = new ViewGroup(this);
View v1 = new View(this);
View v2 = new View(this);
parent.addView(vg1);
vg1.addView(v1);
parent.addView(v2);
v1.setOnAwesomeListener(new AwesomeListener() {
onAwesome(View v) {
doDynamicThings();
}
}
setContentView(parent);
Hybrid
This is the case used most often in my opinion. Declare a layout in XML with an id, like android:id="#+id/v1" then load Views from XML into Java
setContentView(R.layout.layout);
View v1 = findViewById(R.id.v1);
// dynamically change v1
How to design a layout using XML
So the lack of GUI designer tools has left you no choice but to dive into coding up your layout by hand. Good news is that once you get the hang of it you should be able to tackle any layout you wish. Let's look at the building blocks
ViewGroup
First off you need to choose a ViewGroup to define the structure of the layout, or section of the layout. Remember that these can be nested, so design top-down and try to classify sections of the layout based on the form you want them to have. There are two main options:
LinearLayout
As the name implies, useful for arranging items in a line. Choose an orientation, horizontal or vertical, and simply add items. They will be added in top to bottom or left to right ordering.
RelativeLayout
Useful for placing an item in a specific location on the screen. So if you want to put a button in the top-left, or a bar across the top, this is your ViewGroup.
Layout Parameters
Used for defining the width, height, weight, and other aspects of a view.
There are two options for width and height: fill_parent (replaced with match_parent in API level 8) and wrap_content. The view can choose to either fill the parent view's width, or take only the space it needs.
There is another useful layout parameter, unique to LinearLayout, called weight. It is useful for letting views share space in ratios, or letting one view take the space left over after other views in the LinearLayout take their share.
Example
Let's try to design the layout for Google Maps. Pretend it is a layout that I have in my head, and I want to implement it. Here is a screenshot
I will try to break this down:
Looking at it, there is a bar across the top and a map underneath it. I believe this could be implemented with either a LinearLayout or a RelativeLayout. However, the buttons in the bottom right and left scream RelativeLayout, so I will go with that.
<?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" >
<TODO:BAR
android:id="#+id/bar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true">
</TODO:BAR>
<MapView
android:id="#+id/map"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/bar" />
<ImageButton
android:id="#+id/latitude"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_marginBottom="20dp"
android:layout_marginLeft="20dp" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginBottom="20dp"
android:layout_marginRight="20dp"
android:orientation="vertical" >
<ImageButton
android:id="#+id/zoom_in"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageButton
android:id="#+id/zoom_out"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</RelativeLayout>
Now some explanation. In RelativeLayout you use alignParent[direction] to specify where the view goes. I also wanted some space on the sides, so I used margin[direction] to specify in dp or density-independent pixels. As you can see, wrap_content is used most of the time, so the buttons would acquire the size of the image used on them.
Now everything is defined but the bar at the top. I'm going to break it up into four different Views: The dropdown menu view, the search view, the layers button and the my location button. The way I would like it to work is put the menu at the far left, and the layers and my location buttons on the right, with the search box taking up the remaining space. This sounds like a job for LinearLayout and weight! Here is how I define the bar, which can be inserted into the placeholder above to get the final layout
<LinearLayout
android:id="#+id/bar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true" >
<ImageButton
android:id="#+id/dropdown_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<EditText
android:id="#+id/search"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<ImageButton
android:id="#+id/layers"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageButton
android:id="#+id/my_location"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Setting the width of the search bar to 0dp means let the other views take what they need, then the weight says take the remaining space.
And there you have it. A recreation of the basic layout for the Google Maps app (minus button images and other niceties like custom views), showing how you might use various layouts and XML fairly painlessly. Hopefully this was useful.
The tool chain is a little weak in this area. I don't really care for DroidDraw, and the Eclipse GUI editor is not very good for anything more than simple layouts. It often renders RelativeLayouts incorrectly for example.
Personally I do almost everything directly in XML. You have to understand how all the different Layout classes work to do anything complex anyway. The only real downside to XML is that all of the extra cruft from tags, attributes, etc. makes for a lot of extra stuff to type, but the editor takes care of most of that for you.
I have many activities with a scrollview inside a tablelayout. However, it is necessary a small design change, so I have to put a black transparent view over the whole screen from the top to the bottom. Is it possible to do it in the tablelayout or the scrollview?
RelativeLayout allows for easy overlapping of views. You'll have to adjust the existing views in your app because it doesn't do anything automatically.
EDIT:
A quick way to do this would be to take your existing view (the ScrollView) that is already organized and put it in a top-level RelativeLayout. Then, all you have to do is add new view inside the RelativeLayout with the width and height both set to MATCH_PARENT. The result should be the black transparent view will be visible over the ScrollView.
I normally use FrameLayout to achieve any kind of 'layering' of views.
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
//your existing layout
<View
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#33000000" />
</FrameLayout>
As DeeV said, you can probably use RelativeLayout in a similar way, but you might have to set additional attributes on its children to achieve this.