I'm trying to programatically add two views as children of a root RelativeLayout, when one view is below another.
Here's the root view (which also resides in another CoordinatorLayout, but I don't think it's related):
<RelativeLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
Now, here is one of the two layouts I'm trying to add programatically:
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
and the other one:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/icon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentLeft="true"
android:background="#drawable/ic_group_members"/>
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/icon"
android:layout_centerVertical="true"
android:layout_marginLeft="15dp"
android:layout_toRightOf="#+id/icon"
android:textSize="18sp"
android:textStyle="bold"
android:text="#string/members_title"/>
</RelativeLayout>
I added this with this code:
RelativeLayout container = (RelativeLayout)findViewById(R.id.container);
container.addView(topView);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.BELOW, bottomView.getId());
bottomView.setLayoutParams(lp);
container.addView(bottomView);
The result is: the bottom view is not visible.
What I tried:
Changing the first RecyclerView's height to WRAP_CONTENT (thought it might fill all space and hide the bottom layout), which had no effect.
Instead of setting the LayoutParams to the bottom view, to:
container.addView(bottomView, lp);
But it didn't work either.
Using a LinearLayout instead of the RelativeLayout container, same behaviour either.
I have no more ideas what can cause this problem, and by looking at similar questions, nothing worked. Any ideas what am I doing wrong?
Your first view is RecyclerView, which is a scrollable view. It doesn't matter if you set the height wrap_content to RecyclerView/ListView. In all cases, it's going to fill the whole screen unless you set a specific height to the RecyclerView, obviously smaller than the device's height. The second view below RecyclerView would show up then. Here's what you can try:
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, HEIGHT_OF_VIEW);
recyclerView.setLayoutParams(params);
The LinearLayout approach should work.
Just mind that:
1) Container LinearLayout should have layout_height MATCH_PARENT
2) RecyclerView should have layout_height of 0 and layout_weight of 1
If instead you want to keep the RelativeLayout approach try:
1) BottomLayout with rule RelativeLayout.ALIGN_PARENT_BOTTOM
2) RecyclerView with rule RelativeLayout.ABOVE
Example 2nd approach:
RelativeLayout containerLayout = (RelativeLayout) findViewById(R.id.container);
RelativeLayout bottomLayout = new RelativeLayout(this);
bottomLayout.setId(R.id.bottom_id);
RelativeLayout.LayoutParams bottomLayoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
bottomLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
bottomLayout.setLayoutParams(bottomLayoutParams);
bottomLayout.setBackgroundColor(Color.RED);
TextView bottomTextView = new TextView(this);
bottomTextView.setText("Bottom Layout");
bottomLayout.addView(bottomTextView);
containerLayout.addView(bottomLayout);
RecyclerView recyclerView = new RecyclerView(this);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ABOVE, R.id.bottom_id);
recyclerView.setLayoutParams(params);
recyclerView.setBackgroundColor(Color.BLUE);
containerLayout.addView(recyclerView);
Related
I have a use-case when I need to change a linearlayout's gravity to center in parent programatically. For some reason it crashes :
Non-fatal Exception: java.lang.ClassCastException
android.widget.LinearLayout$LayoutParams cannot be cast to android.widget.RelativeLayout$LayoutParams
I have the following xml :
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
android:clickable="true"
android:orientation="vertical">
<ImageView
android:id="#+id/imageView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="#drawable/bg02" />
<LinearLayout
android:id="#+id/myLinearLayout"
android:layout_width="300dp"
android:layout_marginTop="30dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:orientation="vertical">
...
...
</LinearLayout>
</RelativeLayout>
code :
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
params.weight = 1.0f;
params.gravity = Gravity.CENTER;
myLinearLayout.setLayoutParams(params);
I also tried changing the LinearLayout.LayoutParams to RelativeLayout.LayoutParams since I thought it should be relative to the parent itself (which is RelativeLayout in this case) but that didn't change much..
LinearLayout is inside RelativeLayout, so must be RelativeLayout.LayoutParams instead of LinearLayout.LayoutParams
You need to add RelativeLayout Param instead of LinearLayout param and in RelativeLayout param you need to add Rules like this:
RelativeLayout.LayoutParams params =
new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
//params.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
//params.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
The Linearlayout is a child of a RelayiveLayout as pointed out by the previous responder. If you want to center the linear layout in the relativelayout, you can add rule as follows.
RelativeLayout.LayoutParams params = myLinearLayout.getLayoutParams();
params.addRule(RelativeLayout.CENTER_IN_PARENT);
myLinearLayout.setLayoutParams(params);
Assuming that you want the linearlayout to be centered. If not, you can find the rule that suits your purpose.
I am risking writing a duplicate question, but as I was researching the answer to another SO question, I realized that I couldn't find a simple question and answer that included setting both gravity and layout_gravity of a LinearLayout. Also, I was confused as to the difference between them when talking about a ViewGroup rather than just a view. I am answering my question below.
Here are some of the other questions I viewed:
How to set gravity to layout programmatically?
Set gravity for LinearLayout programmatically
android - setting LayoutParams programmatically
LayoutParams gravity not working
layout_gravity in LinearLayout
Problem with setLayoutParams method in android UI
how to set setLayoutParams for linear layout elements
Is it possible to change the layout width and height in Android at run time?
Short answer
Set gravity
linearLayout.setGravity(Gravity.CENTER);
Set layout gravity
// the LinearLayout's parent is a FrameLayout
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(400, 400);
params.gravity = Gravity.TOP|Gravity.RIGHT;
linearLayout.setLayoutParams(params);
Background
Previously, I have explained the difference between 'gravity' and `layout_gravity' for views within a layout.
Setting the gravity of a LinearLayout itself changes the location of the views within it. Setting the layout_gravity of a LinearLayout changes how the LinearLayout is arranged within its parent layout.
This image shows a LinearLayout (brown) within a FrameLayout (white). The LinearLayout's gravity is set to center_horizontal and its layout_gravity is set to right|bottom.
Here is the xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="#+id/llExample"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="right|bottom"
android:background="#e3e2ad"
android:gravity="center_horizontal"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="100dp"
android:layout_height="50dp"
android:background="#bcf5b1"
android:text="TextView 1" />
<TextView
android:id="#+id/textView1"
android:layout_width="100dp"
android:layout_height="50dp"
android:background="#aacaff"
android:text="TextView 2" />
</LinearLayout>
</FrameLayout>
Changing things programmatically
The following code shows how to change both the gravity and the layout_gravity of the LinearLayout.
public class LinearLayoutGravity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.linear_layout_gravity);
// Change the gravity (not layout_gravity) of the LinearLayout
LinearLayout ll = (LinearLayout) findViewById(R.id.llExample);
ll.setGravity(Gravity.CENTER);
// Change the layout_gravity (not gravity) of the LinearLayout
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(400, 400);
params.gravity = Gravity.TOP|Gravity.RIGHT;
ll.setLayoutParams(params);
}
}
And here is the result:
See also
RelativeLayout and LinearLayout with gravity: What is the effect?
If you are using KOTLIN use or operator like this:
GRAVITY = Gravity.RIGHT or Gravity.CENTER_VERTICAL
frameContainer.layoutParams = FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT,
GRAVITY)
How can I use Java code to change the layout_weight of my View object from XML? I've included the last thing I tried below. vynosy is my attribute with value that I want to set.
View hospVyslLineAppColor = (View) view.findViewById
(R.id.hospodarsky_vysledok_line_appcolor);
hospVyslLineAppcolor.setLayoutParams(new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT,
Math.abs((float)vynosy)));
My XML:
<View
android:id="#+id/hospodarsky_vysledok_line_appcolor"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_weight="69382"
android:background="#a8a8a8" />
You can use this for linearlayout
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT;
params.weight = 1;
I think that this will help you... Set Width Programatically on SO
but i think that is not possible to change this property programmatically but is only possible to set a new Layout(View in generally) within the new property.
You need to understand how the Layout_weights work. These are effective only if you have more than one views. Your code is correct, just you need to add one more view. Both declared in a linear layout. The layout in which you need to have the weights applied.
View hospVyslLineAppColor = (View) view.findViewById (R.id.hospodarsky_vysledok_line_appcolor);
hospVyslLineAppcolor.setLayoutParams(new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT,
Math.abs((float)vynosy))); // see to it the value of vynosy is less than 1
View hospVyslLineAppColor1 = (View) view.findViewById (R.id.hospodarsky_vysledok_line_appcolor);
hospVyslLineAppColor1.setLayoutParams(new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT,
(1 - Math.abs((float)vynosy)))); // Will complement the weight
And re-wite your XML file:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- layout_height is 0dp as height is to be set by weight factor -->
<View
android:id="#+id/hospodarsky_vysledok_line_appcolor"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.4"
android:background="#a8a8a8" />
<!-- layout_height is 0dp as height is to be set by weight factor -->
<View
android:id="#+id/hospodarsky_vysledok_line_appcolor1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.6"
android:background="#a8a8a8" />
</LinearLayout>
I've been searching around in Google for a bit but I can't seem to find what I want to do. I want to be able to programatically add an icon as an overlay in an activity at a specified position without using any xml.
An example of what I mean: http://cdn9.staztic.com/app/a/2326/2326236/pollfish-demo-2-1-s-307x512.jpg
Any ideas?
It depends at layout you are using. If you are using RelativeLayout, you can do it this way:
<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:id="#+id/main" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:src="#android:drawable/ic_"/>
</RelativeLayout>
Which is equal with this Java code (except root RelativeLayout):
RelativeLayout layout = (RelativeLayout) findViewById(R.id.main);
ImageView child = new ImageView(this);
child.setImageDrawable(getResources().getDrawable(R.drawable.ic_launcher));
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
child.setLayoutParams(params);
layout.addView(child);
I am trying to add a text view to an imageview inside a horizontal scrollview programatically. However, this does not seem to work.
Sample Image on in RelativeLayout without scrolling:
Here is a sample image in horizontal scrolling:
Here is my xml layout:
<HorizontalScrollView android:id="#+id/home_horizontal_scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/middle_menu_title" >
<LinearLayout android:id="#+id/home_linear_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</LinearLayout>
</HorizontalScrollView>
Inside my test code:
LinearLayout layout = (LinearLayout)findViewById(R.id.home_linear_layout);
for(int i = 0 ; i < 10; i++){
ImageView myView = new ImageView(this);
myView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
myView.setAdjustViewBounds(true);
myView.setScaleType(ScaleType.FIT_XY);
myView.setPadding(0, 2, 2, 0);
myView.setImageResource(R.drawable.render);
layout.addView(myView);
TextView text = new TextView(this);
text.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, 50));
text.setBackgroundColor(Color.parseColor("#4000"));
text.setTextColor(Color.WHITE);
text.setGravity(Gravity.CENTER);
text.setText("Header Title");
layout.addView(text);
I have also tried using Relative Layout inside the horizontal scrollview without any success.
Inside a simple relative layout like below , I am able to display the title and image but not when it is in the horizontal scrollview
<RelativeLayout android:id="#+id/top_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/menu_title"
android:background="#drawable/background_gradient">
<ImageView
android:id="#+id/imageView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="2dip"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:adjustViewBounds="true"
android:scaleType="fitXY"
android:src="#drawable/render" />
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:background="#4000"
android:gravity="center"
android:text="Image Title"
android:textColor="#FFFFFF" />
</RelativeLayout>
Any advise?
There is a problem in your layout :
you say to the LinearLayout parent view to take a width according to its children :
using android:layout_width="wrap_content"
then you say the children to take a width according to the parent :
using LayoutParams.MATCH_PARENT
you have to understand that it can't give a predictible result since they both depend to each other.
I think if you set the width to LayoutParams.WRAP_CONTENT on the children it will solve the issue :
ImageView myView = new ImageView(this);
myView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));
myView.setAdjustViewBounds(true);
myView.setScaleType(ScaleType.FIT_XY);
myView.setPadding(0, 2, 2, 0);
myView.setImageResource(R.drawable.render);
layout.addView(myView);
TextView text = new TextView(this);
text.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, 50));
text.setBackgroundColor(Color.parseColor("#4000"));
text.setTextColor(Color.WHITE);
text.setGravity(Gravity.CENTER);
text.setText("Header Title");
layout.addView(text);
EDIT : seen the edit from the question, LinearLayout can't be the good answer because it doesn't allow children overlapping.
You can easily add an image to a TextView without putting it in a new parent layout by using the compoud drawables :
myTextView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.left, 0, 0, 0);
Put 0 to remove drawable,
You can put a drawable on any side (left, top, right, bottom)
see the documentation here, it may help you.
the size of the drawable has to match your needs since it use (as it says) the drawable intrinsic bounds.
if you don't have any other view in your LinearLayout than a image and a text, it's advised to use compound drawables for optimizations.
EDIT : seen the edit in the question : the compound drawable can't be the answer if you need to overlap your image and your text.