Android ConstraintLayout programmatically connect but only work top to top - java

LinearLayout.LayoutParams navigationBarParams =
new LinearLayout.LayoutParams(0, (int)(BAR_DEFAULT_HEIGHT_DP * density) );
_navigationBar.setId(R.id.navigation_fragment_navigation_bar);
_navigationBar.setPadding(0, 0, 0, 0);
_navigationBar.setLayoutParams(navigationBarParams);
_navigationBar.setOrientation(LinearLayout.HORIZONTAL);
_navigationBar.setBaselineAligned(false);
_navigationBar.setWeightSum(6f);
_navigationBar.setElevation(20.0f);
ConstraintLayout con = (ConstraintLayout)_rootView.findViewById(_rootConstraintLayoutId);
con.addView(_navigationBar);
ConstraintSet set = new ConstraintSet();
set.clone(con);
set.constrainWidth(_navigationBar.getId(), 0);
set.connect(_navigationBar.getId(), ConstraintSet.TOP, con.getId(), ConstraintSet.TOP, 100 ); //work!
set.connect(_navigationBar.getId(), ConstraintSet.LEFT, con.getId(), ConstraintSet.LEFT,100 ); //not work!!
set.connect(_navigationBar.getId(), ConstraintSet.RIGHT, con.getId(), ConstraintSet.RIGHT, 100 ); //not work!!
set.applyTo(con);
I add LinearLayout to root ConstraintLayout.
and connect constraint TOP to TOP, LEFT to LEFT, RIGHT to RIGHT with all value 100.
but only top value 100 is work.
not work left, right. what wrong my code?

임근영 Use Start and End instead on that way your view it will support different languages.
set.connect(boton.getId() , ConstraintSet.START , ConstraintSet.PARENT_ID , ConstraintSet.START , 80);
I know there is a bug reported on google for that.

android.support.constraint.ConstraintLayout
on that try removing it and use
"LinearLayout"
you will be able to change your orientation as you like.
by writing
andriod:oreiantation="horizontal" or andriod:oreiantation="vertiacl"
its your choice

Related

How to set a view at specific position on screen?

How to can I set a view at a specific point on the screen programmatically? I want use a Point like x and y. I don't want it to translateX or translateY. I want for example to set a view to the Point x: 0 and y: 0 that means it needs to be at the top left of the screen. How can I achieve that?
I was trying this but the view translates X and Y what I don't want.
val layoutInflater = LayoutInflater.from(context)
val inflatedView: View = layoutInflater.inflate(R.layout.fragment_change_font_size_right, null, false)
inflatedView.popup_xml_view.x = 0f
inflatedView.popup_xml_view.y = 0f
Android had a layout that would support this requirements, but I think that it was pretty bad in regards to performance and it was deprecated (I hope that I am not wrong making this affirmation). However, the same behaviour can be implemented using a FrameLayout and add the views in that layout.
To add a view at a particular position, you create its layout params to set a width and a height, then set the margins which will position your view as absolute coordinates (the dimension is in pixels):
val imageView = ImageView(this)
imageView.setBackgroundResource(android.R.color.holo_red_dark)
imageView.layoutParams = FrameLayout.LayoutParams(width, height).apply {
setMargins(left, top, right, bottom)
}
root.addView(imageView)
For a height/width of 200 and margins of (100, 100, 0, 0), it will look something like the image below (run on an emulated Pixel 3).
NOTE: Here is a talk where they talk about this approach to emulate the AbsoulteLayout and why they "killed" it.
I found this to work:
ViewGroup.MarginLayoutParams margins = (ViewGroup.MarginLayoutParams) layout.getLayoutParams();
margins.topMargin = 100;
margins.leftMargin = 200;
Alternatively use animate:
view.animate().x(x).y(y).setDuration(0).start();

Programatically setting constraints is leading to views overlapping

