I'm doing summer lab assignment for my Android class.
In layout_main.xml I have:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="#layout/main_menu" />
<fragment
android:name="tests.tinyplanner.ActivityFragment"
android:id="#+id/mainActivityFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
In main_menu.xml I have:
<?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="wrap_content"
android:orientation="vertical" >
<tests.tinyplanner.ThemeButton
android:id="#+id/todoButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/todo_button_title" />
<tests.tinyplanner.ThemeButton
android:id="#+id/calendarButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/calendar_button_title" />
<tests.tinyplanner.ThemeButton
android:id="#+id/notesButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/notes_button_title" />
</LinearLayout>
For layout_main.xml I have a class:
package tests.tinyplanner;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
public class MainLayout extends LinearLayout {
private View todoButton;
private View calendarButton;
private View notesButton;
private LayoutInflater inflater_;
private View inflateView_;
private void doInflate(Context context) {
this.inflater_ = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.inflateView_ = this.inflater_.inflate(R.layout.layout_main, this);
this.todoButton = this.inflateView_.findViewById(R.id.todoButton);
this.calendarButton = this.inflateView_.findViewById(R.id.calendarButton);
this.notesButton = this.inflateView_.findViewById(R.id.notesButton);
}
public MainLayout(Context context, AttributeSet attrs) {
super(context, attrs);
this.doInflate(context);
}
public MainLayout(Context context) {
this(context, null);
}
public View getTodoButton() {
return this.todoButton;
}
public View getCaldendarButton() {
return this.calendarButton;
}
public View getNotesButton() {
return this.notesButton;
}
}
I use this layout in MainActivity
this.layout = new MainLayout(this);
TextView logoTextView = (TextView)((LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.logo_layout, null);
((MainLayout) this.layout).addView(logoTextView);
this.setContentView(this.layout);
this.todoButton = ((MainLayout)this.layout).getTodoButton();
this.todoButton.setOnClickListener(this);
this.calendarButton = ((MainLayout)this.layout).getCaldendarButton();
this.calendarButton.setOnClickListener(this);
this.notesButton = ((MainLayout)this.layout).getNotesButton();
this.notesButton.setOnClickListener(this);
All buttons are displayed correctly. The problem is that logoTextView is not displayed at all. logo_layout is like this:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:text="#string/logo_title"
android:id="#+id/logoTextView"
android:theme="#style/LogoTheme"
android:layout_height="wrap_content" >
</TextView>
LogoTheme is like this:
<style name="LogoTheme">
<item name="android:textStyle">bold</item>
<item name="android:textColor">#color/colorFontButtonDefault</item>
<item name="android:textAllCaps">true</item>
<item name="android:ems">80</item>
<item name="android:textSize">18sp</item>
<item name="android:gravity">center</item>
<item name="android:textAlignment" tools:targetApi="17">center</item>
</style>
Why is logoTextView not displayed?
Couple of things went wrong in your code. Before jumping into it, let me clear some concept
1) By default, orientation for Linear layout will be Horizontal. It means that all child view will be stack horizontally inside linear layout based on width defined for each child.
| ChildA | ChildB | ChildC |
2) If Any one child defines width as "MATCH_PARENT" then it will not allow to show other child underneath it, just like below
| ChildA | (Not visible) childB | (Not visible) childC|
Based on this information, Let try to understand your issue
First thing: Inside MainActivity, where you try to create a MainLayout, you need to specify Orientation for MainLayout
this.layout = new MainLayout(this);
((MainLayout)this.layout).setOrientation(LinearLayout.VERTICAL);
This will allow to stack all children vertically so that we can see all children
Second thing:, Inside layout_main.xml, please define layout_height of Linear layout as "wrap_content". This will allow your logotext to be seen on screen
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include layout="#layout/main_menu" />
<fragment
android:name="tests.tinyplanner.ActivityFragment"
android:id="#+id/mainActivityFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
EDIT: (Why need to add orientation even though setting it from XML)
Lets check how MainLayout is created. First we created instance of MainLayout inside Activity. which in turn call doInflatelayout() inside main layout.
By doing so what we are doing is, we create a linear layout and inside inflate new linear layout (with orientation set from XML)
By looking at the View Hierarchy:
MainLayout (Parent)
LinearLayout (with Orientation inside XML)
Linear Layout ( with ThemeButton and Orientation set from XML)
Now You have Orientation set for first child of MainLayout. But you are not setting orientation for MainLayout.
So we need to set Orientation for MainLayout when we create it.
I hope this will help you
Related
I would like to do something like this:
https://storage.googleapis.com/spec-host/mio-staging%2Fmio-design%2F1563837804615%2Fassets%2F1XlKhaQFU9aS84ACmF-EDjVKDgI4pPldv%2F02-overflowmenu.mp4
I would like to squeeze a "ViewGroup" as you can see in the video. In the meantime, I want to fade out the content in the ViewGroup at its original position. i.e. not pushing the content to the right.
Any idea how to implement this?
Thanks!
You can do such animations with Transition API. Declare two ViewGroups: first one is horizontal with cut/copy buttons, second is vertical with search/share buttons. Then switch these ViewGroups with TransitionManager. Then just provide Transition which describes how views on first and second ViewGroups appears and disappers.
import androidx.appcompat.app.AppCompatActivity;
import androidx.transition.ChangeBounds;
import androidx.transition.Fade;
import androidx.transition.Scene;
import androidx.transition.Slide;
import androidx.transition.Transition;
import androidx.transition.TransitionManager;
import androidx.transition.TransitionSet;
public class MainActivity extends AppCompatActivity {
private ViewGroup mSceneRoot;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_layout);
mSceneRoot = findViewById(R.id.sceneRoot);
showPopup1();
}
private void showPopup1() {
ViewGroup popup1 = (ViewGroup) getLayoutInflater().inflate(R.layout.popup_1, mSceneRoot, false);
popup1.findViewById(R.id.btnGo).setOnClickListener(v -> {
showPopup2();
});
Scene scene = new Scene(mSceneRoot, popup1);
TransitionManager.go(scene, getTransition(false));
}
private void showPopup2() {
ViewGroup popup2 = (ViewGroup) getLayoutInflater().inflate(R.layout.popup_2, mSceneRoot, false);
popup2.findViewById(R.id.btnBack).setOnClickListener(v -> {
showPopup1();
});
Scene scene = new Scene(mSceneRoot, popup2);
TransitionManager.go(scene, getTransition(true));
}
}
activity_layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/sceneRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom|right"
android:orientation="vertical"
android:paddingBottom="150dp"
android:paddingRight="50dp"
android:clipToPadding="false"
android:clipChildren="false"/>
popup_1.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/popup1"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:transitionName="bg"
app:cardElevation="10dp">
<Button
android:id="#+id/btnGo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="go"
android:transitionName="btn_go"/>
</androidx.cardview.widget.CardView>
popup_2.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/popup2"
android:layout_width="wrap_content"
android:layout_height="250dp"
android:transitionName="bg"
app:cardElevation="10dp">
<Button
android:id="#+id/btnBack"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="back"
android:transitionName="btn_back"/>
</androidx.cardview.widget.CardView>
Last thing here is getTransition method. You can just use AutoTransition, it can handle easy layout changes.
private Transition getTransition(boolean open) {
return new AutoTransition();
}
Result:
Also just for demostration I wrote more complex transition where button on first viewgroup appear/dissapear with Slide animation.
private Transition getTransition(boolean open) {
Slide btnGo = new Slide(Gravity.RIGHT);
btnGo.addTarget("btn_go");
ChangeBounds bgBounds = new ChangeBounds();
bgBounds.addTarget("bg");
Fade btnBack = new Fade();
btnBack.addTarget("btn_back");
TransitionSet set = new TransitionSet();
set.setOrdering(TransitionSet.ORDERING_SEQUENTIAL);
if (open) {
set.addTransition(btnGo);
set.addTransition(bgBounds);
set.addTransition(btnBack);
} else {
set.addTransition(btnBack);
set.addTransition(bgBounds);
set.addTransition(btnGo);
}
return set;
}
Result:
Note that transitionName for background should be same in both layouts.
All transition classes here are from androix package so code is backward compatible. But if you need support pre Lollipop devices you should set transitionName via ViewCompat.setTransitionName method.
You can check my another answer with more difficult/custom transition.
I'm trying to load an existing layout from XML and then create dynamically a button and a Circle, the reason which I cannot include them onto the XML is because the purpose is to create Circles dynamically, actually the following code is a snippet of what I want to create.
I know the way I am doing this (adding the layout) is wrong, but after reading a lot of Internet content I failed to did it by myself, because that I request help.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_etest);
LayoutInflater inflater;
inflater = this.getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout layout = (LinearLayout)
inflater.inflate(R.layout.activity_etest ,
null);
LinearLayout viewGroup = layout;
Button b1 = new Button(this);
b1.setText("test");
viewGroup.addView(b1);
viewGroup.addView(new Circle(this));
}
}
And my class Circle, which extends from View and its method onDraw() consists of:
... onDraw(){
canvas.drawCircle(x, y, radius, paint);
}
The parameters of drawCircle are not rellevant to this question. I have defined them elsewhere.
I also add the XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Button"
android:id="#+id/button12"
android:layout_gravity="center_horizontal" />
</LinearLayout>
create one view group like linearlayout in your xml and using its instance add your dynamic views in that.
activity_etest.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="#+id/viewg" xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
activity
setContentView(R.layout.activity_etest);
Linearlayout viewgroup = (LinearLayout)findViewById(R.id.viewg);
Button b1 = new Button(this);
b1.setText("test");
viewGroup.addView(b1);
viewGroup.addView(new Circle(this));
I have to move the indicator from the left to the right (because of the plane image). I couldn't succeed also because the expandableviewlist is inside a fragment and not inside a whole activity. Any idea? Thanks!
I don't know a way to do that from XML but i'll tell you a way to do so dynamically in your adapter.
First you have to remove group indicator from your xml
<ExpandableListView [...]
android:groupIndicator="#null" />
Then in your layout of the parent add an imageview in the right position of your layout.
Then in your custom adapter do the following
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
...
if (isExpanded) {
groupHolder.img.setImageResource(R.drawable.group_down);
} else {
groupHolder.img.setImageResource(R.drawable.group_up);
}
...
}
One more solution is:
1) First set groupIndicator in your ExpandableListView to #null:
<ExpandableListView [...]
android:groupIndicator="#null" />
2) Then create group_indicator.xml file with following details:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/down_icon" android:state_selected="false"></item>
<item android:drawable="#drawable/up_icon" android:state_selected="true"></item>
<item android:drawable="#drawable/down_icon"></item>
</selector>
3) Then create group_header.xml layout with following details and inflate this layout in getGroupView() method of ExpandableListAdapter.java:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp">
<TextView
android:id="#+id/tvHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:textColor="#color/white"
android:layout_centerVertical="true"
android:textSize="16sp"/>
<ImageView
android:id="#+id/ivGroupIndicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/group_indicator"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"/>
</RelativeLayout>
3) In getGroupView() method of your ExpandableListAdapter.java class, just set the following:
ivGroupIndicator.setSelected(isExpanded);
With this approach, your down_icon and up_icon will work properly.
Hope this helps.
put this into your xml view:
<ExpandableListView
...
android:layoutDirection="rtl" />
than you can set the gravity of your text title in your layout item according your preference.
your text view parent list item:
<TextView
...
android:gravity="center"/>
eg. result:
another solution to put the indicator on the right programmatically:
expandableListView = (ExpandableListView) findViewById(R.id.expandableListView);
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
Resources r = getResources();
int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
50, r.getDisplayMetrics());
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
expandableListView.setIndicatorBounds(width - px, width);
} else {
expandableListView.setIndicatorBoundsRelative(width - px, width);
}
where expandableListView is your ExpandableListview
In your groupcustom.xml file you can use Relativelayout and put that image to
android:alignParentRight = "true";
I have several layout files that are mostly the same, except for one section. Is there a way that I can have the common XML all in one place; instead of copy/pasting, and having to update a bunch of files when I want to make 1 change?
I know that I can include XML from other XML files, but the common code isn't an internal control; it is the outer wrapper; so include doesn't work. Basically, I have a bunch of files that all look like this:
<LinearLayout
android:id="#+id/row"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<ImageView android:layout_height="26dp"
android:id="#+id/checkImage"
android:layout_width="26dp"
android:layout_alignParentTop="true"
android:scaleType="fitCenter"/>
<!-- Different types of views go here depending on which layout file it is -->
<ImageButton android:layout_height="fill_parent"
android:id="#+id/playButton"
android:layout_width="42dp"
android:src="#drawable/play_button"
android:scaleType="center"
android:background="#00000000"/>
</LinearLayout>
Basically, I want to do what ASP.Net does with Master Pages. Is there any option for this?
The solution was pretty easy.
You need to extend "Activity" Class, in onCreate() function SetContentView to your base xml layout and also need to override setContentView in base Activity Class
For Example:
1.Create base_layout.xml with the below code
<?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="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="#+id/image_view_01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxHeight="50dp" />
</LinearLayout>
<LinearLayout
android:id="#+id/base_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</LinearLayout>
</LinearLayout>
Create BaseActivity.java
public class BaseActivity extends Activity {
ImageView image;
LinearLayout baseLayout;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.base_layout);
this.image = (ImageView) this.findViewById(R.id.image_view_01);
this.baseLayout = (LinearLayout) this.findViewById(R.id.base_layout);
this.image.setImageResource(R.drawable.header);
}
#Override
public void setContentView(int id) {
LayoutInflater inflater = (LayoutInflater)getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(id, this.baseLayout);
}
}
and SomeActivity.java
public class SomeActivity extends BaseActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.some_layout);
//rest of code
}
}
The only thing I noticed so far was that when requesting a progress bar (requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS)) this needs to be done before calling super.onCreate. I think this is because nothing can be drawn yet before calling this function.
This worked great for me and hopefully you will find this useful in your own coding.
Maybe you could use one main layout XML file and then add/remove other widgets dynamically through code as needed.
I was trying to do exactly this - I wanted a view that had a button on the left and a button on the right, but could have arbitrary content in the middle (depending on who was including it). Basically a custom view group that could have child view in the XML layout, and would wrap those child views with another XML layout. Here is how I did it:
top_bar.xml: This represents the common layout to wrap things with. Note the LinearLayout (could be any layout) with an ID "addChildrenHere" - it is referenced later.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/topBarLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="left" />
<LinearLayout
android:id="#+id/addChildrenHere"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<Button
android:id="#+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="right" />
</LinearLayout>
main.xml: The main layout. This includes a custom viewgroup (WrappedLayout) with a few children. Note how it declares a custom XML namespace, and sets two custom attributes on the WrappedLayout tag (these say which layout to wrap the children with, and where within that layout the children of this node should be placed).
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:karl="http://schemas.android.com/apk/res/karl.test"
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<karl.test.WrappedLayout
android:id="#+id/topBarLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
karl:layoutToInflate="#layout/top_bar"
karl:childContainerID="#+id/addChildrenHere">
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is a child of the special wrapper."
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is another child; you can put anything here."
android:textAppearance="?android:attr/textAppearanceMedium" />
</karl.test.WrappedLayout>
</LinearLayout>
attrs.xml: This goes in res/values. This defines the custom XML attributes used in the XML above.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="WrappedLayout">
<attr name="layoutToInflate" format="integer"/>
<attr name="childContainerID" format="integer"/>
</declare-styleable>
</resources>
Finally, WrappedLayout.java: This handles reading the custom attributes, and doing a bit of hackery to make addView() actually add the views in a different place.
package karl.test;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
public class WrappedLayout extends FrameLayout
{
///Attempts to add children to this layout will actually get forwarded through to mChildContainer.
///This would be final, but it's actually used indirectly by the constructor before it's initialised.
private ViewGroup mChildContainer;
public WrappedLayout(Context context, AttributeSet attrs)
{
super(context, attrs);
//read the custom attributes
final int layoutToInflate;
final int childContainerID;
{
final TypedArray styledAttributes = context.obtainStyledAttributes(attrs, R.styleable.WrappedLayout);
layoutToInflate = styledAttributes.getResourceId(R.styleable.WrappedLayout_layoutToInflate, 0);
childContainerID = styledAttributes.getResourceId(R.styleable.WrappedLayout_childContainerID, 0);
styledAttributes.recycle();
}
if(layoutToInflate == 0
|| childContainerID == 0)
{
Log.e("Error", "WrappedLayout.WrappedLayout(): Error reading custom attributes from XML. layoutToInflate = " + layoutToInflate + ", childContainerID =" + childContainerID);
}
else
{
//inflate the layout and (implicitly) add it as a child view
final View inflatedLayout = View.inflate(context, layoutToInflate, this);
//grab the reference to the container to pass children through to
mChildContainer = (ViewGroup)inflatedLayout.findViewById(childContainerID);
}
}
///All the addView() overloads eventually call this method.
#Override
public void addView(View child, int index, ViewGroup.LayoutParams params)
{
if(mChildContainer == null)
{
//still inflating - we're adding one of the views that makes up the wrapper structure
super.addView(child, index, params);
}
else
{
//finished inflating - forward the view through to the child container
mChildContainer.addView(child, index, params);
}
}
}
This works, as far as I can tell. It doesn't work very well with the Eclipse layout editor (I'm not quite sure what the problem is), but you can view the layout fine. Changing the children of the WrappedLayout seems to require editing the XML manually.
Have you looked at Applying Styles and Themes?
I want to show two views in one activity. If I clicked on button in the first view I want to see the second and other way round.
The views should not have the same size as the screen so I want e.g. to center it, like you see in first.xml.
But if I add the views with
addContentView(mFirstView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
the views are not centered. They are shown at top left.
How can I use the xml settings to e.g. center it?
first.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:background="#drawable/background"
android:layout_gravity="center"
android:minWidth="100dp"
android:minHeight="100dp"
android:paddingBottom="5dp"
>
<LinearLayout android:id="#+id/head"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageButton android:id="#+id/first_button"
android:src="#drawable/show_second"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#null" />
</LinearLayout>
second.xml same as first.xml but with
<ImageButton android:id="#+id/second_button"
android:src="#drawable/show_first"
... />
ShowMe.java
public class ShowMe extends Activity {
View mFirstView = null;
View mSecondView = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initFirstLayout();
initSecondLayout();
showFirst();
}
private void initFirstLayout() {
LayoutInflater inflater = getLayoutInflater();
mFirstView = inflater.inflate(R.layout.first, null);
getWindow().addContentView(mFirstView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
ImageButton firstButton = (ImageButton)mMaxiView.findViewById(R.id.first_button);
firstButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
ShowMe.this.showSecond();
}
});
}
private void initSecondLayout() {
// like initMaxiLayout()
}
private void showFirst() {
mSecondView.setVisibility(View.INVISIBLE);
mFirstView.setVisibility(View.VISIBLE);
}
private void showSecond() {
mFirstView.setVisibility(View.INVISIBLE);
mSecondView.setVisibility(View.VISIBLE);
}}
Hope someone can help.
Thanks
Why don't you use setContentView(R.layout.yourlayout)? I believe the new LayoutParams you're passing in addContentView() are overriding those you defined in xml.
Moreover, ViewGroup.LayoutParams lacks the layout gravity setting, so you would have to use the right one for the layout you're going to add the view to (I suspect it's a FrameLayout, you can check with Hierarchy Viewer). This is also a general rule to follow. When using methods that take layout resources as arguments this is automatic (they might ask for the intended parent).
With this consideration in mind, you could set your layout params with:
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(/* wrap wrap */);
lp.setGravity(Gravity.CENTER);
addContentView(mYourView, lp);
But I would recommend setContentView() if you have no particular needs.
EDIT
I mean that you create a layout like:
~~~/res/layout/main.xml~~~
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="....."
android:id="#+id/mainLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
then in your onCreate() or init...Layout():
setContentView(R.layout.main);
FrameLayout mainLayout = (FrameLayout)findViewById(R.id.mainLayout);
// this version of inflate() will automatically attach the view to the
// specified viewgroup.
mFirstView = inflater.inflate(R.layout.first, mainLayout, true);
this will keep the layout params from xml, because it knows what kind it needs. See reference.