我无法找到一种方法来获取包含任意 View
v 的 Window
引用。我发现 getWindowToken,但我不知道如何使用它?有人知道吗?
此外,有人知道为什么它返回一个 IBinder
而不是一个 Window
吗?
我无法找到一种方法来获取包含任意 View
v 的 Window
引用。我发现 getWindowToken,但我不知道如何使用它?有人知道吗?
此外,有人知道为什么它返回一个 IBinder
而不是一个 Window
吗?
嗯...由于所有视图都有一个创建它们的活动(Context
)的引用,因此您可以使用该Context
来获取窗口的引用。让我向您展示我几分钟前编写的这个示例:
// main activity
import android.app.Activity;
import android.os.Bundle;
public class GetWindow extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyView view = new MyView(this);
view.changeSomethingInWindow(); // keep an eye on this method
setContentView(view);
}
}
然后,在您的视图中可以这样做:
// your view :D
import android.app.Activity;
import android.content.Context;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
public class MyView extends View{
public MyView(Context context) {
super(context);
}
@Nullable
private Activity getActivity() {
if (context == null) return null;
if (context instanceof Activity) return (Activity) context;
if (context instanceof ContextWrapper) return getActivity(((ContextWrapper)context).getBaseContext());
return null;
}
public void changeSomethingInWindow(){
// get a reference of the activity
Activity parent = getActivity();
if(parent == null) return;
// using the activity, get Window reference
Window window = parent.getWindow();
// using the reference of the window, do whatever you want :D
window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
}
在这种情况下,我将窗口显示模式更改为全屏。希望这可以帮助你。如果你遇到问题,请告诉我。
我知道这是一个老问题,但在搜索谷歌时仍然会重定向到此处,由于上面的答案不完全有效,这就是我所做的更改视图内部窗口标志的方法。(上面的代码基本上做了同样的事情,但它假设所有视图都附加到活动中。)
它不会获取实际的 Window
实例,而是返回属性,这允许更新标志,或者在此时窗口具有的任何东西。
装饰视图或附加到窗口的顶部视图应该具有 WindowManager.LayoutParams
的实例,并且您应该能够设置所需的标志,因为参数具有 WindowManager.LayoutParams.flags
整数值。以下是获取窗口参数的方法。
private WindowManager.LayoutParams tryGetWindowParams()
{
View view = this;
if (view.getLayoutParams() instanceof WindowManager.LayoutParams)
return (WindowManager.LayoutParams) view.getLayoutParams();
while (view.getParent() instanceof View)
{
view = (View) view.getParent();
if (view.getLayoutParams() instanceof WindowManager.LayoutParams)
return (WindowManager.LayoutParams) view.getLayoutParams();
}
return null;
}
之后,你应该能够只需执行以下操作(示例将使用FLAG_NOT_TOUCHABLE标志,但可以根据需要使用任何其他窗口标志)。
private boolean setWindowNotTouchable()
{
WindowManager.LayoutParams windowParams = tryGetWindowParams();
if (windowParams != null)
{
if ((windowParams.flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) == 0)
{
windowParams.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
requestLayout();
}
return true;
}
return false;
}
private boolean setWindowTouchable()
{
WindowManager.LayoutParams windowParams = tryGetWindowParams();
if (windowParams != null)
{
if ((windowParams.flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0)
{
windowParams.flags &= ~WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
requestLayout();
}
return true;
}
return false;
}
View.requestLayout()
,因为窗口参数需要更新。
IBinder
而不是Window
,你有什么想法吗? - Casebash