I'm trying to make a layout with 10 equal height rows, each row containing an ImageView and a TextView. When I put an image into the ImageView, I would like it scaled to retain the same aspect and fit inside the ImageView, not changing the ImageView size or the height of the containing TableRow.
The problem I have is that when I load an image into the ImageView, the ImageView seems to expand, and it also changes the height of the TableRow (?) I've been looking at this for a while, but can't seem to get it to work. It's possible I have missed one of the details of how Android layout or an ImageView works (?)
I've created a smaller example from my code which exhibits the problem. I've also set the background color on the ImageView so it is easier to see it change size.
Below are my layout files and code (apologies for the formatting, I have also put the complete Eclipse project at http://dl.dropbox.com/u/28937795/ImageRowSample.zip)
Any help would be appreciated. =)
MAIN.XML
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TableRow style="#style/SlashRowStyle">
<ImageView style="#style/SlashViewStyle" />
<TextView style="#style/NumberViewStyle" android:text="0" />
</TableRow>
<TableRow style="#style/SlashRowStyle">
<ImageView style="#style/SlashViewStyle" />
<TextView style="#style/NumberViewStyle" android:text="1" />
</TableRow>
<TableRow style="#style/SlashRowStyle">
<!-- I'm setting the background of this ImageView
so it's easier to see it change size -->
<ImageView android:id="#+id/image2" style="#style/SlashViewStyle"
android:background="#FF0000"/>
<TextView style="#style/NumberViewStyle" android:text="2" />
</TableRow>
<TableRow style="#style/SlashRowStyle">
<ImageView style="#style/SlashViewStyle" />
<TextView style="#style/NumberViewStyle" android:text="3" />
</TableRow>
<TableRow style="#style/SlashRowStyle">
<ImageView style="#style/SlashViewStyle" />
<TextView style="#style/NumberViewStyle" android:text="4" />
</TableRow>
<TableRow style="#style/SlashRowStyle">
<ImageView style="#style/SlashViewStyle" />
<TextView style="#style/NumberViewStyle" android:text="5" />
</TableRow>
<TableRow style="#style/SlashRowStyle">
<ImageView style="#style/SlashViewStyle" />
<TextView style="#style/NumberViewStyle" android:text="6" />
</TableRow>
<TableRow style="#style/SlashRowStyle">
<ImageView style="#style/SlashViewStyle" />
<TextView style="#style/NumberViewStyle" android:text="7" />
</TableRow>
<TableRow style="#style/SlashRowStyle">
<ImageView style="#style/SlashViewStyle" />
<TextView style="#style/NumberViewStyle" android:text="8" />
</TableRow>
<TableRow style="#style/SlashRowStyle">
<ImageView style="#style/SlashViewStyle" />
<TextView style="#style/NumberViewStyle" android:text="9" />
</TableRow>
<LinearLayout style="#style/ButtonBarStyle" >
<Button android:text="Add Image" android:onClick="onClickedAddImage"
android:gravity="center" android:layout_width="0dip"
android:layout_height="fill_parent" android:layout_weight="1" />
<Button android:text="Clear Image" android:onClick="onClickedClearImage"
android:gravity="center" android:layout_width="0dip"
android:layout_height="fill_parent" android:layout_weight="1" />
</LinearLayout>
</TableLayout>
.
STYLES.XML
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="SlashRowStyle" >
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">0dip</item>
<item name="android:layout_weight">1</item>
<item name="android:gravity">center</item>
</style>
<style name="SlashViewStyle" >
<!-- I want scaling so it fits in the Imageview with the same aspect.
I tried both fitCenter and centerInside -->
<item name="android:scaleType">fitCenter</item>
<item name="android:layout_width">0dip</item>
<item name="android:layout_height">fill_parent</item>
<item name="android:layout_weight">40</item>
<item name="android:gravity">center</item>
</style>
<style name="NumberViewStyle">
<item name="android:layout_width">0dip</item>
<item name="android:layout_height">fill_parent</item>
<item name="android:layout_weight">60</item>
<item name="android:gravity">center</item>
<item name="android:typeface">sans</item>
<item name="android:textStyle">bold</item>
<item name="android:textSize">20sp</item>
<item name="android:textColor">#0000FF</item>
</style>
<style name="ButtonBarStyle">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:orientation">horizontal</item>
<item name="android:background">#404040</item>
<item name="android:paddingTop">5dip</item>
</style>
</resources>
.
IMAGEROWSAMPLEACTIVITY.JAVA
public class ImageRowSampleActivity extends Activity {
private ImageView _iv;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
_iv = (ImageView)findViewById(R.id.image2);
}
public void onClickedAddImage(View v) {
_iv.setImageResource(R.drawable.x);
}
public void onClickedClearImage(View v) {
//_iv.setImageResource(0); //Tried this also
_iv.setImageDrawable(null);
}
}
After looking at it some more I finally stumbled onto the answer.
The problem is the TableRows in the TableLayout. The Android SDK TableLayout doc says that
The children of a TableLayout cannot specify the layout_width attribute. Width is always
MATCH_PARENT. However, the layout_height attribute can be defined by a child; default value
is WRAP_CONTENT. If the child is a TableRow, then the height is always WRAP_CONTENT.
The TableRow doc also says
The children of a TableRow do not need to specify the layout_width and layout_height
attributes in the XML file. TableRow always enforces those values to be respectively
MATCH_PARENT and WRAP_CONTENT.
So, yeah, the problem was the TableRows always ignoring my settings and making their heights WRAP_CONTENT, then also forcing the ImageView's height to be WRAP_CONTENT. When I converted the TableLayout and TableRows to LinearLayouts with the correct orientations, everything worked as I originally expected...
Related
I'm trying to align 3 TableLayouts within a ConstraintLayout. I want the table with the MaterialButtons to have 1:1 dimension ratio, while the table on the top and on start still completely remains within the bounds of the screen. This is what it currently looks like:
The definition of this TableLayout:
<TableLayout
android:id="#+id/play_field_table"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/play_field_row_values_table"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.7">
<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.google.android.material.button.MaterialButton style="#style/field_unpainted" />
...
<com.google.android.material.button.MaterialButton style="#style/field_unpainted" />
</TableRow>
...
</TableLayout>
The definition of the button's style:
<style name="field_unpainted" parent="Widget.MaterialComponents.Button.OutlinedButton">
<item name="android:layout_margin">0dp</item>
<item name="android:padding">0dp</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_weight">1</item>
<item name="android:insetTop">0dp</item>
<item name="android:insetBottom">0dp</item>
<item name="android:textAlignment">center</item>
<item name="android:textStyle">bold</item>
<item name="android:backgroundTint">#ffffff</item>
<item name="android:strokeColor">#000000</item>
<item name="cornerFamily">cut</item>
<item name="cornerRadius">0dp</item>
</style>
The definition of the TableLayout on the start:
<TableLayout
android:id="#+id/play_field_row_values_table"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginLeft="8dp"
app:layout_constraintBottom_toBottomOf="#+id/play_field_table"
app:layout_constraintEnd_toStartOf="#+id/play_field_table"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/play_field_table">
<TableRow
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="end|center_vertical"
android:text="1 1"
android:textAlignment="gravity"
android:textColor="#color/black" />
</TableRow>
...
</TableLayout>
This is the definition of the TableLayout on the top:
<TableLayout
android:id="#+id/play_field_column_values_table"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="#+id/play_field_table"
app:layout_constraintEnd_toEndOf="#+id/play_field_table"
app:layout_constraintStart_toStartOf="#+id/play_field_table">
<TableRow
android:layout_width="0dp"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_horizontal|bottom"
android:text="1"
android:textAlignment="gravity"
android:textColor="#color/black" />
...
</TableRow>
...
</TableLayout>
I've tried setting the layout_constraintDimensionRatio to 1:1 on the "id/play_field_table", but then it stretches out of the screen:
Also tried setting the layout_constraintDimensionRatio to 1:1 in the button style, but then the buttons either are just not displayed or the same result as above.
I feel like the ratios should be both set for the buttons and for the table, just can't figure out correct combinations. Any advice?
I managed to fix the issue by setting the following values for the "#+id/play_field_table" TableLayout:
Changed "layout_height" from "wrap_content" to "0dp" value
Added "layout_constraintDimensionRatio" with "1:1" value
Added "layout_weight" with "1" value to the TableRows inside the TableLayout
I have created a button layout with 4 separate "border" views (left, right, top, bottom) and alpha-numeric text intended to be in the center. I using the 4 separate border views so I can selectively hide (or not) each side. When used in a grid layout, I intend to enable the borders on a per button basis to create gridlines between the buttons (think tic-tac-toe lines).
But I cannot seem to center the alpha-numeric text vertically inside the button. Any help would be appreciated.
Here is the relevant xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/dialPadButton"
android:id="#+id/pad_btn_2"
android:orientation="horizontal"
android:background="#android:color/darker_gray">
<!-- Left Border -->
<View style="#style/dialPadButtonVerticalBorderStyle"
android:id="#+id/left_border"
android:visibility="visible"
android:layout_alignParentLeft="true"
></View>
<RelativeLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Top Border -->
<View style="#style/dialPadButtonHorizontalBorderStyle"
android:id="#+id/top_border"
android:visibility="visible"
android:layout_alignParentTop="true"
></View>
<!-- Alpha-numeric text -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:orientation="vertical">
<TextView style="#style/dialPadButtonNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAlignment="center"
android:textSize="#dimen/dial_number_text_size"
android:text="2"
android:layout_gravity="center" />
<TextView style="#style/dialPadButtonText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="#dimen/dial_letter_text_size"
android:text="abc"
android:layout_gravity="center" />
</LinearLayout>
<!-- Bottom Border -->
<View style="#style/dialPadButtonHorizontalBorderStyle"
android:id="#+id/bottom_border"
android:visibility="visible"
android:layout_alignParentBottom="true"
></View>
</RelativeLayout>
<!-- Right Border -->
<View style="#style/dialPadButtonVerticalBorderStyle"
android:id="#+id/right_border"
android:visibility="visible"
android:layout_alignParentRight="true"
></View>
</RelativeLayout>
For additional reference, here are the style definitions:
<resources>
<style name="dialPadButton">
<item name="android:layout_width">100dp</item>
<item name="android:layout_height">100dp</item>
<item name="android:fontFamily">sans-serif</item>
</style>
<style name="dialPadButtonNumber">
<item name="android:textColor">#00FF00</item>
<item name="android:maxLines">1</item>
</style>
<style name="dialPadButtonText">
<item name="android:textColor">#00FF00</item>
<item name="android:layout_marginTop">-10dp</item>
<item name="android:maxLines">1</item>
</style>
<style name="dialPadButtonHorizontalBorderStyle">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">2dp</item>
<item name="android:background">#EEEEEE</item>
</style>
<style name="dialPadButtonVerticalBorderStyle">
<item name="android:layout_height">match_parent</item>
<item name="android:layout_width">2dp</item>
<item name="android:background">#EEEEEE</item>
</style>
</resources>
you can do these
android:gravity="center"
or
android:layout_height="wrap_content"
on your LinearLayout
simply add
android:gravity="center"
to the linearlayout that holds the two textviews, the linear layout is defined match parent so you need the children to be gravity:center
like this :
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:gravity="center"
android:orientation="vertical">
<TextView style="#style/dialPadButtonNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAlignment="center"
android:textSize="25sp"
android:text="2"
android:layout_gravity="center" />
<TextView style="#style/dialPadButtonText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25sp"
android:text="abc"
android:layout_gravity="center" />
</LinearLayout>
How to stop checkbox from disappearing in code below when text in the TextView is too long? I'm not interested in hardcoding max_width for the TextView and I want to display my whole text.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/tv"
style="#style/Text"
android:layout_weight="0"
android:text="#string/multiple_sounds" />
<CheckBox
android:id="#+id/cb"
style="#style/Text"
android:layout_gravity="right"
android:layout_weight="1"/>
</LinearLayout>
styles.xml
<style name="Text">
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:padding">#dimen/margin</item>
<item name="android:textSize">#dimen/text</item>
<item name="android:textAlignment">center</item>
</style>
I would use weight. Add android:weightSum to your LinearLayout with value 1.
For each element in your LinearLayout add weight. For example 0.8 for textview and 0.2 for Checkbox.
Then set width to 0dp for each element !
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="1">
<TextView
android:id="#+id/tv"
style="#style/Text"
android:layout_weight="0.8"
android:text="#string/multiple_sounds" />
<CheckBox
android:id="#+id/cb"
style="#style/Text"
android:layout_gravity="right"
android:layout_weight="0.2"/>
</LinearLayout>
And update your style :
<style name="Text">
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">0dp</item>
<item name="android:padding">#dimen/margin</item>
<item name="android:textSize">#dimen/text</item>
<item name="android:textAlignment">center</item>
</style>
If you are about to display large data on textview, i suggest to use scroll view in your parent layout.
I'm late for this but I hope to help smn with this issue. Have same problem checkBox make TextView unreachable for LinearLayout, both checkBox and textView need to have this line in xml:
android:layout_gravity="center_vertical"
use text view weight = 1 and other view as wrap_content so size of other view not change according your text
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="1">
<TextView
android:id="#+id/tv"
style="#style/Text"
android:layout_weight=""
android:text="#string/multiple_sounds" />
<CheckBox
android:id="#+id/cb"
style="#style/Text"
android:layout_gravity="right"
android:layout_weight="wrap_content"/>
</LinearLayout>
If you want text to go in new line (use RelativeLayout):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<CheckBox
android:id="#+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true" />
<TextView
android:id="#+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toStartOf="#id/checkbox" />
</RelativeLayout>
Another solution is to use this lib to shrink text:
https://github.com/grantland/android-autofittextview
I would suggest to use RelativeLayout to maintain uniformity in UI. Below is sample Relative layout code
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="2">
<TextView
android:id="#+id/tv"
style="#style/Text"
android:layout_toLeftOf="#+id/cb"
android:text="#string/multiple_sounds" />
<CheckBox
android:id="#+id/cb"
style="#style/Text"
android:layout_gravity="right"
android:layout_alignParentEnd="true"/>
</RelativeLayout>
I am quite new to android and i am designing a Table layout with every row containing two textviews.The problem is that the text in textview gets truncated if text is long.I have used wrap content and applied weight also but not help me .The code for layout is below
<TableLayout
android:id="#+id/tableLayout"
style="#style/fill_parent_wrap_content" >
<TableRow style="#style/both_wrap_content" >
<TextView
style="#style/InfoTextView1"
android:text="#string/customerName"
android:textStyle="bold" />
<TextView
android:id="#+id/txtDetailCustomerName"
style="#style/InfoTextView1" />
</TableRow>
<TableRow style="#style/both_wrap_content" >
<TextView
style="#style/InfoTextView1"
android:text="#string/caNumberDetail"
android:textStyle="bold" />
<TextView
android:id="#+id/txtDetailCaNo"
style="#style/InfoTextView1" />
</TableRow>
<TableRow style="#style/both_wrap_content" >
<TextView
style="#style/InfoTextView1"
android:text="#string/customerAddress"
android:textStyle="bold" />
<TextView
android:id="#+id/txtDetailAddress"
style="#style/InfoTextView1"
/>
</TableRow>
</TableLayout>
</Scrollview>
This is a style that i apply to textviews
<style name="InfoTextView1">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_marginLeft">5dp</item>
<item name="android:paddingTop">15dp</item>
<item name="android:textColor">#color/Black</item>
<item name="android:textSize">#dimen/text_size_small</item>
</style>
Try this..
<TableRow
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:weightSum="2">
<TextView
android:layout_height="50dp"
android:layout_width="0dp"
android:layout_weight="1"
android:singleLine="true"
android:ellipsize="marquee"/>
<TextView
android:layout_height="50dp"
android:layout_width="0dp"
android:layout_weight="1"
android:singleLine="true"
android:ellipsize="marquee"/>
</TableRow>
Then put this line in java file textview.setSelected(true);
Show the style for the TableLayout and TableRows...
I bet the problem is on them.
This one puzzles me since my first steps with Android. I can't make both columns in a 2-column TableLayout exact 50% each.
Here's an example:
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="fill_parent" >
<TableLayout
android:id="#+id/tablelayout"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:paddingRight="2dip" >
<TableRow>
<TextView
style="#style/TextViewStandard"
android_layout_span="2"
android:layout_weight="1"
android:text="Bla" />
</TableRow>
<TableRow>
<TextView
style="#style/TextViewStandard"
android:layout_weight="1"
android:text="Name:" />
<EditText
style="#style/EditTextStandard"
android:id="#+id/et_name"
android:layout_weight="1" />
</TableRow>
<TableRow>
<TextView
style="#style/TextViewStandard"
android:layout_weight="1"
android:text="URL:" />
<EditText
style="#style/EditTextStandard"
android:id="#+id/et_url"
android:layout_weight="1" />
</TableRow>
<TableRow>
<Button
style="#style/ButtonStandard"
android:layout_column="0"
android:layout_marginTop="6dip"
android:onClick="onClickOk"
android:text="#android:string/ok" />
</TableRow>
</TableLayout>
</ScrollView>
And here's the corresponding style definition:
<resources>
<style name="ButtonStandard" parent="#android:style/Widget.Button">
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">fill_parent</item>
</style>
<style name="EditTextStandard" parent="#android:style/Widget.EditText">
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_marginLeft">2dip</item>
<item name="android:layout_marginRight">2dip</item>
<item name="android:layout_marginTop">2dip</item>
<item name="android:layout_width">fill_parent</item>
</style>
<style name="TextViewStandard" parent="#android:style/Widget.TextView">
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_marginLeft">2dip</item>
<item name="android:layout_marginRight">2dip</item>
<item name="android:layout_marginTop">2dip</item>
<item name="android:layout_width">fill_parent</item>
<item name="android:textColor">#android:color/white</item>
</style>
</resources>
This becomes really messed up with a CheckBox involved.
What's wrong with my definition?
Many thanks in advance.
HJW
Have you tried to set the android:layout_width attribute to 0dp (and of course keep the android:layout_weight as 1) on the child views?
I have been in similar scenarios when I also wanted to distribute the given space equally between two child views but failed to do so since the child with "wider content" also became wider, within its parent, than its sibling. This was due to the fact that the wider child had a greater initial width. Making sure both children started of from the same width (android:layout_width="0dp" on both of them) also guaranteed to distribute the space evenly among them.
This is how I format my tables evenly. Not part of your question but to span all columns android:layout_span="2" on other TableRow children that do not contain the android:layout_column attribute. Hope this helps.
<TableLayout
android:id="#+id/tableLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:stretchColumns="0,1">
<TableRow
android:id="#+id/tableRow1"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/textView1"
android:layout_column="0">
</TextView>
<TextView
android:id="#+id/textView2"
android:layout_column="1">
</TextView>
</TableRow>
</TableLayout>
I would create a table layout
Inside a frame layout holding your control. In this example I have two columns layout and I put two ImageView's centered in each column.
<TableLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:stretchColumns="1">
<TableRow>
<FrameLayout
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1">
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/button_wedding_day_cheat_sheet"
android:id="#+id/buttonWeddingDayCheatSheet"
android:onClick="onClickWeddingDayCheatSheet"
android:layout_gravity="center_horizontal">
</ImageView>
</FrameLayout>
<FrameLayout
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1">
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/button_share_favorite_recipe"
android:id="#+id/buttonShareFavoriteRecipe"
android:onClick="onClickShareFavoriteRecipe"
android:layout_gravity="center_horizontal">
</ImageView>
</FrameLayout>
</TableRow>
</TableLayout>
The columns in the android table always adjust to the widest view which in any row. There are no explicit controls here of the columns. Grid view has more control of the column size such as: android:columnWidth="100dp"
If the left and righ view in the table would be set to the same size then a centered table could have two 50% spaced columns.