我有一个包含2个片段的活动:A和B.目前A已添加到活动中。单击按钮后:
ft.replace(containerId, B, tag);
ft.addToBackStack("A");
ft.commit();
显示B,正常删除A.
拉动以刷新并在加载进度时按回:
// this is implementation in OnBackPressed()
....
int backStackEntryCount = fm.getBackStackEntryCount();
if (backStackEntryCount > 0) {
fm.popBackStackImmediate();
}
....
问题是片段B仍显示在屏幕上(空白)并重叠片段A,如果再次返回应用将退出。关于B的一些信息:
这是B源代码:
public class B extends MyFragment {
protected View view;
protected ListView listView;
protected ImageView progress;
protected TextView notifText;
protected LayoutInflater inflater;
protected PTRBaseAdapter adapter;
protected SwipeRefreshLayout mSwipeRefreshLayout;
protected String emptyText;
protected boolean fromRest;
protected int loads = 0;
protected float mPreviousX = 0;
protected float mPreviousY = 0;
protected void doRefresh(boolean fromRest) {
if (!isAdded()) return;
notifText.setVisibility(View.GONE);
fetchFromDatabase();
if (fromRest) {
refresh();
}
}
private void fetchFromDatabase() {
/* fetch data from db here and got the "list" */
adapter = new EventAdapter(list);
listView.setAdapter(adapter);
loads++;
if (adapter.getCount() == 0) {
notifText.setText(R.string.NoEvents);
notifText.setVisibility(View.VISIBLE);
} else {
notifText.setVisibility(View.GONE);
}
}
private void refresh() {
if (!isAdded()) return;
GenericManager.getInstance().fetchEvents(mContext, new OnFinished() {
@Override
public void onFinished(boolean result) {
if (result) {
if (isAdded() && getActivity() != null) {
fetchFromDatabase();
adapter.notifyDataSetChanged();
listView.invalidate();
mSwipeRefreshLayout.setRefreshing(false);
}
}
}
});
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.ptr_list, container, false);
this.inflater = inflater;
mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipeRefresh);
mSwipeRefreshLayout.setColorSchemeResources(R.color.md_material_blue_600);
listView = (ListView) view.findViewById(R.id.pull_refresh_list);
listView.setOnItemClickListener(mOnItemClickListener);
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
boolean enable = false;
if (listView != null && listView.getChildCount() > 0) {
boolean firstItemVisible = (listView.getFirstVisiblePosition() == 0);
boolean topOfFirstItemVisible = (listView.getChildAt(0).getTop() == 0);
enable = firstItemVisible && topOfFirstItemVisible;
}
mSwipeRefreshLayout.setEnabled(enable);
}
});
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
refresh();
}
});
progress = (ImageView) view.findViewById(R.id.progress);
progress.setVisibility(View.GONE);
notifText = (TextView) view.findViewById(R.id.notifText);
notifText.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getActionMasked();
float x = event.getX();
float y = event.getY();
switch (action) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
float dx = x - mPreviousX;
float dy = y - mPreviousY;
if (dy > 300) {
mSwipeRefreshLayout.post(new Runnable() {
@Override
public void run() {
mSwipeRefreshLayout.setRefreshing(true);
doRefresh(fromRest);
}
});
}
break;
case MotionEvent.ACTION_UP:
break;
}
mPreviousX = x;
mPreviousY = y;
return true;
}
});
setTopbarTitle();
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
doRefresh(true);
}
@Override
public void setTopbarTitle() {
topbar = (TopBar) getActivity().findViewById(R.id.topbar);
topbarTitle = R.string.Events;
((MyActivity) getActivity()).setTabBarVisibility(false);
topbar.setVisibility(View.VISIBLE);
super.setTopbarTitle();
}
@Override
public void onResume() {
doRefresh(false);
super.onResume();
}
/* The adapter for list but I think it does not affect anything */
在MyFragment中,我覆盖了onDettach:
@Override
public void onDetach() {
super.onDetach();
try {
Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");
childFragmentManager.setAccessible(true);
childFragmentManager.set(this, null);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
片段B的布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/swipeRefresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MyActivity">
<RelativeLayout
style="@style/viewstyle">
<com.myapp.viewcomp.TopBar
android:id="@+id/topbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone" />
<ImageView
android:id="@+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@drawable/progress" />
<ListView
android:id="@+id/pull_refresh_list"
style="@style/ptr_style"
android:background="@color/white"
android:divider="@color/white"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/topbar" />
<TextView
android:id="@+id/notifText"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/progress"
android:layout_centerInParent="true"
android:gravity="center"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:visibility="gone" />
</RelativeLayout>
</android.support.v4.widget.SwipeRefreshLayout>
我不知道为什么片段B进入onDetach但它仍然在屏幕上冻结,我可以在底部看到一点A片段。任何建议都非常感激,我几天坚持这件事:(
我认为问题在于B片段的实现,但我无法弄明白,不确定问题是否来自SwipeRefreshLayout ......
答案 0 :(得分:1)
我自己用
解决了问题mSwipeRefreshLayout.destroyDrawingCache();