Issue
I need to modify custom View's ViewGroup.MarginLayoutParams depending on some inner state of the View.
The task looks like this:
- Set some of the
ViewGroup.MarginLayoutParamsduringView's initialization at the same time saving them to keep track of what was set viaView's layout attributes (layout_marginTop, etc). - At the desired moments in the future, change
ViewGroup.MarginLayoutParamsusing either stored values or some other ones.
Hence, I have 2 questions:
- What is the right place to save
ViewGroup.MarginLayoutParamsset via the layout attributes?
Can't do it in the View's constructor, since the parent ViewGroup hasn't yet assigned it. Is onAttachedToWindow() the correct place for that?
- Is
onMeasure()the correct place for adjustingViewGroup.MarginLayoutParamsas needed?
Something like this:
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams)getLayoutParams();
params.topMargin = ...;
setLayoutParams(params);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
Since in the code above we're calling setLayoutParams() in onMeasure() (when the current layout pass in progress), would it cause the second layout pass?
Solution
You can just keep a reference to the ViewGroup that you're working with, and call getLayoutParams as needed. You'll need to make the params variable a more specific instance of ViewGroup- You could instantiate it as
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) view.getLayoutParams();
Then, you can just call your choice of
params.setMarginStart(int);
params.setMarginEnd(int);
params.setMargins(int, int, int, int);
to set the margins. Note that you do NOT need to call setLayoutParams() at all to have the changes apply. The params variable and view.getLayoutParams() reference the same object, so any changes you make to one will apply to the other.
A full code example could look like the following:
public final class MyActivity extends AppCompatActivity {
RelativeLayout parent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
parent = (RelativeLayout) findViewById(R.id.parent);
}
private void setParentMargin(int left, int top, int right, int bottom) {
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) parent.getLayoutParams();
params.setMargins(left, top, right, bottom);
params.setMarginStart(left);
params.setMarginEnd(right);
}
}
As long as you call that method after onCreate, you should be fine.
The answer to your second question depends on what event is triggering the change in margin. If it's whenever the activity gets recreated, you could do it in onResume (because that's guaranteed to happen after onCreate). You could also call it from an onClickListener, or from an interface callback. So, you do not necessarily have to set the margins in onMeasure.
Answered By - evanklicker
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.