I have a simple project with a TabLayout in the MainActivity with 3 tabs, each tab has a SwipeRefreshLayout.
If I pull to refresh the first tab, then move to the third tab while the first tab is still refreshing, when I go back to the first tab it looks like there is a view over the first tab with a snapshot of the state of the tab before I moved to the third tab. I can scroll the items and use the tab normally.
Please see the images below and my code below.
I can dismiss the "refresh indicator" calling swipeLayout.setRefreshing(false); in onPause of ContentFragment, but the overlay view stays there.
public class MainActivity extends AppCompatActivity {
ViewPager viewPager;
TabLayout tabLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.viewpager);
tabLayout = (TabLayout) findViewById(R.id.tablayout);
PagerAdapter pageAdapter = new PagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(pageAdapter);
tabLayout.setupWithViewPager(viewPager);
}
static class PagerAdapter extends FragmentPagerAdapter {
private final int TAB_COUNT = 3;
public PagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return new ContentFragment();
}
@Override
public int getCount() {
return TAB_COUNT;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Tab 1";
case 1:
return "Tab 2";
case 2:
return "Tab 3";
default:
throw new IndexOutOfBoundsException("Invalid tab position");
}
}
}
}
public class ContentFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
RecyclerView recyclerView;
private RecyclerAdapter adapter;
SwipeRefreshLayout swipeLayout;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_content, container, false);
adapter = new RecyclerAdapter();
recyclerView = (RecyclerView) view.findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter);
swipeLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_container);
swipeLayout.setOnRefreshListener(this);
swipeLayout.setColorSchemeColors(Color.RED, Color.GREEN, Color.BLUE, Color.CYAN);
return view;
}
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override public void run() {
swipeLayout.setRefreshing(false);
}
}, 5000);
}
private class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_item, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.tvTitle.setText("Item #" + position);
}
@Override
public int getItemCount() {
return 50;
}
class ViewHolder extends RecyclerView.ViewHolder {
private final TextView tvTitle;
public ViewHolder(View itemView) {
super(itemView);
tvTitle = (TextView) itemView.findViewById(R.id.tvTitle);
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.TabLayout
android:id="@+id/tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
app:tabGravity="fill" />
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_below="@id/tablayout"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_container"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.v4.widget.SwipeRefreshLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="100dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:id="@+id/tvTitle" />
</RelativeLayout>
The solution I've found was to remove all the SwipeRefreshLayout views when the fragment view gets destroyed:
@Override
public void onDestroyView() {
swipeLayout.removeAllViews();
super.onDestroyView();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With