Is setPadding broken for LinearLayout? - android

I have a very short problem. I have a custom control that is based upon LinearLayout. I inflate it's view from xml', in which the root is set as element.
Now when I try to set the padding of this custom control by "this.setPadding(x,x,x,x)" it does not affect the TextView and ImageView I add to this control in a few lines of code later.
Currently I am bypysing it, by setting the margin of each control separately, to achieve the global padding of the whole custom control, but it would be nice to know if there is a catch in using setPadding dynamicaly, or maybe a mistake is mine.
To simplify, my case looks like that:
setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL);
LinearLayout.LayoutParams lp = new
LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT); setLayoutParams(lp);
setPadding(0, 30, 0, 30); //I know it's in px
Afterwards I'm adding a large image, which shrinks due to it's size, but the padding of LinearLayout(which I try to set dynamicaly) does not affect it, only if I set margin on it directly.
Any tip would be greatly appriciated.

After a little of digging, found an answer through other StackOverflow question:
https://stackoverflow.com/a/13363318/905938
Basicaly if one person sets a background reasource with a selector xml given (as in my case) it overrides completely the previous padding setting. So the padding I was setting within the custom control initialization was lost as soon as it was set.
Now that I know the problem, I basicaly just intercept the call to this method in my custom control like this:
#Override
public void setBackgroundResource(int resid)
{
int paddingLeft, paddingTop, paddingRight, paddingBottom;
paddingLeft = getPaddingLeft();
paddingTop = getPaddingTop();
paddingRight = getPaddingRight();
paddingBottom = getPaddingBottom();
super.setBackgroundResource(resid);
setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
}
That solves the problem, and I hope will solve a problem for anybody who will find this question with a similar problem.

Related

Are Android XML style attributes not overridden in order?

I have a TextView which should have 10dp padding in the top and bottom, and 30dp on the left. I then tried:
android:padding="10dp"
android:paddingLeft="30dp"
That's what I'd do in CSS. But it doesn't work.
Regardless of the order, my left padding is 10dp. Are Android style attributes not overridden in the order they appear? If so, is there any list of priorities?
Ex: android:padding always overrides android:paddingLeft
Overriding is an important feature in CSS which saves a lot of coding, so I wanted to know if that's possible in Android.
Maybe I just couldn't find the answer with the right terms. If someone could point me where to understand it I'd be very appreciated.
The Android layout system is different from CSS. It does not care about the order of the properties, and padding always overrides paddingLeft, paddingRight, etc.
You can find the relevant source code in View.java here (padding is set) and here (if padding is set it is used, even if paddingLeft is set).
This is the most important snippet:
if (padding >= 0) {
leftPadding = padding;
topPadding = padding;
rightPadding = padding;
bottomPadding = padding;
mUserPaddingLeftInitial = padding;
mUserPaddingRightInitial = padding;
}
As I understand from the source code,
when you set the padding attribute it can be overridden by other padding attributes.

Can a View be focused and invisible at the same time?

I want to have an EditText in focus so it is edited, but also invisible. In other words, all the user will see is the keyboard.
Is that possible?
AFAIK, an invisibility Edittext cannot have a view( I have never tried) so the workaround for you is
You can set a transaparent background for edittext to achieve this.
youredittext.setBackgroundResource(android.R.color.transparent);
or you can directly set the attribute in XML like this
android:background="#null"
I know I might be late, but recently I had to face a similar problem.
The solution could also be this one (use in styles.xml or in the layout):
android:layout_width = 0dp
android:layout_height = 0dp
That will also let your EditText be still focusable.
My two alternate approaches:
Approach 1: Fade it out
view.animate().alpha(0.0f).setDuration(0);
and fade it in when you want it back
view.animate().alpha(1.0f).setDuration(0);
Setting duration to 0 ensures it happens instantaneously.
Approach 2: Set the view outside the screen
LayoutParams params = view.getLayoutParameters();
int offset = -80; // offset from the screen border, choose your own
params.setMargins(0, 0, offset, 0); // left, top, right, bottom
view.setLayoutParams(params);
and do
params.setMargins(0, 0, 0, 0); // left, top, right, bottom
view.setLayoutParams(params);
when you want it back.

