How to detect if view has finished re-drawing - java

I have an ImageView and I want to change it's size in runtime. So I do the following:
LayoutParams params = (LayoutParams) imgView.getLayoutParams();
params.width = size;
params.height = size
imgView.setLayoutParams(params);
The problem is that based on these new width and height I want to change my another ImageView, but seems like LayoutParams are not applied immedately, because Log put just after setLayoutParams prints old width value. So here is a question: is there any way to force ImageView to update (I already tried View.invalidate() and View.requestLayout but no success), or is there any way to detect if ImageView has finished updating, so I can use it's new parameters?

you can attach a viewTreeObserver. Which will get called every time layout is changed
You can follow this link

Related

Changing LinearLayout Height from top (default from bottom) in Android programmatically (Java)

I want to change the height of a LinearLayout and works everything OK, but I want height decreasing and increasing from the top (the defaults starts decreasing and increasing from the bottom).
Here is an example:
LinearLayout linearLayout = findById(R.id.layout);
LinearLayout.LayoutParameters layoutParams = (LinearLayout.LayoutParameters) linearLayout.getLayoutParams();
layoutParams.height = linearLayout.getHeight() - 1;
linearLayout.setLayoutParams(layoutParams);
This works OK. The only thing I wanna change is the direction of height change.
Thanks for the replay.
You can achieve this by binding(the bottom) of your linear layout inside a constraint layout,
Also is there a parent to your linear layout?, if so then it being unbound might be the reason
I achieved changing the direction with the setLayoutDirection(View.LAYOUT_DIRECTION_LOCALE) from teh ViewGroup class. Also had to change layout's gravity to bottom in the xml.
Thanks for contribute to my answer.

Display rotated views that exceed screen bounds correctly without resizing

Right now I am trying to solve a problem with adding views on top of a custom view that can exceed the screen bounds. That custom view draws different rectangles at different angles. For later use it should be possible to select the rectangles for later drag n drop implementations where I don’t want to constantly redraw the whole custom view.
So over each drawn rectangle I put a button that has the same dimensions and rotation.
For some reason however android seems to resize my views automatically when it hits the end of the Screen:
My expectation(button covers everything even if only half visible):
The actual behaviour(button gets shrunk):
This by itself is not a huge issue when the view I want to add is not rotated.
If the view is rotated however the rotation around the center point causes all kinds of problems as the view is now smaller and on a different location:
My expectation(button is rotated exactly around the center point of the object):
What I get is button becomes smaller and therefore its center point moves:
I read on other questions that View.setClipChildren(false) and View.setClipPadding(false) should help. But all it does is basically mess up my view hierarchy because I kinda want clipping to happen but not the automated resize. And on top of that it doesn’t fix the issue that I am having.
Does any of you have an Idea how I can fix this?
I tried to do the same on IOS and JavaFX which both work as I expected them to.
Since I am trying to solve the whole thing programmatically, I created some test code that places a buttons center point on the screen edge and rotates it 45 degrees: So you should only be able to see half of the button. But the button appears smaller and is fully visible on the right side of the screen. Of course due to the different center point it’s also not on the location I would expect it to be.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Context context = getApplicationContext();
RelativeLayout relativeLayout = new RelativeLayout(context);
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int height = displaymetrics.heightPixels;
int width = displaymetrics.widthPixels;
Button button = new Button(context);
button.setText("DO STUFF");
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(800, 80);
params.leftMargin = width - 400;
params.topMargin = height / 2;
button.setLayoutParams(params);
button.setRotation(45);
button.setBackgroundColor(Color.RED);
relativeLayout.addView(button);
setContentView(relativeLayout);
}
}
I found the solution myself by accident.
It appears to be a special behavior of the RelativeLayout. I didn't find anything that explains it, but I swapped it out with a FrameLayout which has two positive effects.
It works as I expected it to
I got a performance increase since I was also nesting multiple Relative Layouts into each other.

Weight property on android linear layout is not working

I am aware that there are a lot of questions out there with a similar question. However, most of them deal with horizontal orientation whereas my problem is with vertical orientation. And I have tried a few but they were of no help.
I am having issues with vertical orientation of linear layout. I have got this so far:
My layout parameter for this is as follows:
LinearLayout.LayoutParams lparams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
lparams.weight = 1;
// And then simply adding this Layout param to all the widgets
However, when I set the height property to 0, I get nothing. My understanding is I should still get the same output since it should be assigning equal height to all of them based on the weight property. Can any one please help out?
I have finally figured out the problem. The problem was not with my understanding. My understanding is correct. However, when setting the content view I was passing in the same LayoutParams that I used for widgets. When, I set the height to 0, it would all set the height of everything to 0. To get around it, I just needed to create a new LayoutParam and pass that in with Content View.

Two overlapping ImageViews in Android

In a ViewGroup I want to put two ImageViews overlapping: The imageview A have a transparent background and some drawing across the image, the imageview B.
I want both them to be at the same place and have the same size (but can't fix their size in the XML because if the image at ivB changes the ivA should resize to match the new size.
Since the ivA source image does not change I tried ivA.getWidth() and ivA.getHeight() for setting the ivB size but their value are 0,0 in the onCreate() method.
Is there some "easy" way of doing this?
Override the ImageView and in onLayout() you can get proper width or height after calling super.onLayout(). Try setting values in the place.
Try getting the dimensions in onWindowFocusChangedListener.
An easier way would be putting the ImageViews in a FrameLayout (which is built to put Views on top of the other), and resize the FrameLayout instead.

Only some Layout Params work

I am trying to align a custom View object above and aligned_left of a RelativeLayout. My (snipped) code looks something like this:
int bored = board.getId(); //board is the RelativeLayout
Border border = new Border();
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_LEFT, bored);
params.addRule(RelativeLayout.ABOVE, bored);
this.addView(border,params);
This gives me a Border object aligned_left with my RelativeLayout but NOT "ABOVE" (technically, it is above it, but it's at the top of the screen not aligned the way it's supposed to be). And, even stranger, when I do this:
int bored = board.getId();
Border border = new Border();
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_LEFT, bored);
params.addRule(RelativeLayout.BELOW, bored); //<---The only difference
this.addView(border,params);
...it works perfectly. it is aligned left and below in the ways that are expected. Why is the ABOVE attribute giving me such a hard time?
Edit:
ABOVE is supposed to align the bottom edge of one view with the top edge of the target. Here is a screen shot of how my project is not working as intended.
The green bar at the top of the screen is the Border object I am trying to align. As you can see, its left edge is aligned with "board" however it is in the wrong place at the top of the screen.
Can you check if board and Border are not using more space? for example, by setting the background to a color to see their dimensions in the screen?
Maybe board, which you mention is a RelativeLayout is bigger of what you think.
I hope this helps
I fixed my problem by using an ImageView instead of my custom Border class (which was basically just a bitmap drawn to a canvas from a resource). My code now looks like this:
int bored = board.getId(); //board is the RelativeLayout
ImageView border = new ImageView(this);
border.setImageResource(R.drawable.border_tiki1);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_LEFT, bored);
params.addRule(RelativeLayout.ABOVE, bored);
this.addView(border,params);
My best guess is that it was having trouble defining the ABOVE constant for my custom object. Thanks to everyone who took the time to look over this. Here's what my view looks like now:
From this anchor, I'll build the rest of the border out of other small pieces. Thanks again!
Without seeing the rest of the code, this is just a guess, but the order in which the objects are created makes a difference in how the objects are layed out. Especially where Relative Layouts are concerned.

Categories