I'm trying to write some code to display two views within a constraint layout. I have used the following code so that the first view should appear on the left of the screen, and the second on the right.
ConstraintSet set = new ConstraintSet();
set.clone(cl);
set.connect(tv.getId(), ConstraintSet.LEFT, ConstraintSet.PARENT_ID, ConstraintSet.LEFT, 0);
set.connect(img.getId(), ConstraintSet.RIGHT, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT, 0);
set.applyTo(cl);
However when I run my app the two views just appear in the centre overlapping each other.
The code for my two views is:
ConstraintLayout.LayoutParams params3 = new
ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.WRAP_CONTENT,
ConstraintLayout.LayoutParams.WRAP_CONTENT
);
params3.setMargins(8,8,8,8);
ConstraintLayout.LayoutParams params4 = new
ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.WRAP_CONTENT,
ConstraintLayout.LayoutParams.WRAP_CONTENT
);
params4.setMargins(5,5,5,5);
LinearLayout.LayoutParams params5 = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
);
TextView tv = new TextView(mContext);
tv.setText(LeagueName);
tv.setTextSize(18);
tv.setLayoutParams(params3);
ImageView img = new ImageView(mContext);
img.setImageResource(R.mipmap.basketball);
img.setLayoutParams(params4);
cl.addView(tv);
cl.addView(img);
card.addView(cl);
mLayout.addView(card);
I'm new to android so I've almost certainly missed something fundamental.
Thanks
So after a lot of playing around I've discovered that getId() returns the same default value for each element and so each time I added a new constraint I was applying it to every view. The way around this is to use setId() every time you create a new view in order to ensure they remain unique.

Android: calling setPadding() on a view doesn't work when I also set the layoutParams on the view

If I call setPadding() on a view, I can successfully set the padding, however, if I first set the layoutParams and then the padding, or set the padding and then set the layoutParams, the padding is not applied.
Demonstration:
//This doesn't work
textView.setLayoutParams(linearLayoutParams);
textView.setPadding(0, 100, 0 , 0);
//This doesn't work either
testView.setPadding(0, 100, 0 , 0);
textView.setLayoutParams(linearLayoutParams);
//This does work
textView.setPadding(0, 100, 0 , 0);
Does anyone know how to use setLayoutParams() and setPadding() at the same time, or why setLayoutParams() is stopping setPadding() from working?
Edit:
More detail:
I call this method in onCreate()
public void initTextView(){
Textview textView = (TextView) findViewById(R.id.textView);
LinearLayout.LayoutParams linearLayoutParams = new LinearLayout.LayoutParams(myWidth, myHeight);
textView.setLayoutParams(linearLayoutParams);
//This doesn't work
textView.setPadding(0, 100 ,0 , 0);
}
but if I comment out this line from above:
// textView.setLayoutParams(linearLayoutParams);
Then the setPadding() method does work.
Thanks in advance.
I don't believe there's anything wrong with the code, rather just not understanding what it's doing.... if your myHeight value is smaller than the padding, you're just simply not going to notice the effect.
In the attached series of screenshots, the first screenshot is the default TextView containing a price (it has no layout params other than what's set in xml).
In the 2nd screenshot I set the textview to the following (height=30, top padding = 100:
LinearLayout.LayoutParams linearLayoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 30);
textview.setLayoutParams(linearLayoutParams);
textview.setPadding(0, 100, 0, 0);
The text is there, the top padding is there, but it's all forced to "crop" to the set height of 30 (note I also lost all my original xml parameters (gravity, margins, etc) because setting LayoutParams cancels all of that and only applies whatever I set in those LayoutParams).
In the 3rd screenshot I set the textview to the following (height=150, top padding = 100:
LinearLayout.LayoutParams linearLayoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 150);
textview.setLayoutParams(linearLayoutParams);
textview.setPadding(0, 100, 0, 0);
Voila! Since I've given the view ample height, it can fully display the text and the top padding (though again, I lost all my xml parameters).. If you go back to your source, try it out: replace myHeight with some fixed value (try at least 150) and see if things display as they should.
object ScreenUtils {fun dpToPixel(dp: Int): Int {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp.toFloat(), Resources.getSystem().displayMetrics).toInt()}}
in Kotlin
setPadding(ScreenUtils.dpToPixel(8), 0, ScreenUtils.dpToPixel(8), 0)

