Quick question: at runtime I do a boolean check, if it returns true I would like to have two buttons in a relative layout on my MainActivity class. If its false I want to instead have two other widgets where those buttons would be (or near enough). How do I do that?
you could also implement a ViewSwitcher where a more complicated set of buttons/widgets can be switched out very easily with a single call to
ViewSwitcher mViewSwitcher = (ViewSwitcher) findViewById(R.id.viewswitcher);
if (some_logic == true) {
mViewSwitcher.showNext();
}
Set up your XML like this and the above will switch between the two LinearLayouts:
<ViewSwitcher
android:id="#+id/viewswitcher"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
--- buttons, Views, whatever---
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
--- buttons, Views, whatever---
</LinearLayout>
If you have just those two alternatives put them both in your layout and hide / show the one you want. View#setVisibility()
If you want it more dynamic you can add and remove widgets programmatically. ViewGroup#addView()
Modifying a RelativeLayout during runtime is quite complicated since you need to set all those layout parameters so you could add a simple layout like a FrameLayout in the place where the buttons should go and put them inside the frame. Has the advantage that you can setup all the relative layout parameters for the frame in xml.
Related
I am using the LinearLayout and inside there's button I am making visibilty gone based on supported states. SupportedStatuses are true then making Button as Visible but SupprtedStatuse are false then making button as Gone.
This is in a header and Button is Gone but still takes up the space.
Here is the Layout which I am using.
<LinearLayout
android:id="#+id/llparentView"
android:layout_width="match_parent"
android:layout_height="wrap_content
android:orientation="vertical">
<Button
android:id="#+id/btn_change_status"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
Anybody have a good solution then it helps me a lot.
You could use a FrameLayout around whatever layout you are using
For example:
<FrameLayout android:layout_width="match_parent" android:layout_height="wrap_content">
<!-- put your views here -->
</FrameLayout>
This will ensure when using View.GONE the FrameLayout collapses on the space.
Try to wrap your button in another Linear/Frame layout and change their visibility as well.
I need 2 relative layouts to overlap in a parent layout. I'm not sure what the parent layout should be, but I think it has to be FrameLayout.
<FrameLayout>
<RelativeLayout id=layout_one>
<Button></Button>
<ImageView></ImageView>
...
</RelativeLayout>
<RelativeLayout id=layout_two>
<Button id = a></Button>
<Button id = b></Button>
...
</RelativeLayout>
</FrameLayout>
Only one of the RelativeLayouts will be seen at a time. At first it is "layout_two". Then when Button "a" is clicked "layout_two" needs to be invisible and "layout_one" must appear. However, clicking Button a doesn't call onClick method, although I can see the button. Is there better way of doing what I'm trying to do?
Make Relative Layout as parent and then put your layouts on it.what I suggest is use Relative.
I want to place 2 ImageViews, one above the other.
Here is an example with a square and a circle.
How can I do that? I know only in runtime what images to use, so I cannot specify them in an xml file.
Thank you in advance.
You can use FrameLayout to stack views on each other.
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/img_green" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/img_red"/>
</FrameLayout>
then you may set android:layout_margin="" to properly position the ImageViews.
Note that the last child of FrameLayout is the top most visible view
You should specify their location inside the layout programmatically, this is not exactly what you are asking for, but you will get an idea of what you have to do :
How to create a RelativeLayout programmatically with two buttons one on top of the other?
Since absolute layout is deprecated you probably have to play with margins.
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 two layouts, what is the best way to switch between the two layouts when a user clicks on a button?
You could call setContentView(R.layout.layout2) on ButtonClick
The best way is to use android.widget.ViewFlipper. With it you can create different layout from xml and then switch among them with simple method like this:
ViewFlipper viewFlipper = (ViewFlipper) findViewById(R.id.myViewFlipper);
// you can switch between next and previous layout and display it
viewFlipper.showNext();
viewFlipper.showPrevious();
// or you can switch selecting the layout that you want to display
viewFlipper.setDisplayedChild(1);
viewFlipper.setDisplayedChild(viewFlipper.indexOfChild(findViewById(R.id.secondLayout)
Xml example with tree layouts:
<ViewFlipper
android:id="#+id/myViewFlipper"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/firstLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
[...]
</LinearLayout>
<LinearLayout
android:id="#+id/secondLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
[...]
</LinearLayout>
<LinearLayout
android:id="#+id/thirdLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
[...]
</LinearLayout>
</ViewFlipper>
Use ViewSwitcher.
make one layout file that includes two layouts. your two layouts should be place in viewswitcher.
associate an onclick listener that switch two layout with a button.
if you separate two layouts in different file, you can use tag in layout xml file.
Use "fragment manager" after creating fragments and putting your layouts into it on run time or "view pager" as it can also add swapping effect. Do not use setContentView(R.layout.your_layout) without clearing the previous layout (use "gone" or "clear") for changing layout on run time as it slows down your app (because now there are two layout running) and even creates confusion for the app.