存储分配的 ViewGroup.MarginLayoutParams 并在任意时刻修改它们
Storing assigned ViewGroup.MarginLayoutParams and modifying them at arbitrary moments
我需要根据 View
的某些内部状态修改自定义 View
的 ViewGroup.MarginLayoutParams
。
任务看起来像这样:
- 在
View
的初始化期间设置一些 ViewGroup.MarginLayoutParams
,同时保存它们以跟踪通过 View
的布局属性设置的内容(layout_marginTop
, 等等).
- 在未来需要的时刻,使用存储值或其他一些值更改
ViewGroup.MarginLayoutParams
。
因此,我有两个问题:
- 通过布局属性设置的
ViewGroup.MarginLayoutParams
保存的正确位置是什么?
无法在 View
的构造函数中执行此操作,因为父 ViewGroup
尚未分配它。 onAttachedToWindow()
是正确的地方吗?
onMeasure()
是根据需要调整ViewGroup.MarginLayoutParams
的正确位置吗?
像这样:
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams)getLayoutParams();
params.topMargin = ...;
setLayoutParams(params);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
由于在上面的代码中我们在 onMeasure()
中调用了 setLayoutParams()
(当当前布局传递正在进行时),它会导致第二次布局传递吗?
您可以只保留对您正在使用的 ViewGroup
的引用,并根据需要调用 getLayoutParams
。您需要使 params
变量成为 ViewGroup
的更具体实例 - 您可以将其实例化为
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) view.getLayoutParams();
然后,您可以调用您选择的
params.setMarginStart(int);
params.setMarginEnd(int);
params.setMargins(int, int, int, int);
设置边距。请注意,您根本不需要调用 setLayoutParams()
来应用更改。 params
变量和 view.getLayoutParams()
引用同一个对象,因此您对其中一个所做的任何更改都将应用于另一个。
完整的代码示例如下所示:
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);
}
}
只要您在 onCreate
之后调用该方法就可以了。
第二个问题的答案取决于触发保证金变化的事件。如果是在 activity 重新创建时,您可以在 onResume
中执行(因为这保证在 onCreate
之后发生)。您也可以从 onClickListener
或接口回调中调用它。因此,您不一定必须在 onMeasure
.
中设置边距
我需要根据 View
的某些内部状态修改自定义 View
的 ViewGroup.MarginLayoutParams
。
任务看起来像这样:
- 在
View
的初始化期间设置一些ViewGroup.MarginLayoutParams
,同时保存它们以跟踪通过View
的布局属性设置的内容(layout_marginTop
, 等等). - 在未来需要的时刻,使用存储值或其他一些值更改
ViewGroup.MarginLayoutParams
。
因此,我有两个问题:
- 通过布局属性设置的
ViewGroup.MarginLayoutParams
保存的正确位置是什么?
无法在 View
的构造函数中执行此操作,因为父 ViewGroup
尚未分配它。 onAttachedToWindow()
是正确的地方吗?
onMeasure()
是根据需要调整ViewGroup.MarginLayoutParams
的正确位置吗?
像这样:
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams)getLayoutParams();
params.topMargin = ...;
setLayoutParams(params);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
由于在上面的代码中我们在 onMeasure()
中调用了 setLayoutParams()
(当当前布局传递正在进行时),它会导致第二次布局传递吗?
您可以只保留对您正在使用的 ViewGroup
的引用,并根据需要调用 getLayoutParams
。您需要使 params
变量成为 ViewGroup
的更具体实例 - 您可以将其实例化为
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) view.getLayoutParams();
然后,您可以调用您选择的
params.setMarginStart(int);
params.setMarginEnd(int);
params.setMargins(int, int, int, int);
设置边距。请注意,您根本不需要调用 setLayoutParams()
来应用更改。 params
变量和 view.getLayoutParams()
引用同一个对象,因此您对其中一个所做的任何更改都将应用于另一个。
完整的代码示例如下所示:
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);
}
}
只要您在 onCreate
之后调用该方法就可以了。
第二个问题的答案取决于触发保证金变化的事件。如果是在 activity 重新创建时,您可以在 onResume
中执行(因为这保证在 onCreate
之后发生)。您也可以从 onClickListener
或接口回调中调用它。因此,您不一定必须在 onMeasure
.