I am programmatically adding a TableLayout to a parent LinearLayout in Android. The table has one row with two columns; an EditText and a Button. I am also specifying that the EditText can be stretched to fill the width while the Button remains constant in size (kind of like an input-append component). Everything is fine until I populate a long text as the value for the EditText, which seems to make it stretch so that the whole value can be displayed (rather than being ellipsized). This of course means the button is pushed off the right edge, making it unusable.
The added dynamic layout:
<?xml version="1.0" encoding="UTF-8"?>
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:stretchColumns="0">
<TableRow>
<EditText
android:id="#+id/added_text"
android:padding="8dp"
android:layout_width="wrap_content"
android:layout_height="64dp"
android:layout_marginLeft="8dp"
android:layout_gravity="center_vertical"
android:text=""
androin:scrollHorizontally="true"
android:ellipsize="end"
android:enabled="false"/>
<ImageButton
android:id="#+id/added_button"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_margin="8dp"
android:layout_gravity="center_vertical"
android:src="#drawable/minus"/>
</TableRow>
</TableLayout>
The code that populates the EditText and adds the table:
LinearLayout parent = (LinearLayout) findViewById(R.id.parent); // LinearLayout
LayoutInflater li = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View dynamic = li.inflate(R.layout.dynamic, null);
EditText et = (EditText) dynamic.findViewById(R.id.added_text);
et.setText("Some very long text...");
parent.addView(dynamic, 1);
What I want is simple; just to ellipsize the EditText value so that the added view honors the parent width.
Looks like adding the following to the EditText above solved it.
android:layout_weight="1"
Found it here actually:
Android: Stop EditText from going outside of tablerow
Related
I'm using the Html.fromHtml() function to set the text of a TextView in multiple screens. All of them are of the following pattern: Name. I used the Log to see if the strings were correct, and they are.
But there's one common thing on the two cases that aren't working: i'm inflating and copying a row layout.
I'm using a LinearLayout as a row and adding multiple of these inside another linearlayout.
The row layout that is being copied:
<?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="horizontal"
android:weightSum="3">
<TextView
android:id="#+id/bandName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:layout_marginTop="15dp"
android:text="Band"
android:textColor="#color/darkTxtLightBg"
android:textColorLink="#color/darkTxtLightBg"
android:clickable="true"
android:linksClickable="true"
android:textSize="17sp" />
<TextView
android:id="#+id/bandOnTour"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginTop="15dp"
android:gravity="end"
android:text="Band"
android:textColor="#color/darkTxtLightBg"
android:textSize="16sp" />
</LinearLayout>
The LinearLayout where i insert the rows:
<LinearLayout
android:id="#+id/table_bandList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="vertical"
android:layout_marginTop="10dp">
</LinearLayout>
The code where i copy, populate and add these views:
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout tr;
for (Band b : bandsFollowed) {
tr = (LinearLayout) inflater.inflate(R.layout.bandrow_followedlist, null);
TextView t1 = (TextView) tr.findViewById(R.id.bandName);
t1.setText(Html.fromHtml("" + b.name + ""));
t1 = (TextView) tr.findViewById(R.id.bandOnTour);
t1.setText(getResources().getString(R.string.onTour));
t1.setTextColor(getResources().getColor(R.color.bandFollowed));
tl.addView(tr);
}
What i tried:
Set all the parent layouts to android:clickable="true", but it made no difference.
Using the android:onClick attribute with a function, but that won't work as i need to.
Using a TableLayout and TableRows instead of LinearLayouts, but i had the same problem.
So, why does it work when i simply set a text to another TextView that i have, but it doesn't work when i add them dynamically? Could it be something with the inflater, the parent or even the xml file?
I know the link is there because the text is underlined, but nothing happens when i click it.
Try the following code, I have tested. Hope this helps!
TextView textView = (TextView) findViewById(R.id.textView);
textView.setMovementMethod(LinkMovementMethod.getInstance());
final String htmlString="Go to Google";
textView.setText(Html.fromHtml(htmlString));
I got this screen that have some static and some dynamic views to be created.
I want infinity number of views to be created and i think dynamic is the way forward
Now all i need is to create the top column with image buttons , the edittext with clientname and the spinner with cash in the xml (this is the layout i have currently) now i want if a user clicks the cart icon the views with product name, quantity and price to be generated dynamically and then the bottom views are also generated via xml
like this
As you can see there're two row of product,quantity and price. Currently this is done via xml can someboy help out how can i generate and arrange the row with quantity and price and product name in between an existing xml layout like this?
NB: the main layout is relative layout and the layout that contains the row to be generated dynamically is this
<LinearLayout
android:id="#+id/laygroup0"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/lvpaymode"
android:gravity="center"
android:orientation="vertical" >
<AutoCompleteTextView
android:id="#+id/autoproduct0"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:drawableLeft="#drawable/ic_shopping_cart_black_24dp"
android:ems="10"
android:hint="#string/strproductname"
android:padding="10dp"
android:singleLine="true" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal" >
<EditText
android:id="#+id/autoquantity0"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_weight="1"
android:drawableLeft="#drawable/ic_local_mall_black_24dp"
android:ems="10"
android:hint="#string/strquantity"
android:inputType="numberDecimal"
android:padding="10dp"
android:singleLine="true" >
</EditText>
<EditText
android:id="#+id/autoprice0"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_weight="1"
android:drawableLeft="#drawable/ic_attach_money_black_24dp"
android:ems="10"
android:hint="#string/strprice"
android:inputType="numberDecimal"
android:padding="10dp"
android:singleLine="true" >
</EditText>
</LinearLayout>
</LinearLayout>
I can not give complete code bc I'm writing from my phone, but I can give you more pointers.
Create the parent layout in xml in the main layout. It will be much easyer if its a LinearLayout (any other layout it will be much harder to deal with, more care and more code).
Then use findViewById to reference the parent it in java code:
LinearLayout parent = findViewById(R.layout....);
You will use the parent to add in it the child views.
Next set up a button with an onClick event hooked up. In the onClick event you will inflate the child layout: View child = LayoutInflater.from(context).inflate(R.layout.childxml);
Next use TextView tv = child.findViewById(... to find all the views contained in it etc. Set up other button events here if you have buttons.
At last you can add the child to the parent: parent.addView(child);
If the parent its a linear layout with the orientation set to vertical all the views will arrange nicely one below the other.
If you add many views you risk extending more than the phone's screen allows it and it will not be scrollable. You can overcome this by wrapping the parent linear layout with a ScrollView in xml. Now it will work nicely.
Hope it helps.
I have a TextView, defined like this:
<TextView
android:id="#+id/play_info"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#color/play_info_background"
android:ellipsize="none"
android:maxLines="8"
android:orientation="vertical"
android:scrollbars="none"
android:singleLine="false"
android:textColor="#color/play_info_text_color"
android:textSize="#dimen/play_info_font_size"
android:overScrollMode="never" >
</TextView>
I set the TextView to be scrollable in code, like this:
cardInfo = (TextView) play.findViewById(R.id.play_info);
cardInfo.setMovementMethod(new ScrollingMovementMethod());
The TextView scrolls, but not smoothly, like anything inside a ScrollView.
I would like for it to scroll smoothly.
I have already tried putting the TextView (with scrolling disabled) inside a ScrollView, but this messes with the height of the TableRow it's contained in, and there doesn't seem to be a way to correct that.
The problem is if you want "smooth scroll" you have to place the TextView in a ScrollView. And when you do that, you can no longer
set the height of the TextView to "match_parent". Like, for example, when you need a large TextBox that is filled dynamically with text,
but not resized. And when you try by setting the ScrollView's attribute to "match_parent", the child TextView still wraps around the content.
I was able to do it like this:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:drawable/edit_text">
<ScrollView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#null"
android:gravity="bottom"
android:singleLine="false"
android:typeface="serif"/>
</ScrollView>
</RelativeLayout>
A RelativeLayout container that serves as a new TextView, with the desired background, the original TextView with background set to null. So when the TextView
expands, with new text appended, it's just like text volume increasing. The text is aligned with the layout attributes if the ScrollView.
You may also need to disable scrolling for the TextView, to avoid collision with the ScrollView's scrolling in certain scenarios.
You probably missing focus attribute, Textview is not in focus so its not scrolling.
<TextView
android:id="#+id/title_itemcount"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:focusable="true"
android:focusableInTouchMode="true"
android:maxLines="3"
android:padding="4dp"
android:scrollbars="vertical"
android:textColor="#android:color/background_dark" />
Hope it helps... :)
probably the title of my question is not really clear.
I'm developing my first Android Application for a University project. What I need now is to give the possibility of entering one "ingredient" to my users in order to look for recipes in a database. This is easy.
I read probably all the similar posts on this website but I couldn't solve my problem: now I want to give the user the possibility of specifying more than one ingredient so that there should be a "+" button below my first EditText field allowing to add new EditText fields between the first and the button itself.
Together with the EditText field I need a "-" button that, when clicked, "hide" the relative input field.
I hope the description is clear.
What I have now is my main XML layout and the second one, with edittext and "-"button...but I didn't understand how to push/inflate/show this layout in the main one...
Could you please help me?
This isthe layout I want to push:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_below="#+id/ingredient"
android:layout_height ="wrap_content"
android:layout_width="fill_parent"
android:visibility="gone"
android:id="#+id/newLine1">
<EditText
android:id="#+id/ingredient"
android:layout_width="100dp"
android:layout_height="50dp"
android:inputType="text"
android:hint="#string/hint_ingredient" />
<Button
android:id="#+id/remove"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:text="#string/remove"
android:layout_toRightOf="#+id/ingredient"
android:onClick="removeLine"
/>
</RelativeLayout>
This is the main layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/main_linear">
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:scrollbars="horizontal"
android:id="#+id/scrollView"
android:layout_weight="1.0" android:fadingEdge="none">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="300dp" android:layout_height="wrap_content" android:id="#+id/ingredients">
<EditText
android:id="#+id/ingredient"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:hint="#string/hint_ingredient" />
</RelativeLayout>
</ScrollView>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_height ="wrap_content"
android:layout_width="match_parent"
android:id="#+id/buttons">
<Button
android:id="#+id/add"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="#string/add"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/add"
android:text="#string/search"
/>
</RelativeLayout>
</LinearLayout>
What about removing the new lines added by the inflator?
For now I solved like this:
public void removeLine(View v)
{
View line = (View) v.getParent();
line.setVisibility(View.GONE);
}
Is there some other way?
In the onClickListener for your "+" button you'll need to use a LayoutInflater to inflate your ingredient layout into a View. Then use findViewById() to get a reference to your ingredients RelativeLayout and add the new View to it.
Make sure that you specify LayoutParams for the new view that is inflated.
You may want to change ingredients to a LinearLayout. It is easier to add views to it than a RelativeLayout because you can just add views to a LinearLayout without having to worry about their relative position.
Good luck.
in the onClickListener to your '+' button write something like this :
int et_counter=1;
LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
EditText et = new EditText(RecipeActivity.this);
//assign them an ID with an int counter
//use this counter later to refer to the EditText
//to retrieve the values
et.setId(et_counter);
ll.addView(et);
you could retrieve values like this :
for (n = 1; n <= et_counter; n++){
et = (EditText) findViewById(n);
String ingridient=et.getText().toString();
//use the text somewhere
}
Similarly you can assign an onClick listener to your '-' button, refer to the EditText with the ID using et_counter and remove it using et.setVisibility(View.GONE);
You should be able to use this with your logic. Good Luck :-)
I'm trying to create a layout containing, among other things, a LinearLayout. The XML for the whole screen is:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="#+id/fileSelView"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Spinner android:id="#+id/dirListSpinner"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"/>
<Spinner android:id="#+id/fileTypeSpinner"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"/>
<EditText android:id="#+id/fileNameTF"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_toRightOf="#+id/fileTypeSpinner"/>
<LinearLayout android:id="#+id/centerBox"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_below="#+id/dirListSpinner"
android:layout_above="#+id/fileTypeSpinner"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true">
<ListView android:id="#+id/dirView" android:background="#f00"
android:layout_width="fill_parent" android:layout_height="fill_parent"
android:layout_weight="1"/>
<RelativeLayout android:id="#+id/buttonBox" android:background="#0f0"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_weight="0">
<Button android:id="#+id/upButton"
android:text="Up"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"/>
<Button android:id="#+id/mkdirButton"
android:text="MkDir"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_below="#+id/upButton"
android:layout_centerHorizontal="true"/>
<Button android:id="#+id/okButton"
android:text="OK"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_below="#+id/mkdirButton"
android:layout_centerHorizontal="true"/>
<Button android:id="#+id/cancelButton"
android:text="Cancel"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_below="#+id/okButton"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
The result of this layout looks like this:
The LinearLayout itself is laid out the way I want, within its parent, but its contents come out all wrong. It has two children: a ListView on the left and a RelativeLayout on the right. The ListView should take up all the available height, and as much width as possible, while the RelativeLayout should be a small as possible and vertically centered within its parent. Instead, the ListView ends up being way too narrow, and the RelativeLayout grows to fill the space, despite the ListView having android:layout_weight="1" and the RelativeLayout having android:layout_weight="0". Also, the RelativeLayout is aligned with the top of its parent, despite having android:gravity="center_vertical".
What am I doing wrong?
UPDATE
OK, I changed android:gravity="center_vertical" to android:layout_gravity="center" on the RelativeLayout, and now it is vertically centered within its parent, as desired.
Regarding the layout weight issue, I tried changing android:layout_width="fill_parent" to android:layout_width="0px" on the ListView, but that didn't work; I'm getting the same result as before, with the ListView way too narrow and the RelativeLayout expanding to take up the available space.
The layout now looks like this: http://thomasokken.com/layout-problem2.png
Note that the buttons in the RelativeLayout are not correctly centered horizontally. It's as if the RelativeLayout got sized and laid out correctly at first, and then grew towards the left later, without re-laying out its children.
I haven't been able to get the ListView to get sized properly using a RelativeLayout parent, either. Could it be resizing itself in response to a setAdapter() call? I'm using a custom ListAdapter class whose getView() method returns RelativeLayout objects:
public View getView(int position, View convertView, ViewGroup parent) {
File item = items[position];
if (convertView == null) {
Context context = parent.getContext();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.file_selection_dialog_row, null);
ImageView icon = (ImageView) convertView.findViewById(R.id.fdrowimage);
icon.setImageResource(item.isDirectory() ? R.drawable.folder : R.drawable.document);
}
TextView text = (TextView) convertView.findViewById(R.id.fdrowtext);
text.setText(item.getName());
return convertView;
}
The layout for the list rows looks like this:
<?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">
<ImageView android:id="#+id/fdrowimage"
android:layout_height="35dp" android:layout_width="wrap_content"
android:layout_alignParentLeft="true"
android:paddingRight="5dp" android:paddingLeft="3dp"/>
<TextView android:id="#+id/fdrowtext"
android:layout_width="wrap_content" android:layout_height="35dp"
android:layout_toRightOf="#+id/fdrowimage"
android:layout_alignTop="#+id/fdrowimage"
android:layout_alignBottom="#+id/fdrowimage"
android:gravity="center_vertical"
android:textSize="23dp"/>
</RelativeLayout>
There are a few things going on here.
First as to the vertical centering of the RelativeLayout. android:gravity="center_vertical" indicates that the children of this view should have center_vertical applied. And it is actually working. As you can see by the size of the green background, your RelativeLayout is only as big as it needs to be to fit the buttons. You have two solutions. If you want the height of the view to stay the same and be centered inside its parent, you would use android:layout_gravity="center". If you want the RelativeLayout to fill the column then you need to set the layout_height of the RelativeLayout to be "fill_parent". android:layout_gravity applies to the view itself inside its parent. android:gravity applies to the view's children.
Second is the layout weight issue. The LinearLayout will first layout any wrap_content items (ie, your RelativeLayout), then it will apply children that have a layout_weight AND a size of 0. If you want your layout_weight to work properly, you need to set the layout_width of the ListView to "0px".