I want to align a TextView above an EditText. The following code is working well when the TextView is not higher than the space between the Top Margin of the window (red line) and the EditText (green line), like in the screenshot.
The problem occurs when the TextView has more lines than in the screenshot: it just "overruns" the EditText, but I want to keep the EditText in foreground.
In other words: I would like to place the TextView's bottom margin onto the green line and let it grow towards the red line, in order to maintain the visibility of the EditText.
// LINEAR LAYOUT
LinearLayout layout = new LinearLayout(getApplicationContext());
layout.setOrientation(LinearLayout.VERTICAL);
setContentView(layout);
// TEXTVIEW
// how to set bottom margins programmatically?
layout.addView(tv);
// EDITTEXT
// place the EditText to the bottom of the layout, working well
et.setGravity(Gravity.BOTTOM);
et.setInputType(InputType.TYPE_CLASS_TEXT);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
params.gravity = Gravity.BOTTOM;
et.setLayoutParams(params);
layout.addView(et);
This should do it for you:
// LINEAR LAYOUT
LinearLayout layout = new LinearLayout(getApplicationContext());
layout.setOrientation(LinearLayout.VERTICAL);
setContentView(layout);
// TEXTVIEW
LinearLayout.LayoutParams paramstv = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT,1f);
tv.setLayoutParams(paramstv);
layout.addView(tv);
// EDITTEXT
et.setGravity(Gravity.BOTTOM);
et.setInputType(InputType.TYPE_CLASS_TEXT);
LinearLayout.LayoutParams etparams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT,8f);
etparams.gravity = Gravity.BOTTOM;
et.setLayoutParams(etparams);
layout.addView(et);
I guess the key is really to wrap both the EditText and TextView into LayoutParams. Probably you have to adjust the weights.
If this one doesn't work, try to create your layout with an XML file (the handling there is easier).
Try using the relative layout instead and set the edittext at the parent's bottom..
In case you don't want to switch to relative layout then try declaring edit text before the text view..
You can set the property of EditText type to textMultiline.
As you're using LinearLayout , set weight for your views
LinearLayout.LayoutParams paramTextView = new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT, 1.0f);
tv.setlayoutParams(paramTextView);
LinearLayout.LayoutParams paramEditText = new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT, 3.0f);
et.setlayoutParams(paramEditText);
This shall give you the result you expect
This below xml code can solve your problem...
<RelativeLayout
android:layout_height="match_parent"
android:layout_width="match_parent">
<SrollView
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_above="#+id/edittext_id"
android:layout_margin="7dp">
<TextView
android:id="#+id/text_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</SrollView>
<EditText
android:id="#+id/edittext_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
Related
I want to add a ViewStub to my layout. This is how the ViewStub should look like, as xml:
<ViewStub
android:id="#+id/viewstub_id"
android:layout="#layout/use_this_layout"
android:inflatedId="#+id/inflated_stub"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
I have come up with this code, but the layout is not showing.
I'm reusing the id, because I'm deleting and adding the stub again. I guess the code not working has something to do with the constraints or the layout width/height, but I'm not sure. What am I doing wrong?
ViewStub vs = new ViewStub(this);
vs.setId(R.id.viewstub_id);
vs.setLayoutResource(R.layout.use_this_layout);
vs.setInflatedId(R.id.inflated_stub);
ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(0, 0);
vs.setLayoutParams(layoutParams);
ConstraintLayout cl = findViewById(R.id.viewStubWrapper);
ConstraintSet cs = new ConstraintSet();
cs.clone(cl);
cs.connect(ConstraintSet.PARENT_ID, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM);
cs.applyTo(cl);
cl.addView(vs); // the ConstraintLayout is the ViewStub's parent
vs.inflate();
I found something that seems to work:
ViewStub vs = new ViewStub(this);
vs.setId(R.id.viewstub_id);
vs.setLayoutResource(R.layout.use_this_layout);
vs.setInflatedId(R.id.inflated_stub);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
vs.setLayoutParams(lp);
ConstraintLayout cl = findViewById(R.id.viewStubWrapper);
cl.addView(vs);
vs.inflate();
Seems like I didn't need the constraints after all, I just needed to use LayoutParams.MATCH_PARENT for width and height instead of 0.
I'm trying to add a bunch of ImageView on my UI using a loop, the problem is that I have no Idea if the ImageView is being added or not because when I run the app it just gives me a blank white screen.
for(int i = 0; i < jsonArray.length(); i++) {
Log.d("test", "ok"); //the loop works btw
poster.setId(i);
JSONObject jsonObject = jsonArray.getJSONObject(i);
ImageView poster = new ImageView(getApplicationContext());
poster.setBackgroundResource(R.drawable.myPoster);
RelativeLayout.LayoutParams posterParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT
);
posterParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
posterParams.addRule(RelativeLayout.CENTER_VERTICAL);
posterParams.width = 160; //is this DP?
posterParams.height = 220;
relativeLayout.addView(poster, posterParams);
}
Any suggestion is welcome.
EDIT
I added another piece of code just to test if a widget will be added without using a loop:
//test
LinearLayout layout = new LinearLayout(this);
Button btn = new Button(this);
btn.setText("this is a button");
btn.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
layout.addView(btn);
And I still get the same result, just blank.
First of all, you are giving exactly the same parameter to each ImageView this causes all your ImageView lays on Like STACK only the last one will be visible to you. You may use ScrollView to see if the ImageViews actually added to your root layout
Secondly, set layout parameters to your dynamic ImageViews not your root layout.
Update
How to use ScrollView,
First of all, your XML should contain ScollView and a child (LinearLayout in our case but you can choose any layout depending on your use case) for placing your ImageView
<ScrollView>
<LinearLayout
android:id = "imageViewPlaceHolder">
</LinearLayout>
</ScrollView>
Secondly, in your Java code, you should find an inner layout to add views as follows
LinearLayout placeHolder = findViewById(R.id.imageViewPlaceHolder);
Then you are ready to add ImageViews into placeHolder since your placeHolder wrapped with ScrollView it will create a scroll dynamically if the content height goes beyond the dedicated height.
placeHolder.addView(yourImageView);
Adding everything from Java
HorizontalScrollView hsv = new HorizontalScrollView(context);
hsv.setLayoutParams(yourLayoutParams);
LinearLayout myPlaceHolder = new LinearLayout(context);
myPlaceHolder.setLayoutParams(yourLayoutParamsForLinearLayout);
myPlaceHolder.addView(yourDesiredImageView);
hsv.addView(myPlaceHolder);
yourRootLayout.addView(hsv);
Hope it makes sense, feel free to ask any clarification
try this:
listView = (ListView) findViewById(R.id.lv_info);
ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, text);
listView.addHeaderView(creatHeader(getString(R.string.abuot_email),getResources().getString(R.string.email_info)));
listView.addHeaderView(creatHeader(getString(R.string.about_phone),getResources().getString(R.string.admin_phone_num)));
listView.addHeaderView(creatHeader(getString(R.string.about_copyright), getResources().getString(R.string.copyright_info)));
listView.addHeaderView(creatHeader(getString(R.string.about_version),getResources().getString(R.string.version_info)));
listView.setAdapter(adapter);
Method creatHeader:
public View creatHeader(String title, String text) {
View v = getLayoutInflater().inflate(R.layout.lv_item_header_info, null);
((TextView) v.findViewById(R.id.tvTitle)).setText(title);
((TextView) v.findViewById(R.id.tvText)).setText(text);
return v;
}
Layout file for items:
<?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"
android:padding="#dimen/activity_vertical_margin">
<TextView
android:id="#+id/tvTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="ssss"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"/>
<TextView
android:id="#+id/tvText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="sssssssss"
android:gravity="center_vertical"/>
</LinearLayout>
I have a hierarchy that is like this:
LinearLayout(horizontal)
ImageView
LinearLayout(vertical)
TextView
TextView
TextView
TextView
I want to be able to add the hierarchy above through iteration as long as there is data that could be obtained from the database(using Parse)
I have tried putting up the ImageView and LinearLayout under the parent LinearLayout but it doesn't seem to work. Here is my code in MainActivity.Java:
LinearLayout LL_Outer = (LinearLayout) findViewById(R.id.new_linearLayoutOuter);
LL_Outer.setOrientation(LinearLayout.VERTICAL); // set orientation
LL_Outer.setBackgroundColor(color.white); // set background
// set Layout_Width and Layout_Height
LinearLayout.LayoutParams layoutForOuter = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
LL_Outer.setLayoutParams(layoutForOuter);
LinearLayout LL_Inner = (LinearLayout) findViewById(R.id.new_linearLayoutInner);
LL_Inner.setOrientation(LinearLayout.HORIZONTAL);
LL_Inner.setBackgroundColor(color.white);
LinearLayout.LayoutParams layoutForInner = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
LL_Inner.setLayoutParams(layoutForInner);
//LL_Outer.addView(LL_Inner);
ImageView IV = (ImageView) findViewById(R.id.new_imageViewPP);
//IV.getLayoutParams().height = 55;
//IV.getLayoutParams().width = 55;
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
params.setMargins(14, 12, 0, 0);
params.height = 55;
params.weight = 55;
IV.setBackgroundColor(color.black);
IV.setLayoutParams(params);
LL_Inner.addView(IV);
LL_Outer.addView(LL_Inner);
I don't know where I went wrong as my code did not prompt any error. Please help.
EDIT: I have edited the Orientations accordingly and when I run the app, it stops working. And prompts an error in LogCat saying "The specified child already has a parent. You must call removeView() on the child's parent first.
Here's my XML:
<LinearLayout
android:id="#+id/new_linearLayoutOuter"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#color/white"
android:orientation="horizontal" >
<ImageView
android:id="#+id/new_imageViewPP"
android:layout_width="55dp"
android:layout_height="55dp"
android:layout_marginLeft="14dp"
android:layout_marginTop="12dp"
android:background="#color/black"
android:contentDescription="#string/pp" />
<LinearLayout
android:id="#+id/new_linearLayoutInner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#color/white"
android:orientation="vertical" >
<TextView
android:id="#+id/new_textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/movie_title"
android:paddingTop="10dp"
android:paddingLeft="7dp"
android:textSize="15sp" /> <!-- Title of the movie -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/review_by"
android:paddingTop="3dp"
android:paddingLeft="7dp"
android:textSize="12sp" /> <!-- By -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/movie_stars"
android:paddingTop="3dp"
android:paddingLeft="7dp"
android:textSize="12sp" /> <!-- Rating and date -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/sample_string"
android:maxLines="5"
android:scrollbars="vertical"
android:paddingTop="10dp"
android:paddingLeft="7dp"
android:textSize="12sp"
android:layout_gravity="center_vertical|right" /> <!-- Review content -->
</LinearLayout>
</LinearLayout>
You want that hierarchy programmatically.
- LinearLayout(horizontal)
- ImageView
- LinearLayout(vertical)
- TextView
- TextView
- TextView
- TextView
Ok lets start with Parent LinearLayout
LinearLayout parent = new LinearLayout(context);
parent.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
parent.setOrientation(LinearLayout.HORIZONTAL);
//children of parent linearlayout
ImageView iv = new ImageView(context);
LinearLayout layout2 = new LinearLayout(context);
layout2.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
layout2.setOrientation(LinearLayout.VERTICAL);
parent.addView(iv);
parent.addView(layout2);
//children of layout2 LinearLayout
TextView tv1 = new TextView(context);
TextView tv2 = new TextView(context);
TextView tv3 = new TextView(context);
TextView tv4 = new TextView(context);
layout2.addView(tv1);
layout2.addView(tv2);
layout2.addView(tv3);
layout2.addView(tv4);
And you are done :)
The problem is because the views are already added to the layout in the XML file. Then you findViewById (find them) and try to add them to the layout again. That is why the app crashes complaining that, view already has a parent and you can't add it again.
In the XML File LinearLayout already has child view. So there is not need to add them in code.
i suggest you to remove the xml file and just use full code on the java side. you can add the views programatically from the java side. this one from xtreemdeveloper but i change few line for the parent layout.
// remove this params set it up below
parent.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
// change the code above into
.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
addContentView(parent,layoutParams);
// end of my change
it will look like this in full code =
LinearLayout parent = new LinearLayout(context);
// remove this params set it up below
parent.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
// change the code above into
.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);
addContentView(parent,layoutParams);
// end of my change
parent.setOrientation(LinearLayout.HORIZONTAL);
//children of parent linearlayout
ImageView iv = new ImageView(context);
LinearLayout layout2 = new LinearLayout(context);
layout2.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
layout2.setOrientation(LinearLayout.VERTICAL);
parent.addView(iv);
parent.addView(layout2);
//children of layout2 LinearLayout
TextView tv1 = new TextView(context);
TextView tv2 = new TextView(context);
TextView tv3 = new TextView(context);
TextView tv4 = new TextView(context);
layout2.addView(tv1);
layout2.addView(tv2);
layout2.addView(tv3);
layout2.addView(tv4);
Let's say I have two buttons in a RelativeLayout. A button labeled "one" at the top and a button labeled "three" underneath "one". The layout is defined like this.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:id="#+id/mainContainer"
tools:context=".MainActivity" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tvOne"
android:layout_centerHorizontal="true"
android:layout_alignParentTop="true"
android:text="One" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tvThree"
android:layout_centerHorizontal="true"
android:layout_below="#id/tvOne"
android:text="Three" />
</RelativeLayout>
So I wrote some code in the onCreate of MainActivity to dynamically create a Button, and insert it in between one and three. But it isn't working. Is there something I'm missing? I created this question as a simplified version of a bigger problem I'm having, so it's not acceptable for me to clear the layout and just insert one two and three dynamically.
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button one = (Button)findViewById(R.id.tvOne);
Button three = (Button)findViewById(R.id.tvThree);
//Dynamically create a button, set it underneath one and above two.
Button two = new Button(this);
two.setText("TWO TWO TWO TWO TWO TWO TWO");
//Create some layout params so that this button is horizontally centered,
//above button number three and below button number one
final int WC = RelativeLayout.LayoutParams.WRAP_CONTENT;
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(WC, WC);
params.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
params.addRule(RelativeLayout.BELOW, one.getId());
params.addRule(RelativeLayout.ABOVE, three.getId());
two.setLayoutParams(params);
//Add button number two to the activity.
RelativeLayout rl = (RelativeLayout)findViewById(R.id.mainContainer);
rl.addView(two);
}
Working code and I have checked this.
public class Main extends Activity {
Context ctx;
RelativeLayout rlayMainContainer;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ctx = this;
rlayMainContainer = (RelativeLayout) findViewById(R.id.mainContainer);
Button one = (Button) findViewById(R.id.tvOne);
Button three = (Button) findViewById(R.id.tvThree);
// adding button two dynamically
Button two = new Button(ctx);
two.setText("hello");
two.setId(12);
RelativeLayout.LayoutParams lpSecond = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lpSecond.addRule(RelativeLayout.CENTER_HORIZONTAL);
lpSecond.addRule(RelativeLayout.BELOW, one.getId());
rlayMainContainer.addView(two, lpSecond);
//align button three below button two
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) three
.getLayoutParams();
params.addRule(RelativeLayout.BELOW, two.getId());
three.setLayoutParams(params);
}
}
In fact, the "two" button is there, but you can not see it because its height = 0.
These lines of code make the "two" button's height = 0
params.addRule(RelativeLayout.BELOW, one.getId());
params.addRule(RelativeLayout.ABOVE, three.getId());
Yes, the "two" button layoutParams indicates that it must be between "one" and "three", but there is no space left between those buttons --> no height.
To solve this, you need to remove the line that set "two" is above "three" and add code to indicate that "three" is now below "two"
final int WC = RelativeLayout.LayoutParams.WRAP_CONTENT;
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
WC, WC);
params.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
params.addRule(RelativeLayout.BELOW, one.getId());
two.setLayoutParams(params);
// Add button number two to the activity.
RelativeLayout rl = (RelativeLayout) findViewById(R.id.mainContainer);
rl.addView(two);
two.setId(1);
params = (LayoutParams) three.getLayoutParams();
params.addRule(RelativeLayout.BELOW, two.getId());
three.setLayoutParams(params);
I am creating my controls programmatically, based on JSON received from a server. One of the controls I need to create is a WebView that is horizontally centred on the screen. This is simple in xml layouts as shown below using the layout_gravity option. But how do you do this in code, the WebView unlike TextView does not have a setGravity(Gravity.HORIZONTAL_GRAVITY_MASK) method.
<?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" >
<WebView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
</LinearLayout>
I would use a RelativeLayout, then you can use LayoutParams when adding the view:
RelativeLayout.LayoutParams layoutParams= new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, 1);
relativeLayout.addView(yourWebView, layoutParams);
i use LinearLayout to show webview and setGravity.
LinearLayout linearLayout = new LinearLayout(this);
linearLayout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
linearLayout.setGravity(Gravity.CENTER);
WebView view = new WebView(this);
linearLayout.addView(view);
setContentView(linearLayout);
it help you.