Android TabLayout 有两个选项卡和一个 recyclerview 在切换时滚动到顶部

标签 android android-fragments android-recyclerview

我有一个带有 TabLayout 的 Activity 和一个包含两个选项卡的 Viewpager。这些选项卡是一个重复使用的 fragment ,其中包含一个 Recyclerview。所以每个 Fragment/Tab 都包含一个带有一堆项目的 recyclerview。

在这些选项卡之间切换时,当我返回到上一个选项卡时,滚动状态不会保留。

我错过了什么?

Activity :

public class EventsActivity extends AbstractTracActivity implements OnRowClickListener {

    @BindView(R.id.toolbar)
    Toolbar toolbar;

    @BindView(R.id.tabs)
    TabLayout tabLayout;

    @BindView(R.id.viewpager)
    ViewPager viewPager;

    private final String TAG = EventsActivity.class.getSimpleName();

    private static Context context;
    private SearchView searchView;
    private static EventListFragment eventsFragment, clubsFragment;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        setTheme(R.style.TracTracAppTheme);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.events);
        ButterKnife.bind(this);

        context = this;

        setSupportActionBar(toolbar);
        if (getSupportActionBar() != null) {
            getSupportActionBar().setLogo(R.drawable.tractrac_logo);
            getSupportActionBar().setDisplayShowTitleEnabled(false);
        }

        eventsFragment = EventListFragment.newInstance(EventListFragment.ListType.EVENTS);
        clubsFragment = EventListFragment.newInstance(EventListFragment.ListType.CLUBS);

        TabLayout.Tab events = tabLayout.newTab();
        TabLayout.Tab clubs = tabLayout.newTab();

        tabLayout.addTab(events, 0);
        tabLayout.addTab(clubs, 1);

        tabLayout.setTabTextColors(ContextCompat.getColorStateList(this, R.color.accent));
        tabLayout.setSelectedTabIndicatorColor(ContextCompat.getColor(this, R.color.accent));

        ViewPagerAdapter adapter = new ViewPagerAdapter (getSupportFragmentManager());
        viewPager.setAdapter(adapter);
        tabLayout.setupWithViewPager(viewPager);

        viewPager.setOffscreenPageLimit(2);
        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { }

            @Override
            public void onPageSelected(int position) { }

            @Override
            public void onPageScrollStateChanged(int state) {
                searchView.setQuery("", true);
                searchView.clearFocus();
                searchView.setIconified(true);
                eventsFragment.filterList(null);
                clubsFragment.filterList(null);
            }
        });
    }

    ...

    public static class ViewPagerAdapter extends FragmentPagerAdapter {

        public ViewPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            switch (position) {
                case 1:
                    return clubsFragment;
                default:
                    return eventsFragment;
            }
        }

        @Override
        public int getCount() {
            return 2;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            switch (position) {
                case 1:
                    return context.getResources().getString(R.string.section_clubs);
                default:
                    return context.getResources().getString(R.string.section_events);
            }
        }
    }
}

fragment :

public class EventListFragment extends Fragment implements EventsFragmentPresenter.ViewInterface {

    enum ListType { EVENTS, CLUBS }

    private EventsFragmentPresenter presenter;
    private ListType listType;
    private List<Event> events;
    private RecyclerView recyclerView;

    public static EventListFragment newInstance(ListType listType) {
        EventListFragment f = new EventListFragment();
        Bundle args = new Bundle();
        args.putSerializable("listType", listType);
        f.setArguments(args);
        return f;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(com.tractrac.androidlib.R.layout.base_list_fragment, container, false);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        recyclerView = (RecyclerView) view.findViewById(com.tractrac.androidlib.R.id.recycler_view);

        switch (getListType()) {
            case EVENTS:
                getPresenter().getEvents();
                break;
            case CLUBS:
                getPresenter().getClubEvents();
                break;
        }
    }

    private EventsFragmentPresenter getPresenter() {
        if (presenter == null) {
            presenter = new EventsFragmentPresenter();
            presenter.initialize(this);
        }
        return presenter;
    }

    private ListType getListType() {
        if (listType == null) {
            listType = (ListType) getArguments().getSerializable("listType");
        }
        return listType;
    }

    @Override
    public void listReady(List<Event> events) {
        EventsRecyclerAdapter adapter = new EventsRecyclerAdapter(events, (EventsActivity) getActivity());
        RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getContext());
        recyclerView.setLayoutManager(mLayoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.setAdapter(adapter);

        if (getListType() == ListType.EVENTS) {
            mLayoutManager.scrollToPosition(getPresenter().getCurrentDayEventIndex(events));
        }
        this.events = events;
        ((EventsActivity) getActivity()).hideSpinner();
    }

    public void filterList(String filterBy) {
        if (TextUtils.isEmpty(filterBy)) {
            EventsRecyclerAdapter adapter = new EventsRecyclerAdapter(events, (EventsActivity) getActivity());
            recyclerView.setAdapter(adapter);
            return;
        }

        List<Event> filteredEvents = new ArrayList<>();
        for (Event event : events) {
            if (event.getName().toLowerCase().contains(filterBy) || event.getLocation().toLowerCase().contains(filterBy))
                filteredEvents.add(event);
        }
        EventsRecyclerAdapter adapter = new EventsRecyclerAdapter(filteredEvents, (EventsActivity) getActivity());
        recyclerView.setAdapter(adapter);
    }
}

最佳答案

onPageScrollStateChanged 中,您正在调用 filterList,您每次都在其中创建一个新的 EventsRecyclerAdapter,这是滚动状态被重置的原因。

您应该为您的 RecyclerView 设置一次适配器,然后调用 notify 方法。

关于Android TabLayout 有两个选项卡和一个 recyclerview 在切换时滚动到顶部,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38991118/

相关文章:

c# - Xamarin Android 6.0 Java.Lang.NoSuchMethodError 与 View.SetText

java - android - 回收适配器未出现在 View 寻呼机中

java - 耳机插孔监听器 Android

java - 变量的值与分配的值不同

Android FragmentTransaction.addToBackStack 混淆

android - RecyclerView 在手动和通过 DiffUtil 通知更改时会感到困惑

java - 在某些卡片 android 中,recyclerview 中的删除按钮位置不正确

android - 奇怪的 RecyclerView 复选框 onCheckChanged 行为

android - 使用 ReactNative 构建的 APK 无法替换为使用 Android Studio 构建的 APK

java - 在 Libgdx 中创建水