RecyclerView问题与scrollToPosition

时间:2018-01-16 14:51:23

标签: android android-recyclerview

我有一个带有日历和微调器的片段来过滤数据。

在日历下,有一个回收站视图,可在日历中显示通知。

我显示当前月份的所有通知,并将recyclerview滚动到今天的通知,显示的顶部项目是今天的第一个。

通过通知类型的微调器过滤器。 (全部,通用,任务,考试,缺席)

正常工作但当我选择任何内容并再次选择ALL时,recyclerview会滚动到我使用rvNotifications.scrollToPosition(index)设置的位置,但该项目位于显示项目的底部,而不是顶部。

有人可以帮助我吗?

public class CalendarFragment extends Fragment implements NotificationsAdapter.ListItemClickListener {

    private ArrayList<String> types;

    private ArrayList<SchoolNotification> notifications = new ArrayList();
    private ArrayList<SchoolNotification> notifications_month = new ArrayList();
    private ArrayList<SchoolNotification> notifications_generic = new ArrayList();
    private ArrayList<SchoolNotification> notifications_task = new ArrayList();
    private ArrayList<SchoolNotification> notifications_exam = new ArrayList();
    private ArrayList<SchoolNotification> notifications_absence = new ArrayList();
    private ArrayList<SchoolNotification> notifications_shown = new ArrayList();

    private List<CalendarDay> generic_events_list = new ArrayList();
    private List<CalendarDay> task_events_list = new ArrayList();
    private List<CalendarDay> exam_events_list = new ArrayList();
    private List<CalendarDay> absence_events_list = new ArrayList();

    private Spinner sp_types;
    private NotificationsAdapter mAdapter;
    private RecyclerView rvNotifications;
    private MaterialCalendarView calendar_mv;

    private CalendarDay selectedDate;

    private Integer index = 0;
    private Integer indexOrigin = 0;
    private Integer indexGeneric = 0;
    private Integer indexTask = 0;
    private Integer indexExam = 0;
    private Integer indexAbsence = 0;


    public static CalendarFragment newInstance() {
        CalendarFragment fragment = new CalendarFragment();
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        notifications = getArguments().getParcelableArrayList("notifications");

        View view = inflater.inflate(R.layout.fragment_calendar, container, false);

        view = initialize(view);

        return view;
    }

