每次用户下拉以刷新显示的列表视图时,我都会尝试使用TextView覆盖操作栏(完全按照Gmail应用或reddit同步应用的方式执行)。我正在使用SwipeRefreshLayout进行刷新,但我认为这无关紧要。我有一个类(HeaderTransformer),它包含TextView并使用WindowManager将textView附加到显示器。 HeaderTransformer类的实例是从片段内调用的(它包含SwipeRefreshLayout和ListView以刷新)。在片段的第一次创建时,TextView叠加层完美地工作。但是,如果我旋转屏幕或以某种方式重新创建片段,WindowManager不会附加TextView并引发BadTokenException。
以下是一些代码:
private HeaderTransformer ht;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_misc, container, false);
View refresh_header = getActivity().getLayoutInflater().inflate(R.layout.swipe_refresh_header_layout, null);
ht = new HeaderTransformer(getActivity(), refresh_header);
}
@Override
public void onResume() {
super.onResume();
getActivity().runOnUiThread(new Runnable(){
@Override
public void run() {
if(!getActivity().isFinishing())
ht.addHeaderViewToActivity(getActivity());
}
});
}
public class HeaderTransformer {
private View mHeaderView;
private TextView mMainTextView;
private Context mContext;
public HeaderTransformer(Context context, View headerView) {
mHeaderView = headerView;
mContext = context;
mMainTextView = (TextView) headerView.findViewById(R.id.ptr_text);
}
public void onReset() {
mMainTextView.setVisibility(View.VISIBLE);
mMainTextView.setText(R.string.pull_to_refresh_label);
}
public void onRefreshStarted() {
mMainTextView.setText(R.string.refreshing_label);
}
public void addHeaderViewToActivity(Activity mActivity) {
Rect mRect = new Rect();
// Get the Display Rect of the Decor View
mActivity.getWindow().getDecorView().getWindowVisibleDisplayFrame(mRect);
// Honour the requested layout params
int width = WindowManager.LayoutParams.MATCH_PARENT;
int height = WindowManager.LayoutParams.WRAP_CONTENT;
ViewGroup.LayoutParams requestedLp = mHeaderView.getLayoutParams();
if (requestedLp != null) {
width = requestedLp.width;
height = requestedLp.height;
}
// Create LayoutParams for adding the View as a panel
WindowManager.LayoutParams wlp = new WindowManager.LayoutParams(width, height,
WindowManager.LayoutParams.TYPE_APPLICATION_PANEL,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE |
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
PixelFormat.TRANSLUCENT);
wlp.x = 0;
wlp.y = mRect.top;
wlp.gravity = Gravity.TOP | Gravity.LEFT;
// Workaround for Issue #182
mHeaderView.setTag(wlp);
try{
mActivity.getWindowManager().addView(mHeaderView, wlp);
}
catch(Exception e){
e.printStackTrace();
}
}
这是堆栈跟踪:
05-14 00:09:03.286: W/System.err(18190): android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
05-14 00:09:03.286: W/System.err(18190): at android.view.ViewRootImpl.setView(ViewRootImpl.java)
05-14 00:09:03.286: W/System.err(18190): at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java)
05-14 00:09:03.286: W/System.err(18190): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java)
05-14 00:09:03.286: W/System.err(18190): at com.faisalalqadi.resume.util.HeaderTransformer.addHeaderViewToActivity(HeaderTransformer.java:72)
05-14 00:09:03.286: W/System.err(18190):at com.faisalalqadi.resume.fragment.MiscellaneousFragment$3.run(MiscellaneousFragment.java:260)
05-14 00:09:03.286: W/System.err(18190): at android.app.Activity.runOnUiThread(Activity.java)
05-14 00:09:03.286: W/System.err(18190): at com.faisalalqadi.resume.fragment.MiscellaneousFragment.onResume(MiscellaneousFragment.java:256)
05-14 00:09:03.296: W/System.err(18190): at android.support.v4.app.Fragment.performResume(Fragment.java:1543)
05-14 00:09:03.296: W/System.err(18190): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:974)
05-14 00:09:03.296: W/System.err(18190): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1115)
05-14 00:09:03.296: W/System.err(18190): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1097)
05-14 00:09:03.296: W/System.err(18190): at android.support.v4.app.FragmentManagerImpl.dispatchResume(FragmentManager.java:1905)
05-14 00:09:03.296: W/System.err(18190): at android.support.v4.app.FragmentActivity.onResumeFragments(FragmentActivity.java:466)
05-14 00:09:03.296: W/System.err(18190): at android.support.v4.app.FragmentActivity.onPostResume(FragmentActivity.java:455)
05-14 00:09:03.296: W/System.err(18190): at android.app.Activity.performResume(Activity.java)
05-14 00:09:03.296: W/System.err(18190): at android.app.ActivityThread.performResumeActivity(ActivityThread.java)
05-14 00:09:03.296: W/System.err(18190): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java)
05-14 00:09:03.296: W/System.err(18190): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java)
05-14 00:09:03.296: W/System.err(18190): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java)
05-14 00:09:03.296: W/System.err(18190): at android.app.ActivityThread.access$900(ActivityThread.java)
05-14 00:09:03.296: W/System.err(18190): at android.app.ActivityThread$H.handleMessage(ActivityThread.java)
05-14 00:09:03.296: W/System.err(18190): at android.os.Handler.dispatchMessage(Handler.java)
05-14 00:09:03.296: W/System.err(18190): at android.os.Looper.loop(Looper.java)
05-14 00:09:03.296: W/System.err(18190): at android.app.ActivityThread.main(ActivityThread.java)
05-14 00:09:03.296: W/System.err(18190): at java.lang.reflect.Method.invokeNative(Native Method)
05-14 00:09:03.296: W/System.err(18190): at java.lang.reflect.Method.invoke(Method.java)
05-14 00:09:03.296: W/System.err(18190): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java)
我一直在寻找任何可以表明与众不同的事情。我所看到的所有资源都说要为Activity.this交换getApplicationContext()。我认为错误的来源是HeaderTransformer持有对方向更改时销毁/删除的活动/视图的引用。我试图删除对HeaderTransformer实例实例持有的视图或活动的任何引用(并将所有函数更改为mHeaderView作为参数(而不是局部变量)。我仍然得到BadTokenException。
有谁知道造成这种情况的原因是什么?
答案 0 :(得分:0)
因此请保存您的实例,并在旋转屏幕时获取已保存的实例并传递给转换类。