Using LinearLayout.LayoutParams programmatically

I'm having some trouble with Android's LayoutParams.
Basically I am trying to create an application that is completely dynamic, with all layouts generated programmatically and practically nothing beyond my splash screen committed to XML. I am having some success using linear layouts, and the app is rendering everything that I want it to. I am just having some trouble with fine tuning the layouts. e.g. forcing my footer to the bottom of the screen, stretching button bars to cover the entire width, etc.
As far as I can tell, the way to achieve this programmatically is using the setLayoutParams method. My problem is that I am not sure how to get the information into the Layout Params.
At the moment I am using the LinearLayout.LayoutParams (int width, int height) constructor, but I have not found a way of setting the parameters once it is created.
Instead I would like to use the LinearLayout.LayoutParams (Context c, AttributeSet attrs) constructor, but I can't find the right way of declaring an AttributeSet.
Can anyone help me?
Look at all of the "set" methods for the LinearLayout here:
http://developer.android.com/reference/android/widget/LinearLayout.html
Try like below -
android.view.ViewGroup.MarginLayoutParams params = (MarginLayoutParams) surfaceView.getLayoutParams();
params.height = DesireHeight;
params.width = DesireWidth;
params.leftMargin = DesireMarginLeft;
params.topMargin = DesiremarginTop;
params.rightMargin = DesireMarginRight;
params.bottomMargin = DesireMarginBottom;
YOURView.setLayoutParams(params);

Get the size of a text in TextView

I have a problem placing a textView at specified center's x and y coordinates.
Firstly, I tried to set the text in the textView, and to move the view with the width and the height of the view
from this link.
But it doesn't work, and I'd like to try something else.
I'd like to know if there is a method to get the size which a specified text will take in my textView?
I mean, I know the text and the textSize, how can I get the width and the height my textView will take?
Something like the method (NSString)sizeWithFont; for those who know iPhone dev.
Rect bounds = new Rect();
textView.getPaint().getTextBounds(textView.getText().toString(), 0, textView.getText().length(), bounds);
bounds.width() will give you the accurate width of the text in the Text View.
If your textview is called tv
tv.setText("bla");
tv.measure(0, 0); //must call measure!
tv.getMeasuredHeight(); //get height
tv.getMeasuredWidth(); //get width
More on this (updated): How to get width/height of a View
For some reason the solution of Midverse Engineer does not give me always correct results (at least on some Android versions). The solution of Sherif elKhatib works, but has the side effect of changing MeasuredWidth and Height. This could lead to incorrect positioning of the textView.
My solution:
width = textView.getPaint().measureText(text);
metrics = textView.getPaint().getFontMetrics();
height = metrics.bottom - metrics.top;
Using the TextView inner Paing class is not so hot when you have multiple lines of text and different paddings. So stop trying to reinvent the wheel. Use getMeasuredHeight and getMeasuredWidth methods after calling measure(UNSPECIFIED, UNSPECIFIED). Just don't forget to get the new values inside the post, otherwise mostly you'll get a wrong result.
tv.setText(state.s);
tv.measure(UNSPECIFIED,UNSPECIFIED);
tv.post(new Runnable() {
#Override
public void run() {
Log.d("tv","Height = "+tv.getMeasuredHeight());
Log.d("tv","Width = "+tv.getMeasuredWidth());
}
});

Changing LayoutParams programmatically has no effect in Android. Why?

I have a custom view, derived from Button, which I want to position at runtime, relative to another view. Because I don't know that other view's position yet when my view is being inflated (because layouting hasn't started), I leverage the onSizeChanged handler to set my view's position relative to the other view.
In onSizeChanged:
LayoutParams lp = new LayoutParams(this.getMeasuredWidth(), this.getMeasuredHeight());
lp.leftMargin = x;
lp.topMargin = y;
this.setLayoutParams(lp);
forceLayout();
That, however, has no effect. How come?
Some things to consider:
Are you sure this code is being executed?
Have you examined the UI in hierarchyviewer to see if the margins are being set but they are simply not having the visual effect you expect?
Are you sure this isn't better handled just via a RelativeLayout?
Have you tried modifying the existing LayoutParams rather than replacing it?

Categories

Resources