Setting margin AND background color in a TableRow

I have a strange issue when setting programmatically both margin and background color on a TableRow.
I already read this thread about margin, and this one about background color, but apparently, I do things correctly. The problem seems to be somewhere else.
I create dynamically TableRows, which odds must be a specific color (to improve readability). I simply wrote this :
if(myCursor != null && myCursor.moveToFirst()){
do{
TableRow tableRow = new TableRow(getActivity());
TableLayout.LayoutParams tlp = new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.MATCH_PARENT);
tlp.setMargins(0, 10, 0, 10);
tableRow.setLayoutParams(tlp);
for(int j=0 ; j < TopTagsDetailsCursor.getColumnCount();j++){
TextView tv = new TextView(getActivity());
tv.setText(TopTagsDetailsCursor.getString(j));
if (j>0) tv.setGravity(Gravity.CENTER);
tableRow.addView(tv);
}
if ((i % 2) != 0){
tableRow.setBackgroundColor(getResources().getColor(R.color.table_row));
}
dataTable.addView(tableRow);
i++;
});
}while(myCursor.moveToNext());
What I don't understand, is that on each odd row, with my custom background color, my custom margins (10 for top and bottom) aren't "applied" to the row, but they do are on even row.
Still stranger: if I remove the part of the code about custom background color, margins are OK everywhere !!
So, why my custom margins aren't ok when I put custom background color ??
PS: I even tried to move some lines of code (especially the addView(tableRow) and those about the color), but no effect.
Thanks in advance ! :)
It doesn't explain why it didn't work before, but at least I finally found a "fix".
I remove these lines :
TableLayout.LayoutParams tlp = new TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.MATCH_PARENT);
tlp.setMargins(0, 10, 0, 10);
tableRow.setLayoutParams(tlp);
And I replaced :
tableRow.addView(tv);
by :
tableRow.addView(tv, new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, 80)); //or any other value
and it works fine finally... even if I don't understand why my first solution didn't work :) (feel free to explain me why !)

Move view dynamically in relativelayout

I am doing an pageindex, and the current page should be highlighted with a arrow image (imageview).
The index is a RelativeLayout with 25 textviews added to it:
for (int i = 0; i < 25; i++) {
TextView tv = new TextView(this);
tv.setText(Integer.toString(i+1));
tv.setGravity(Gravity.CENTER);
int id = 2000+i;
tv.setId(id);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.FILL_PARENT);
if(i==0)
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
else
params.addRule(RelativeLayout.RIGHT_OF, prevViewId);
prevViewId = id;
rl.addView(tv,params);
}
And when the page changes I do something like this:
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_BOTTOM, 2000+i);
params.addRule(RelativeLayout.ALIGN_RIGHT, 2000+i);
params.addRule(RelativeLayout.ALIGN_LEFT, 2000+i);
arrowImageView.setLayoutParams(params);
rl.requestLayout();
rl.invalidate();
Everything looks correct, I can place the arrow at arbitrary page at "start up", but the arrow wont move when page is changed. I have debuged and verified that the code is run and everything looks correct, but still the arrow is stuck in the first position. If I force delete and add a new imageview instead of updating the LayoutParams the arrow will disappear totally.
I have the same problem.. I also want to move my views around at run-time inside a reference layout. So if anyone ca help that would be awesome.
What i believe is happening above is that the arrow IS having its location changed, however it doesn't get updated to the screen. Correct me if I'm wrong, please, this is just my guess as I am too having the same problem.
-edit-
After some messing around I've found what works for me is to remove first then add.
rl.removeView(tv);
rl.addView(tv,params);
-edit-
also, u can save the params for the moving view into a unique variable so that way all ude have to do is change the margins...
for example: instead of params, have it be its own name "arrowParams"
then to move it ude just need: arrowParams.leftMargin = 2000+i; and so on...

Categories