I'm trying to position items inside my RelativeLayout so that the image appears first, the title to the right of it, and the content below the image area. Those three content items appear on top of each other. I understand that my LayoutParams probably aren't being set, but I'm not sure why or how to fix it. Any help? Thanks.
RelativeLayout rl = (RelativeLayout)findViewById(R.id.contentTable);
for(int i=0;i<itemIndexes.size();i++)
{
RelativeLayout item = new RelativeLayout(this);
item.setId(i);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(320, RelativeLayout.LayoutParams.WRAP_CONTENT);
if(i>0)
{
lp.addRule(RelativeLayout.RIGHT_OF,i-1);
}
item.setLayoutParams(lp);
ImageView iv = new ImageView(this);
if(globals.myHitetItems.get(itemIndexes.get(i)).image!=-1)
{
iv.setImageResource(globals.myHitetItems.get(itemIndexes.get(i)).image);
item.addView(iv);
}
else
{
iv.setImageResource(R.drawable.noimage);
item.addView(iv);
}
RelativeLayout.LayoutParams text1lp =new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
text1lp.addRule(RelativeLayout.RIGHT_OF,iv.getId());
TextView tv = new TextView(this);
tv.setText(globals.myHitetItems.get(itemIndexes.get(i)).name);
tv.setTextSize(20);
tv.setPadding(3, 3, 3, 3);
tv.setLayoutParams(text1lp);
item.addView(tv);
RelativeLayout.LayoutParams text2lp=new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
text2lp.addRule(RelativeLayout.BELOW,iv.getId());
tv = new TextView(this);
tv.setText(globals.myHitetItems.get(itemIndexes.get(i)).content);
tv.setTextSize(20);
tv.setPadding(3, 3, 3, 3);
tv.setLayoutParams(lp);
item.addView(tv);
rl.addView(item);
}
That looks painful to debug. It sounds like maybe the relative rules aren't being set or accepted. I suggest simplifying to a static test set to verify that one row of views can be set relative to each other (and ensure that one of them is anchored to the layout itself).
Related
I am adding some View to the LinearLayout dynamically:
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
params.setMargins(100, 100, 100, 100);
view.setLayoutParams(params);
parent.addView(view);
However, the margins are not getting applied. The following:
view.invalidate();
view.requestLayout();
parent.invalidate();
parent.requestLayout();
didn't work. However, if I force the activity to recreate (e.g. turn off and on my mobile phone), the margins get applied. Calling activity.recreate() also works, but it's too slow.
How to force layout to recalculate margins? Probably, there's something wrong in the flow? I tried to add my views to the root after creation, add children before and after applying properties, but this didn't work for me.
UPD:
I tried to repeat the bug programmatically and got it with this code:
LinearLayout base = new LinearLayout(context);
LayoutParams params1 = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
base.setLayoutParams(params1);
base.setBackgroundColor(Color.CYAN);
root.addView(base);
LinearLayout another1 = new LinearLayout(context);
LayoutParams params2 = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
another1.setLayoutParams(params2);
another1.setOrientation(LinearLayout.VERTICAL);
another1.setBackgroundColor(Color.BLUE);
base.addView(another1);
TextView tv1 = new TextView(context);
tv1.setText("SOME TEST TEXT 1");
tv1.setTextColor(Color.BLACK);
LayoutParams params4 = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
params4.setMargins(100, 100, 100, 100);
tv1.setLayoutParams(params4);
another1.addView(tv1);
TextView tv2 = new TextView(context);
tv2.setText("SOME TEST TEXT 2");
tv2.setTextColor(Color.BLACK);
LayoutParams params5 = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
params4.setMargins(100, 100, 100, 100);
tv2.setLayoutParams(params5);
another1.addView(tv2);
I expect margins to be applied, but they are not. What is the correct order of initializing such a view?
So, my trouble was in DP to PX converter that just wasn't initialized at that moment. However, to clarify everything, my example above is just an error (I didn't change params4 to params5 when adding the second TextView.
Also while testing everything, I found out that the order of adding layouts and their parameters doesn't matter at all.
You probably added child views to the parent view in onCreate().
In onCreate(), parent view does not have actual size.
If you have to do it in onCreate(), try following code.
final ViewTreeObserver observer = parent.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
LinearLayout.LayoutParams params = new
LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
params.setMargins(100, 100, 100, 100);
TextView view = new TextView(context);
view.setLayoutParams(params);
parent.addView(view);
observer.removeOnGlobalLayoutListener(this);
}
};
Hope this will help!
Try this:
LinearLayout ll = findViewById(R.id.linearLayout);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(30,20,30,0);
Hope this will help!
I need to be able to add a layout to my main layout from xml file many times programatically.
The problem is handling assigning ids of the new layout's views. See the code:
MainFragment.java
private int belowOfWhat = R.id.layout_header;
...
onActivityResult:
LayoutInflater myInflater = LayoutInflater.from(getContext());
RelativeLayout layout = (RelativeLayout) myInflater.inflate(R.layout.assignment_layout, null, false);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
//here problems start
//i want to position the new layout below the previously created layout
params.addRule(RelativeLayout.BELOW, belowOfWhat);
layout.setLayoutParams(params);
mRelativeLayout = rootView.findViewById(R.id.to_do_layout);
mRelativeLayout.addView(layout);
belowOfWhat = generateViewId();
idsOfToDos.add(belowOfWhat);
CheckBox assignmentCheckbox = (CheckBox)
//assignment_checkbox is an id of checkbox in the xml layout I add
rootView.findViewById(R.id.assignment_checkbox);
assignmentCheckbox.setId(belowOfWhat);
assignmentCheckbox.setText(mToDoInfo);
I don't know where the problem is, so here is how the app works now: I add a new layout, it gets positioned correctly below layout_header.
But when I add the second or more layouts they overlap each other on top of the app instead of being positioned one below the other.
I'd appreciate if you guided me to the solution of the problem.
If you don't need views'ids for other purposes you could solve more simple.
If I've understood what you are trying to do, what you need is a vertical LinearyLayout instead of a RelativeLayout, then subviews will be added one below each other
You have to use Relative Layout and use the following properties with that to align the views.
RelativeLayout.BELOW
RelativeLayout.RIGHT_OF
RelativeLayout.ALIGN_BOTTOM
RelativeLayout layout = new RelativeLayout(this);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
layout.setLayoutParams(layoutParams);
RelativeLayout.LayoutParams params1 = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
RelativeLayout.LayoutParams params2 = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
RelativeLayout.LayoutParams params3 = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
RelativeLayout.LayoutParams params4 = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
TextView tv1 = new TextView(this);
tv1.setId(1);
tv1.setText("textView1");
TextView tv2 = new TextView(this);
params2.addRule(RelativeLayout.RIGHT_OF, tv1.getId());
tv2.setId(2);
tv2.setText("textView2");
TextView tv3 = new TextView(this);
params3.addRule(RelativeLayout.BELOW, tv1.getId());
tv3.setId(3);
tv3.setText("textView3");
TextView tv4 = new TextView(this);
params4.addRule(RelativeLayout.RIGHT_OF, tv3.getId());
params4.addRule(RelativeLayout.ALIGN_BOTTOM, tv3.getId());
tv4.setId(4);
tv4.setText("textView4");
layout.addView(tv1, params1);
layout.addView(tv2, params2);
layout.addView(tv3, params3);
layout.addView(tv4, params4);
hope so it gives you an idea how to align views pragmatically.
I would like one image to be aligned left and the other to be aligned right but at present the two images just meet in the middle.
Any ideas?
View v = inflater.inflate(R.layout.fragment_hello_moon, parent, false);
TableLayout tl = (TableLayout)v.findViewById(R.id.l1);
TableRow tr = new TableRow(getActivity());
tr.setPadding(50, 0, 50, 0);
TableRow.LayoutParams params = new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.RIGHT;
ImageView imageL = new ImageView(getActivity());
imageL.setImageResource(R.drawable.bell_dl_256);
ImageView imageR = new ImageView(getActivity());
imageR.setImageResource(R.drawable.bell_dr_256);
imageR.setLayoutParams(params);
tr.addView(imageL);
tr.addView(imageR);
tl.addView(tr);
return v;
If I were you, I would use RelativeLayout. Only if two ImageView is enough doing what you want, you can use LinearLayout which orientation property is horizontal. And last advice you can do it in xml layout.
Plz validate the below relative layout
RelativeLayout objRLActionBar=new RelativeLayout(this);
objRLActionBar.setId(2534);
RelativeLayout.LayoutParams objRLActionBarParams=new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT,(int) (screenHeight*layoutHeights[1]));
objRLActionBarParams.addRule(RelativeLayout.BELOW,objRLTitleBar.getId());
objRLActionBar.setBackgroundColor(Color.parseColor("#2e4862"));
ImageView objIVActivityIcon = new ImageView(this);
objRLActionBar.setId(25324);
RelativeLayout.LayoutParams objIVActivityIconParams=new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
objIVActivityIconParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT,objRLActionBar.getId());
objIVActivityIcon.setLayoutParams(objIVActivityIconParams);
objIVActivityIcon.setImageResource(R.drawable.home_def);
objIVActivityIcon.setPadding(2, 0, 2, 0);
objRLActionBar.addView(objIVActivityIcon);
ImageView objIVSeperator = new ImageView(this);
objIVSeperator.setId(25342);
RelativeLayout.LayoutParams objIVSeperatorParams=new RelativeLayout.LayoutParams(1,LayoutParams.FILL_PARENT);
objIVSeperatorParams.addRule(RelativeLayout.RIGHT_OF,objIVActivityIcon.getId());
objIVSeperator.setLayoutParams(objIVSeperatorParams);
objIVSeperator.setImageResource(R.drawable.separator);
objIVSeperator.setBackgroundColor(Color.parseColor("#1f3449"));
objRLActionBar.addView(objIVSeperator);
TextView objTVPageName = new TextView(this);
RelativeLayout.LayoutParams objTVPageNameParams=new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
objTVPageNameParams.addRule(RelativeLayout.RIGHT_OF,objIVSeperator.getId());
objTVPageName.setLayoutParams(objTVPageNameParams);
objTVPageName.setTextColor(Color.WHITE);
objTVPageName.setTextSize(TypedValue.COMPLEX_UNIT_PX,18+sizeAdjust);
objTVPageName.setText("House Details");
objTVPageName.setTypeface(null, Typeface.BOLD);
objTVPageName.setPadding(2, 0, 2, 0);
objRLActionBar.addView(objTVPageName);
objRLBody.addView(objRLActionBar,objRLActionBarParams);
And the output is is as shown below
the image overlapped with text and the 'separator image' comes first! I need the components in this order objIVActivityIcon, objIVSeperator,objTVPageName. What is wrong with the above code plz help...
objRLActionBar.setId(25324);
should be
objIVActivityIcon.setId(25324);
HI , why my text is not coming at the bottom evethough i have given tParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
Here is my code please help,
footScroll_relative = new RelativeLayout(this);
footScroll_scrollView = new ScrollView(this);
footScroll_horizontalScrollView = new HorizontalScrollView(this);
test_text = new TextView(this);
footScroll_relative.setLayoutParams(new LinearLayout.LayoutParams(android.view.ViewGroup.LayoutParams.FILL_PARENT,android.view.ViewGroup.LayoutParams.FILL_PARENT));
LayoutParams tParams = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
tParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
footScroll_horizontalScrollView.setLayoutParams(new LinearLayout.LayoutParams(android.view.ViewGroup.LayoutParams.FILL_PARENT,android.view.ViewGroup.LayoutParams.FILL_PARENT));
footScroll_scrollView.setLayoutParams(tParams);
test_text.setText("Ramesh ");
footScroll_horizontalScrollView.addView(test_text);
footScroll_scrollView.addView(footScroll_horizontalScrollView);
footScroll_relative.addView(footScroll_scrollView);
setContentView(footScroll_relative);
this is an example of how to
TextView tView = ((TextView)view.findViewById(R.id.seekBarFilterLabel));
LayoutParams tParams = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
tParams.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
tView.setLayoutParams(tParams);
Hope this helps
EDIT: well, in your previuos unedited question you ask how to align the text at a RelativaLayout parent bottom, but here you are adding the TextView inside a HorizontalScrollView, wich is incorrect, the rule RelativeLayout.ALIGN_PARENT_BOTTOM are only valid if you are adding a view inside a RelativeLayout, not inside of ScrollView.