    private View initialize(View view) {

        rvNotifications = (RecyclerView) view.findViewById(R.id.rv_notifications);
        LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
        rvNotifications.setLayoutManager(layoutManager);
        rvNotifications.setHasFixedSize(true);

        calendar_mv = (MaterialCalendarView) view.findViewById(R.id.calendar_view);
        sp_types = (Spinner) view.findViewById(R.id.sp_event_type);
        types = new ArrayList<>(Arrays.asList(getActivity().getResources().getString(R.string.all_events),
                getActivity().getResources().getString(R.string.generic), getActivity().getResources().getString(R.string.task),
                getActivity().getResources().getString(R.string.exam), getActivity().getResources().getString(R.string.abscence)));


        NotificationsSelectedMonth();

        classifyNotifications();

        mAdapter = new NotificationsAdapter(notifications_shown, getResources(), CalendarFragment.this);
        rvNotifications.setAdapter(mAdapter);
        rvNotifications.scrollToPosition(index);

        indexOrigin = index;

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), R.layout.spinner_item, types);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        sp_types.setAdapter(adapter);

        List<CalendarDay> today = new ArrayList<>();
        Calendar today_cal = Calendar.getInstance();
        today_cal.set(Calendar.HOUR_OF_DAY, 0);
        CalendarDay calendarDay = CalendarDay.from(today_cal);
        today.add(calendarDay);

        calendar_mv.addDecorator(new DateDecorator(getActivity(), getColor(getActivity(), R.color.primary_darker), generic_events_list));
        calendar_mv.addDecorator(new DateDecorator(getActivity(), getColor(getActivity(), R.color.green), task_events_list));
        calendar_mv.addDecorator(new DateDecorator(getActivity(), getColor(getActivity(), R.color.red), exam_events_list));
        calendar_mv.addDecorator(new DateDecorator(getActivity(), getColor(getActivity(), R.color.black), absence_events_list));

        setListeners();

        return view;
    }

    private void setListeners() {

        sp_types.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
                calendar_mv.removeDecorators();

                List<CalendarDay> today = new ArrayList<>();
                Calendar today_cal = Calendar.getInstance();
                today_cal.set(Calendar.HOUR_OF_DAY, 0);
                CalendarDay calendarDay = CalendarDay.from(today_cal);
                today.add(calendarDay);

                calendar_mv.addDecorator(new DateDecorator(getActivity(), today, true));
                switch (position) {
                    case 0:
                        calendar_mv.addDecorator(new DateDecorator(getActivity(), getColor(getActivity(), R.color.primary_darker), generic_events_list));
                        calendar_mv.addDecorator(new DateDecorator(getActivity(), getColor(getActivity(), R.color.green), task_events_list));
                        calendar_mv.addDecorator(new DateDecorator(getActivity(), getColor(getActivity(), R.color.red), exam_events_list));
                        calendar_mv.addDecorator(new DateDecorator(getActivity(), getColor(getActivity(), R.color.black), absence_events_list));
                        mAdapter = new NotificationsAdapter(notifications_shown, getResources(), CalendarFragment.this);
                        rvNotifications.swapAdapter(mAdapter, false);
                        rvNotifications.scrollToPosition(index);
                        break;
                    case 1:
                        calendar_mv.addDecorator(new DateDecorator(getActivity(), getColor(getActivity(), R.color.primary_darker), generic_events_list));
                        mAdapter = new NotificationsAdapter(notifications_generic, getResources(), CalendarFragment.this);
                        rvNotifications.swapAdapter(mAdapter, false);
                        rvNotifications.scrollToPosition(indexGeneric);
                        break;
                    case 2:
                        calendar_mv.addDecorator(new DateDecorator(getActivity(), getColor(getActivity(), R.color.green), task_events_list));
                        mAdapter = new NotificationsAdapter(notifications_task, getResources(), CalendarFragment.this);
                        rvNotifications.swapAdapter(mAdapter, false);
                        rvNotifications.scrollToPosition(indexTask);
                        break;
                    case 3:
                        calendar_mv.addDecorator(new DateDecorator(getActivity(), getColor(getActivity(), R.color.red), exam_events_list));
                        mAdapter = new NotificationsAdapter(notifications_exam, getResources(), CalendarFragment.this);
                        rvNotifications.setAdapter(mAdapter);
                        rvNotifications.scrollToPosition(indexExam);
                        break;
                    case 4:
                        calendar_mv.addDecorator(new DateDecorator(getActivity(), getColor(getActivity(), R.color.black), absence_events_list));
                        mAdapter = new NotificationsAdapter(notifications_absence, getResources(), CalendarFragment.this);
                        rvNotifications.swapAdapter(mAdapter, false);
                        rvNotifications.scrollToPosition(indexAbsence);
                        break;
                }

            }

            @Override
            public void onNothingSelected(AdapterView<?> parentView) {
            }

        });

    @Override
    public void onListItemClick(SchoolNotification notification) {

        NotificationDetailFragment detailFragment = NotificationDetailFragment.newInstance();
        Bundle bundle = new Bundle();
        bundle.putParcelable("notification", notification);
        detailFragment.setArguments(bundle);

        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.frame_layout, detailFragment);
        fragmentTransaction.addToBackStack(null);
        fragmentTransaction.commit();
    }

    private void NotificationsSelectedMonth() {
        SchoolNotification notif;
        Date notif_date;
        Calendar cal = Calendar.getInstance();
        notifications_month = new ArrayList<>();
        for (int i = 0; i < notifications.size(); i++) {
            notif = notifications.get(i);

            notif_date = notif.getDate();
            cal.setTime(notif_date);

            if (((Integer) cal.get(Calendar.MONTH)) == calendar_mv.getCurrentDate().getMonth()) {
                notifications_month.add(notif);
            }
        }
    }

    private void classifyNotifications() {

        initializeCalendarsDays();
        initializeNotificationCollections();

        Calendar calendar = Calendar.getInstance();
        Calendar cal = Calendar.getInstance();
        CalendarDay calendarDay;

        SchoolNotification notif;
        Date notif_date;

        Calendar auxcal = Calendar.getInstance();
        auxcal.add(Calendar.DATE, + 1);
        Date tomorrow = cal.getTime();

        Boolean setIndex = false;
        Boolean setIndexG = false;
        Boolean setIndexT = false;
        Boolean setIndexE = false;
        Boolean setIndexA = false;


        for (int i = 0; i < notifications_month.size(); i++) {
            notif = notifications_month.get(i);

            notif_date = notif.getDate();

            if (notif_date.before(tomorrow) && !setIndex) {
                index = i;
                setIndex = true;
            }

            cal.setTime(notif_date);
            calendar.set(cal.get(Calendar.YEAR),
                    cal.get(Calendar.MONTH), //months starts from 0
                    cal.get(Calendar.DAY_OF_MONTH));
            calendarDay = CalendarDay.from(calendar);

            if (selectedDate == null || (selectedDate.getYear() == calendarDay.getYear() &&
                    selectedDate.getMonth() == calendarDay.getMonth() &&
                    selectedDate.getDay() == calendarDay.getDay())) {
                notifications_shown.add(notif);
            }

            switch (notif.getType()) {
                case StaticConfiguration.GENERIC:
//                    if (maxDayGeneric.compareTo(dayToday) > 0 || dayToday.compareTo(notif_date) > 0) {
//                        indexGeneric = notifications_generic.size();
//                    }
                    if (notif_date.before(tomorrow) && !setIndexG) {
                        indexGeneric = notifications_generic.size();
                        setIndexG = true;
                    }
                    generic_events_list.add(calendarDay);
                    if (selectedDate == null || (selectedDate.getYear() == calendarDay.getYear() &&
                            selectedDate.getMonth() == calendarDay.getMonth() &&
                            selectedDate.getDay() == calendarDay.getDay())) {
                        notifications_generic.add(notif);
                    }
                    break;
                case StaticConfiguration.TASK:
//                    if (maxDayTask.compareTo(dayToday) > 0 || dayToday.compareTo(notif_date) > 0) {
//                        indexTask = notifications_task.size();
//                    }
                    if (notif_date.before(tomorrow) && !setIndexT) {
                        indexTask = notifications_task.size();
                        setIndexT = true;
                    }
                    task_events_list.add(calendarDay);
                    if (selectedDate == null || (selectedDate.getYear() == calendarDay.getYear() &&
                            selectedDate.getMonth() == calendarDay.getMonth() &&
                            selectedDate.getDay() == calendarDay.getDay())) {
                        notifications_task.add(notif);
                    }
                    break;
                case StaticConfiguration.EXAM:
//                    if (maxDayExam.compareTo(dayToday) > 0 || dayToday.compareTo(notif_date) > 0) {
//                        indexExam = notifications_exam.size();
//                    }
                    if (notif_date.before(tomorrow) && !setIndexE) {
                        indexExam = notifications_exam.size();
                        setIndexE = true;
                    }
                    exam_events_list.add(calendarDay);
                    if (selectedDate == null || (selectedDate.getYear() == calendarDay.getYear() &&
                            selectedDate.getMonth() == calendarDay.getMonth() &&
                            selectedDate.getDay() == calendarDay.getDay())) {
                        notifications_exam.add(notif);
                    }
                    break;
                case StaticConfiguration.ABSENCE:
//                    if (maxDayAbsence.compareTo(dayToday) > 0 || dayToday.compareTo(notif_date) > 0) {
//                        indexAbsence = notifications_absence.size();
//                    }
                    if (notif_date.before(tomorrow) && !setIndexA) {
                        indexAbsence = notifications_absence.size();
                        setIndexA = true;
                    }
                    absence_events_list.add(calendarDay);
                    if (selectedDate == null || (selectedDate.getYear() == calendarDay.getYear() &&
                            selectedDate.getMonth() == calendarDay.getMonth() &&
                            selectedDate.getDay() == calendarDay.getDay())) {
                        notifications_absence.add(notif);
                    }
                    break;
            }
        }
        calendar_mv.addDecorator(new DateDecorator(getActivity(), getColor(getActivity(), R.color.primary_darker), generic_events_list));
        calendar_mv.addDecorator(new DateDecorator(getActivity(), getColor(getActivity(), R.color.green), task_events_list));
        calendar_mv.addDecorator(new DateDecorator(getActivity(), getColor(getActivity(), R.color.red), exam_events_list));
        calendar_mv.addDecorator(new DateDecorator(getActivity(), getColor(getActivity(), R.color.black), absence_events_list));
    }

    private void initializeCalendarsDays() {
        generic_events_list.clear();
        task_events_list.clear();
        exam_events_list.clear();
        absence_events_list.clear();
    }

    private void initializeNotificationCollections() {
        notifications_shown.clear();
        notifications_generic.clear();
        notifications_task.clear();
        notifications_exam.clear();
        notifications_absence.clear();
    }
}

2 个答案:

答案 0 :(得分:1)

您应该为您的回收商视图设置偏移量,如:

layoutManager.scrollToPositionWithOffset(index, 0);

答案 1 :(得分:0)

  

rvNotifications.setAdapter(mAdapter);

而不是

  

rvNotifications.swapAdapter(mAdapter,false);

它有效。但我不知道这是否是一个有效的答案