步骤1.使用导航抽屉模板创建一个新应用程序。
步骤2.添加自定义按钮并覆盖onMeasure方法。
@CoordinatorLayout.DefaultBehavior(MyButton.Behavior.class)
public class MyButton extends android.support.v7.widget.AppCompatButton {
private ViewTreeObserver.OnPreDrawListener mPreDrawListener;
public MyButton(Context context) {
super(context);
}
public MyButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (mPreDrawListener == null) {
mPreDrawListener = new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
offsetTopAndBottom(50);
return true;
}
};
ViewParent p = getParent();
if (p instanceof View) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
((View)p).getViewTreeObserver().addOnPreDrawListener(mPreDrawListener);
}
}
}
}
public static class Behavior extends CoordinatorLayout.Behavior<MyButton> {
@Override
public boolean onLayoutChild(CoordinatorLayout parent, MyButton child, int layoutDirection) {
final List<View> dependencies = parent.getDependencies(child);
return super.onLayoutChild(parent, child, layoutDirection);
}
@Override
public void onAttachedToLayoutParams(@NonNull CoordinatorLayout.LayoutParams lp) {
if (lp.dodgeInsetEdges == Gravity.NO_GRAVITY) {
// If the developer hasn't set dodgeInsetEdges, lets set it to BOTTOM so that
// we dodge any Snackbars
lp.dodgeInsetEdges = Gravity.BOTTOM;
}
}
}
}
第3步。在app_bar_main布局中使用MyButton
。
步骤4.在onPreDraw中设置断点然后我可以看到它将无限执行。如果我评论offsetTopAndBottom(50)
,一切都会顺利。
我还会一遍又一遍地跟踪源代码并查找应用程序接收vsync信号,这会导致Choreographer.java中的onVsync
函数无限运行。为什么会这样?
如果我设置如下的断点并注释onPreDraw
,则最终将无法达到此断点,否则,它总是可以到达。
答案 0 :(得分:1)
在绘制每个帧之前调用回调<ul class"list">
<li>first list item</li>
<li>second list item</li>
<div>
<li>third list item</li>
<li>fourth list item</li>
</div>
<li>fifth list item</li>
<li>sixth list item</li>
</ul>
<form>
<select>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
</select>
</select>
<button type="button">Select List Item</button>
</form>
。由于你通常会继续绘制画框(~60fps),因此被称为“#34;无限地”#34;这是正常的。
为了避免这种行为,通常的模式是将监听器作为onPreDraw()
中的第一个语句删除:
onPreDraw()
其中view.getViewTreeObserver().removeOnPreDrawListener(this);
是您案例中的降级父母。
您可以在this video中看到示例代码。工程师是Android Framework团队的一员。