I've done this before with no issue so i know my mistake is subtle.
picker_dialog_layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="left|center_horizontal"
android:id="#+id/pickerDialog_title"
android:text="HELLO WORLD!!"/>
<NumberPicker
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/pickerDialog_title"
android:id="#+id/pickerDialog_selector"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/pickerDialog_selector"
android:orientation="horizontal">
<Button
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="5"
android:id="#+id/pickerDialog_cancel"
android:gravity="center"
android:text="Cancel"/>
<Button
android:layout_height="match_parent"
android:layout_width="0dp"
android:layout_weight="5"
android:id="#+id/pickerDialog_set"
android:gravity="center"
android:text="Set"/>
</LinearLayout>
</merge>
During the Custom Class constructor, PickerDialog(Context context, AttributeSet attrs, int defStyle) i call:
LayoutInflater.from(context).inflate(R.layout.picker_dialog_layout, this);
And in the parent XML:
<com.company.simonaddicott.controlpanel_1.PickerDialog
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/pickerDialog" />
The view itself does show, and from using layout bound tools in developer tools i can identify that the ui elements are present, or at least the boundaries are present (see below)
What am i missing from this to make there UI elements appear like they should??
My mistake was that I extended the custom view by LinearLayout, but was using RelativeLayout positioning on the picker_dialog_layout.xml.
The elements inside the layout were not showing as they had no relative parent element to be positioned against
Related
I have a custom designed button (LinearLayout) that I want to reuse multiple times by just replacing a couple of attributes of the layout's nested views (icon and text).
I understand that using the <include> tag I can only override root view attributes.
I can sure do it programatically in java, but I wonder if there is a smart way to do this in XML.
Essentially, I want to be able to use something like <include> to reuse below shown complex layout and override only the following two nested attributes in two different nested views:
...
android:src="#drawable/google_icon"
...
android:text=" Google"
...
My (not yet) reusable layout:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/button_vertical_margin"
android:layout_marginBottom="#dimen/button_vertical_margin"
android:gravity="center_horizontal"
android:clickable="true"
android:background="#drawable/default_button_selector">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="-2dp"
android:background="#drawable/layout_border"
android:gravity="center">
<ImageView
android:layout_width="#dimen/button_icon_size"
android:layout_height="#dimen/button_icon_size"
android:layout_margin="#dimen/button_icon_margin"
android:src="#drawable/google_icon" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/layout_border"
android:gravity="center"
android:paddingLeft="#dimen/button_text_horizontal_padding"
android:paddingRight="#dimen/button_text_horizontal_padding">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/button_text_vertical_margin"
android:layout_marginBottom="#dimen/button_text_vertical_margin"
android:textSize="#dimen/button_text_size"
android:text="Continue with" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/button_text_vertical_margin"
android:layout_marginBottom="#dimen/button_text_vertical_margin"
android:text=" Google"
android:textSize="#dimen/button_text_size"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
In my activity, I am setting the layout activity_main onCreate. I am then wanting to inflate my CardView for each of the items in my array.
So far, I've got everything loaded, however my CardView's have lost their margin. When added to the layout through XML, the margin works, but when its inflated as a separate XML file the margin is lost.
I am inflating the activity_main_card like so:
LinearLayout item = (LinearLayout)findViewById(R.id.card_holder);
View child = getLayoutInflater().inflate(R.layout.activity_main_card, null);
item.addView(child);
In the activity_main_card, my XML is as follows:
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="#+id/card_view"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardCornerRadius="2dp"
android:layout_marginBottom="16dp">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:scaleType="fitCenter"
android:background="#drawable/cin"/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="#color/dark_grey"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp"
android:textStyle="normal"
android:textColor="#color/grey_500"/>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
Can anyone point me in the direction where I am going wrong?
You're passing in null as the parent ViewGroup parameter to inflate(). This will cause all layout_* attributes to be ignored, as the inflater has no idea which attributes are valid for the container in which it will be placed (i.e. it has no idea which LayoutParams type to set on the View).
View child = getLayoutInflater().inflate(R.layout.activity_main_card, null);
should be
View child = getLayoutInflater().inflate(R.layout.activity_main_card, item, false);
For more info, see this great article about it -- it's a common mistake.
I want to create a composite view from a bunch of controls, by extending a LinearLayout.
I'm using an XML file to specify the inner layout of my custom control. I'm inflating the custom control from the code via LayoutInflater.
The Problem is:
If i replace the root LinearLayout element to a merge element in the XML, my whole layout fall apart. If I don't, then I only encapsulated a LinearLayout with my custom one.
The question is:
What do i have to change in the merge layout, so my view looks like how a linear layout should?
How it looks like:
With LinearLayout (this is how i want it to look like):
http://oi45.tinypic.com/2pqwby1.jpg
With merge (this is the tag i want to use):
http://i45.tinypic.com/155j4o0.png
The code:
TowerLayout.java (no problems here, just in case):
public class TowerLayout extends LinearLayout implements OnClickListener {
public TowerLayout(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater.from(context).inflate(R.layout.tower_layout, this, true); //this is what i want to use.
//((LinearLayout)findViewById(R.id.root)).setOnClickListener(this); //this is the current ugly workaround.
this.setClickable(true);
setOnClickListener(this);
}
#Override
public void onClick(View v) {
Toast.makeText(getContext(), "Foo", Toast.LENGTH_SHORT).show();
}
}
What i have in Tower_Layout.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="match_parent"
android:clickable="true"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:duplicateParentState="true">
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="TowerA"
android:textAppearance="?android:attr/textAppearanceLarge"
android:duplicateParentState="true"
android:textSize="32sp" />
<ImageView
android:id="#+id/imageView1"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="0.28"
android:duplicateParentState="true"
android:src="#drawable/icon" />
</LinearLayout>
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Basic information"
android:duplicateParentState="true"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_marginLeft="15dip"
android:layout_height="wrap_content"
android:duplicateParentState="true"
android:text="Lorem ipsum dolor sit amet, consectetuer adipiscing elit." />
<TextView
android:id="#+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:duplicateParentState="true"
android:text="16m"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="100sp" />
What i want in Tower_Layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:duplicateParentState="true">
...
</LinearLayout>
...
</merge>
One more thing:
I know, the screenshots are from the eclipse designer, but believe me: they look like this on android phone as well.
You should explicitly set the android:orientation tag for your layouts(and any LinearLayout, ever). Android supposedly uses horizontal by default, but in my experience it just messes it up if it's not set, and leads to some very strange-looking layouts.
I have a custom view like this
public class ButtonBar extends HorizontalScrollView
{
public View mButtonRows;
public ButtonBar(Context context, AttributeSet attrs)
{
super(context, attrs);
LayoutInflater inflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mButtonRows = inflater.inflate(R.layout.toolbar, null);
// button click handling code goes here
addView(mButtonRows);
}
}
which is included in my main xml like this
<com.example.ButtonBar
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_below="#+id/pagecontent" />
and inflates an xml file like this:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ButtonsRow"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="#+id/button1"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_weight="0.3"
android:text="button1"
/>
<Button
android:id="#+id/button2"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_weight="0.3"
android:text="button2"
/>
<Button
android:id="#+id/button3"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_weight="0.3"
android:text="button3"
/>
</LinearLayout>
(It currently only has three buttons, but more are going to be needed in later versions, hence the HorizontalScrollView.)
Looking in hierarchyviewer, the custom view does seem to be screen wide, but the LinearLayout is only as wide as the buttons it contains (about 2/3 of the screen at the current button size), despite having the fill_parent width set; the buttons don't stretch. If I set the LinearLayout's background to #android:drawable/bottom_bar (which is a png the width of the screen), the buttons properly resize; I realise I could do the same thing by creating my own images to match, but I'd much rather do it without if possible.
What am I doing wrong?
ETA: if I change HorizontalScollView to ScrollView, it works fine. Do HSVs just not allow their children to "fill_parent"?
ETA2: Setting android:fillViewport="true" in the main xml fixed it!
Setting android:fillViewport="true" in the main xml fixed it!
If you change to this, for each of the buttons, does it work?
android:layout_width="0px"
android:layout_weight="1"
I have a TextView which I want to pin at the bottom of a landscape activity that is using LinearLayout with vertically arranged elements.
I have set android:gravity="bottom" on the text view, but it still likes to be just below the last element of the LinearLayout exactly what I do not want it to do.
Any suggestions?
You will have to expand one of your upper views to fill the remaining space by setting android:layout_weight="1" on it. This will push your last view down to the bottom.
Here is a brief sketch of what I mean:
<LinearLayout android:orientation="vertical">
<View/>
<View android:layout_weight="1"/>
<View/>
<View android:id="#+id/bottom"/>
</LinearLayout>
where each of the child view heights is "wrap_content" and everything else is "fill_parent".
Update: I still get upvotes on this question, which is still the accepted answer and which I think I answered poorly. In the spirit of making sure the best info is out there, I have decided to update this answer.
In modern Android I would use ConstraintLayout to do this. It is more performant and straightforward.
<ConstraintLayout>
<View
android:id="#+id/view1"
...other attributes elided... />
<View
android:id="#id/view2"
app:layout_constraintTop_toBottomOf="#id/view1" />
...other attributes elided... />
...etc for other views that should be aligned top to bottom...
<TextView
app:layout_constraintBottom_toBottomOf="parent" />
If you don't want to use a ConstraintLayout, using a LinearLayout with an expanding view is a straightforward and great way to handle taking up the extra space (see the answer by #Matthew Wills). If you don't want to expand the background of any of the Views above the bottom view, you can add an invisible View to take up the space.
The answer I originally gave works but is inefficient. Inefficiency may not be a big deal for a single top level layout, but it would be a terrible implementation in a ListView or RecyclerView, and there just isn't any reason to do it since there are better ways to do it that are roughly the same level of effort and complexity if not simpler.
Take the TextView out of the LinearLayout, then put the LinearLayout and the TextView inside a RelativeLayout. Add the attribute android:layout_alignParentBottom="true" to the TextView. With all the namespace and other attributes except for the above attribute elided:
<RelativeLayout>
<LinearLayout>
<!-- All your other elements in here -->
</LinearLayout>
<TextView
android:layout_alignParentBottom="true" />
</RelativeLayout>
I think it will be perfect solution:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- Other views -->
<Space
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<!-- Target view below -->
<View
android:layout_width="match_parent"
android:layout_height="wrap_content">
</LinearLayout>
Step 1 : Create two view inside a linear layout
Step 2 : First view must set to android:layout_weight="1"
Step 3 : Second view will automatically putted downwards
<LinearLayout
android:id="#+id/botton_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<View
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<Button
android:id="#+id/btn_health_advice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
You should put the parameter gravity to bottom not in the textview but in the Linear Layout. Like this:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="bottom|end">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Something"/>
</LinearLayout>
You can also use
android:layout_gravity="bottom"
for your textview
DO LIKE THIS
<LinearLayout
android:id="#+id/LinearLayouts02"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="bottom|end">
<TextView
android:id="#+id/texts1"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_weight="2"
android:text="#string/forgotpass"
android:padding="7dp"
android:gravity="bottom|center_horizontal"
android:paddingLeft="10dp"
android:layout_marginBottom="30dp"
android:bottomLeftRadius="10dp"
android:bottomRightRadius="50dp"
android:fontFamily="sans-serif-condensed"
android:textColor="#color/colorAccent"
android:textStyle="bold"
android:textSize="16sp"
android:topLeftRadius="10dp"
android:topRightRadius="10dp"
/>
</LinearLayout>
try this
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:orientation="vertical" >
<TextView
android:id="#+id/textViewProfileName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView" />
</LinearLayout>