在创建活动后,我正在尝试将动画应用到我的Android应用中的视图.为此,我需要确定视图的当前大小,然后设置动画以从当前大小缩放到新大小.此部分必须在运行时完成,因为视图根据用户的输入缩放到不同的大小.我的布局是用XML定义的.
这似乎是一件容易的事,虽然没有一个能解决我的问题,但很多问题都存在.所以也许我错过了一些明显的东西.我通过以下方式了解了我的观点:
ImageView myView = (ImageView)getWindow().findViewById(R.id.MyViewID);
Run Code Online (Sandbox Code Playgroud)
这工作得很好,但打电话时getWidth()
,getHeight()
,getMeasuredWidth()
,getLayoutParams().width
,等,他们都返回0.我也试过手动调用measure()
视图上,然后到一个呼叫getMeasuredWidth()
,但没有效果.
我已经尝试调用这些方法并在我的activity onCreate()
和in中检查调试器中的对象onPostCreate()
.如何在运行时确定此视图的确切尺寸?
Vik*_*rla 177
使用View上的ViewTreeObserver等待第一个布局.只有在第一个布局后才能使用getWidth()/ getHeight()/ getMeasuredWidth()/ getMeasuredHeight().
ViewTreeObserver viewTreeObserver = view.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
viewTreeObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
viewWidth = view.getWidth();
viewHeight = view.getHeight();
}
});
}
Run Code Online (Sandbox Code Playgroud)
and*_*per 55
实际上有多种解决方案,具体取决于方案:
Run Code Online (Sandbox Code Playgroud)public static void runJustBeforeBeingDrawn(final View view, final Runnable runnable) { final OnPreDrawListener preDrawListener = new OnPreDrawListener() { @Override public boolean onPreDraw() { view.getViewTreeObserver().removeOnPreDrawListener(this); runnable.run(); return true; } }; view.getViewTreeObserver().addOnPreDrawListener(preDrawListener); }
样品用法:
ViewUtil.runJustBeforeBeingDrawn(yourView, new Runnable() {
@Override
public void run() {
//Here you can safely get the view size (use "getWidth" and "getHeight"), and do whatever you wish with it
}
});
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)view.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); int width=view.getMeasuredWidth(); int height=view.getMeasuredHeight();
Run Code Online (Sandbox Code Playgroud)val widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(maxWidth, View.MeasureSpec.AT_MOST) val heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(maxHeight, View.MeasureSpec.AT_MOST) view.measure(widthMeasureSpec, heightMeasureSpec) val width=view.measuredWidth val height=view.measuredHeight
如果你在Kotlin写作,你可以使用下一个函数,它在幕后的工作方式与runJustBeforeBeingDrawn
我写的完全一样:
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
final int newHeight= MeasureSpec.getSize(heightMeasureSpec);
final int newWidth= MeasureSpec.getSize(widthMeasureSpec);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
Run Code Online (Sandbox Code Playgroud)
请注意,您需要将其添加到gradle(通过此处找到):
view.doOnPreDraw { actionToBeTriggered() }
Run Code Online (Sandbox Code Playgroud)Mar*_*k B 19
您是否getWidth()
在视图实际布局在屏幕上之前打电话?
新Android开发人员常犯的一个错误是在其构造函数中使用视图的宽度和高度.当调用视图的构造函数时,Android不知道视图的大小,因此大小设置为零.实际尺寸在布局阶段计算,这在施工后但在绘制任何东西之前发生.您可以使用该
onSizeChanged()
方法在知道值时通知它们,或者您可以稍后使用getWidth()
和getHeight()
方法,例如在onDraw()
方法中.
Nik*_*man 17
基于@ mbaird的建议,我通过继承ImageView
类和重写找到了一个可行的解决方案onLayout()
.然后我创建了一个我的活动实现的观察者接口,并将对它自己的引用传递给了类,这允许它在实际完成大小调整时告诉活动.
我并不是100%确信这是最好的解决方案(因此我没有将此答案标记为正确),但它确实有效,并且根据文档是第一次可以找到视图的实际大小.
gre*_*egm 10
以下是API <11(API 11包含View.OnLayoutChangedListener功能)时通过覆盖视图获取布局的代码:
public class CustomListView extends ListView
{
private OnLayoutChangedListener layoutChangedListener;
public CustomListView(Context context)
{
super(context);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
if (layoutChangedListener != null)
{
layoutChangedListener.onLayout(changed, l, t, r, b);
}
super.onLayout(changed, l, t, r, b);
}
public void setLayoutChangedListener(
OnLayoutChangedListener layoutChangedListener)
{
this.layoutChangedListener = layoutChangedListener;
}
}
public interface OnLayoutChangedListener
{
void onLayout(boolean changed, int l, int t, int r, int b);
}
Run Code Online (Sandbox Code Playgroud)
小智 5
这适用于我onClickListener
:
yourView.postDelayed(new Runnable() {
@Override
public void run() {
yourView.invalidate();
System.out.println("Height yourView: " + yourView.getHeight());
System.out.println("Width yourView: " + yourView.getWidth());
}
}, 1);
Run Code Online (Sandbox Code Playgroud)
使用下面的代码,它给出视图的大小。
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
Log.e("WIDTH",""+view.getWidth());
Log.e("HEIGHT",""+view.getHeight());
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
142219 次 |
最近记录: |