Android - Recyclerview适配器内容未在活动重新创建时刷新

时间:2016-07-16 08:22:15

标签: java android android-recyclerview

我正在使用自定义cursoradapter类的Recyclerview。适配器包含onClickListener,因此当用户长按一行时,用户将获得一个contextMenu,要求从recyclerview中删除所单击的行。

一切都按预期工作,但是当方向发生变化或者由于onResume()中的破坏(由于缺乏或RAM或其他)而重建活动时,再循环视图不会在长时间点击时刷新,但适配器内容已正确更改。

请注意changeCursor()来电notifyDataSetChanged()。一切正常,除了方向改变或活动娱乐。光标数据和适配器都会更改,但旧数据仍然可见。 (注意:仅当Android系统重新创建活动时)可能是什么问题?

这是我的适配器类:

public class ScheduleAdapter extends CursorRecyclerViewAdapter<ScheduleAdapter.ViewHolder> {

    private static Context context;
    private int position;

    public ScheduleAdapter(Context context, Cursor cursor) {
        super(cursor);
        ScheduleAdapter.context = context;
    }

    @SuppressLint("SimpleDateFormat")
    @Override
    public void onBindViewHolder(final ViewHolder viewHolder, final Cursor cursor) {
        TextView lessonName = viewHolder.lessonName;
        final TextView lessonTime = viewHolder.lessonTime;
        TextView lessonRoom = viewHolder.lessonRoom;
        TextView lessonComponent = viewHolder.lessonComponent;

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmm");
        long databaseDateStart = Long.parseLong(cursor.getString(2).replaceAll("-", "") + cursor.getString(3).replaceAll(":", ""));
        long databaseDateEnd = Long.parseLong(cursor.getString(2).replaceAll("-", "") + cursor.getString(4).replaceAll(":", ""));
        long currentDate = Long.parseLong(simpleDateFormat.format(new Date()));

        lessonName.setText(cursor.getString(5));
        lessonRoom.setText(cursor.getString(6));
        lessonComponent.setText(cursor.getString(7));

        if (databaseDateStart <= currentDate && databaseDateEnd >= currentDate) {
            lessonTime.setTextColor(ContextCompat.getColor(context, R.color.colorAccent));
            lessonTime.setText(ApplicationLoader.applicationContext.getResources().getString(R.string.lesson_started));
            viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (!lessonTime.getText().toString().equals(ApplicationLoader.applicationContext.getResources().getString(R.string.lesson_started))) {
                        TranslateAnimation animation = new TranslateAnimation(
                                Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
                                Animation.RELATIVE_TO_SELF, -1.0f, Animation.RELATIVE_TO_SELF, 0.0f
                        );
                        animation.setDuration(100);
                        lessonTime.setAnimation(animation);
                        lessonTime.setTextColor(ContextCompat.getColor(context, R.color.colorAccent));
                        lessonTime.setText(ApplicationLoader.applicationContext.getResources().getString(R.string.lesson_started));
                    } else {
                        TranslateAnimation animation = new TranslateAnimation(
                                Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
                                Animation.RELATIVE_TO_SELF, 1.0f, Animation.RELATIVE_TO_SELF, 0.0f
                        );
                        animation.setDuration(100);
                        lessonTime.setAnimation(animation);
                        String lessonTimes = cursor.getString(3) + " - " + cursor.getString(4);
                        lessonTime.setTextColor(ContextCompat.getColor(context, R.color.colorSecondaryText));
                        lessonTime.setText(lessonTimes);
                    }
                }
            });
        } else if (databaseDateEnd < currentDate) {
            lessonTime.setTextColor(ContextCompat.getColor(context, R.color.colorAccent));
            lessonTime.setText(ApplicationLoader.applicationContext.getResources().getString(R.string.finished));
            viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (!lessonTime.getText().toString().equals(ApplicationLoader.applicationContext.getResources().getString(R.string.finished))) {
                        TranslateAnimation animation = new TranslateAnimation(
                                Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
                                Animation.RELATIVE_TO_SELF, -1.0f, Animation.RELATIVE_TO_SELF, 0.0f
                        );
                        animation.setDuration(100);
                        lessonTime.setAnimation(animation);
                        lessonTime.setTextColor(ContextCompat.getColor(context, R.color.colorAccent));
                        lessonTime.setText(ApplicationLoader.applicationContext.getResources().getString(R.string.finished));
                    } else {
                        TranslateAnimation animation = new TranslateAnimation(
                                Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
                                Animation.RELATIVE_TO_SELF, 1.0f, Animation.RELATIVE_TO_SELF, 0.0f
                        );
                        animation.setDuration(100);
                        lessonTime.setAnimation(animation);
                        String lessonTimes = cursor.getString(3) + " - " + cursor.getString(4);
                        lessonTime.setTextColor(ContextCompat.getColor(context, R.color.colorSecondaryText));
                        lessonTime.setText(lessonTimes);
                    }
                }
            });
        } else {
            String lessonTimes = cursor.getString(3) + " - " + cursor.getString(4);
            lessonTime.setTextColor(ContextCompat.getColor(context, R.color.colorSecondaryText));
            lessonTime.setText(lessonTimes);
            viewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    setPosition(viewHolder.getAdapterPosition());
                    return false;
                }
            });
        }
    }

    @Override
    public void onViewRecycled(ViewHolder holder) {
        holder.itemView.setOnLongClickListener(null);
        super.onViewRecycled(holder);
    }

    /**
     * Gets the row id in SQLite based on the adapter's position.
     *
     * @return the id
     */
    public long getLessonId() {
        return super.getItemId(position);
    }

    private void setPosition(int position) {
        this.position = position;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(context).
                inflate(R.layout.schedule_adapter_item, parent, false);
        return new ViewHolder(itemView);
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {

        final TextView lessonName;
        final TextView lessonTime;
        final TextView lessonRoom;
        final TextView lessonComponent;

        public ViewHolder(View view) {
            super(view);
            lessonName = (TextView) view.findViewById(R.id.schedule_list_row_name);
            lessonTime = (TextView) view.findViewById(R.id.schedule_list_row_time);
            lessonRoom = (TextView) view.findViewById(R.id.schedule_list_row_room);
            lessonComponent = (TextView) view.findViewById(R.id.schedule_list_row_component);
        }
    }
}

这里是我的片段:

public class ScheduleFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {

    private static String componentId;
    private static int type;
    private Date date;
    private ScheduleAdapter adapter;
    private DateFormat simpleDateFormat;
    private SwipeRefreshLayout swipeRefreshLayout;
    private long onLongClickId;
    private TextView emptyTextView;
    private ProgressBar spinner;
    private RecyclerView recyclerView;

    @SuppressLint("SimpleDateFormat")
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        componentId = getArguments().getString("componentId");
        type = getArguments().getInt("type");
        date = (Date) getArguments().getSerializable("date");
        simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        menu.add(0, 0, 0, getResources().getString(R.string.hide_lesson));
        menu.add(0, 1, 1, getResources().getString(R.string.save_lesson));
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        if (getUserVisibleHint() && adapter != null) {
            onLongClickId = adapter.getLessonId();
            if (item.getItemId() == 0) {
                showPromptDialog();
                return true;
            }
            if (item.getItemId() == 1) {
                Cursor cursor = ApplicationLoader.scheduleDatabase.getSingleLesson(onLongClickId);
                if (cursor.moveToFirst()) {
                    String[] startTimeStrings = cursor.getString(0).split(":");
                    String[] endTimeStrings = cursor.getString(1).split(":");

                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(date);

                    calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(startTimeStrings[0]));
                    calendar.set(Calendar.MINUTE, Integer.parseInt(startTimeStrings[1]));

                    Intent intent = new Intent(Intent.ACTION_EDIT);
                    intent.setType("vnd.android.cursor.item/event");
                    intent.putExtra("beginTime", calendar.getTimeInMillis());
                    intent.putExtra("allDay", false);

                    calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(endTimeStrings[0]));
                    calendar.set(Calendar.MINUTE, Integer.parseInt(endTimeStrings[1]));

                    intent.putExtra("endTime", calendar.getTimeInMillis());
                    intent.putExtra("title", cursor.getString(2));
                    intent.putExtra("eventLocation", cursor.getString(3));

                    try {
                        startActivity(intent);
                    } catch (ActivityNotFoundException e) {
                        ScheduleActivity.showSnackbar(getResources().getString(R.string.no_calendar_found));
                    }
                }
                cursor.close();
                return true;
            }
        }
        return false;
    }

    @Override
    public void onResume() {
        super.onResume();
        if (getUserVisibleHint()) {
            if (recyclerView != null && recyclerView.getAdapter() == null) {
                new ScheduleFetcher(false, true, false).execute();
            } else {
                new ScheduleFetcher(false, false, false).execute();
            }
        }
    }

    @SuppressLint("SimpleDateFormat")
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd");
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            int month = calendar.get(Calendar.MONTH);
            String monthString = null;
            switch (month) {
                case 0:
                    monthString = getResources().getString(R.string.january);
                    break;
                case 1:
                    monthString = getResources().getString(R.string.february);
                    break;
                case 2:
                    monthString = getResources().getString(R.string.march);
                    break;
                case 3:
                    monthString = getResources().getString(R.string.april);
                    break;
                case 4:
                    monthString = getResources().getString(R.string.may);
                    break;
                case 5:
                    monthString = getResources().getString(R.string.june);
                    break;
                case 6:
                    monthString = getResources().getString(R.string.july);
                    break;
                case 7:
                    monthString = getResources().getString(R.string.august);
                    break;
                case 8:
                    monthString = getResources().getString(R.string.september);
                    break;
                case 9:
                    monthString = getResources().getString(R.string.october);
                    break;
                case 10:
                    monthString = getResources().getString(R.string.november);
                    break;
                case 11:
                    monthString = getResources().getString(R.string.december);
            }
            ActionBar toolbar = ((ScheduleActivity) getActivity()).getSupportActionBar();
            if (toolbar != null) {
                toolbar.setTitle(simpleDateFormat.format(date) + " " + monthString);
                // ugly workaround to fix toolbar title truncation
                toolbar.setDisplayHomeAsUpEnabled(false);
                toolbar.setDisplayHomeAsUpEnabled(true);
            }
            if (!ApplicationLoader.scheduleDatabase.containsWeek(date) &&
                    !ApplicationLoader.scheduleDatabase.isFetched(date)) {
                new ScheduleFetcher(true, true, false).execute();
            } else {
                new ScheduleFetcher(false, false, false).execute();
            }
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
            savedInstanceState) {
        ViewGroup viewGroup = (ViewGroup) inflater.inflate(R.layout.fragment_schedule, container, false);
        swipeRefreshLayout = (SwipeRefreshLayout) viewGroup.findViewById(R.id.swipe_refresh_layout);
        swipeRefreshLayout.setOnRefreshListener(this);
        swipeRefreshLayout.setColorSchemeResources(R.color.colorAccent, R.color.colorPrimaryText, R.color.colorPrimary);
        emptyTextView = (TextView) viewGroup.findViewById(R.id.schedule_not_found);
        spinner = (ProgressBar) viewGroup.findViewById(R.id.progress_bar);
        recyclerView = (RecyclerView) viewGroup.findViewById(R.id.schedule_recyclerview);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        Cursor scheduleDay = ApplicationLoader.scheduleDatabase.getLessons(
                simpleDateFormat.format(date), componentId);
        if (scheduleDay != null && scheduleDay.getCount() > 0) {
            adapter = new ScheduleAdapter(getActivity(), scheduleDay);
            recyclerView.setAdapter(adapter);
        }
        registerForContextMenu(recyclerView);
        if (recyclerView != null && recyclerView.getAdapter() != null) {
            emptyTextView.setVisibility(View.GONE);
        }
        return viewGroup;
    }

    private void alertConnectionProblem() {
        if (!getUserVisibleHint()) {
            return;
        }
        ApplicationLoader.runOnUIThread(new Runnable() {
            @Override
            public void run() {
                new AlertDialog.Builder(getActivity())
                        .setTitle(getResources().getString(R.string.alert_connection_title))
                        .setMessage(getResources().getString(R.string.alert_connection_description))
                        .setPositiveButton(getResources().getString(R.string.connect),
                                new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int id) {
                                        new ScheduleFetcher(true, false, true).execute();
                                        dialog.cancel();
                                    }
                                })
                        .setNegativeButton(getResources().getString(R.string.cancel),
                                new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int id) {
                                        dialog.cancel();
                                    }
                                }).show();
            }
        });
    }

    private void showPromptDialog() {
        if (!getUserVisibleHint()) {
            return;
        }
        ApplicationLoader.runOnUIThread(new Runnable() {
            @Override
            public void run() {
                new AlertDialog.Builder(getActivity())
                        .setTitle(getResources().getString(R.string.confirmation))
                        .setMessage(getResources().getString(R.string.deletion_description))
                        .setPositiveButton(getResources().getString(R.string.hide),
                                new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, int id) {
                                        ApplicationLoader.scheduleDatabase.hideLesson(onLongClickId);
                                        new ScheduleFetcher(false, false, false).execute();
                                        Snackbar snackbar = Snackbar.make(getActivity().findViewById(R.id.coordinator_layout), getResources().getString(R.string.lesson_hidden), Snackbar.LENGTH_SHORT);
                                        snackbar.setAction(getResources().getString(R.string.undo), new View.OnClickListener() {
                                            @Override
                                            public void onClick(View view) {
                                                ApplicationLoader.scheduleDatabase.restoreLessons(onLongClickId);
                                                new ScheduleFetcher(false, false, false).execute();
                                                Snackbar snackbar1 = Snackbar.make(getActivity().findViewById(R.id.coordinator_layout), getResources().getString(R.string.lesson_restored), Snackbar.LENGTH_SHORT);
                                                snackbar1.show();
                                                ApplicationLoader.restartNotificationThread();
                                            }
                                        });
                                        snackbar.show();
                                        ApplicationLoader.restartNotificationThread();
                                        dialog.cancel();
                                    }
                                })
                        .setNegativeButton(getResources().getString(R.string.cancel), new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                dialog.cancel();
                            }
                        }).show();
            }
        });
    }

    @Override
    public void onRefresh() {
        new ScheduleFetcher(true, false, true).execute();
    }

    public class ScheduleFetcher extends AsyncTask<Void, Void, Void> {

        private final boolean fetchData;
        private final boolean showSpinner;
        private final boolean showSwipeRefresh;
        private Cursor scheduleDay;

        public ScheduleFetcher(boolean fetchData, boolean showSpinner, boolean showSwipeRefresh) {
            this.fetchData = fetchData;
            this.showSpinner = showSpinner;
            this.showSwipeRefresh = showSwipeRefresh;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            if (adapter == null || adapter.getItemCount() == 0) {
                if (showSpinner && spinner != null && emptyTextView != null) {
                    emptyTextView.setVisibility(View.GONE);
                    spinner.setVisibility(View.VISIBLE);
                }
            }
            if (showSwipeRefresh && swipeRefreshLayout != null) {
                swipeRefreshLayout.setRefreshing(true);
            }
        }

        @Override
        protected Void doInBackground(Void... param) {
            if (fetchData) {
                try {
                    ScheduleHandler.saveSchedule(ScheduleHandler.getScheduleFromServer(componentId, date, type), date, componentId);
                } catch (Exception e) {
                    alertConnectionProblem();
                }
            }
            scheduleDay = ApplicationLoader.scheduleDatabase.getLessons(simpleDateFormat.format(date), componentId);
            return null;
        }


        @Override
        protected void onPostExecute(Void param) {
            super.onPostExecute(param);
            if (adapter == null) {
                adapter = new ScheduleAdapter(getActivity(), scheduleDay);
                if (recyclerView != null) {
                    recyclerView.setAdapter(adapter);
                }
            } else {
                adapter.changeCursor(scheduleDay);
            }
            if (adapter.getItemCount() == 0) {
                if (emptyTextView != null) {
                    emptyTextView.setVisibility(View.VISIBLE);
                }
            } else {
                if (emptyTextView != null) {
                    emptyTextView.setVisibility(View.GONE);
                }
            }
            if (showSpinner && spinner != null) {
                spinner.setVisibility(View.GONE);
            }
            if (showSwipeRefresh && swipeRefreshLayout != null
                    && swipeRefreshLayout.isRefreshing()) {
                swipeRefreshLayout.setRefreshing(false);
            }
        }
    }
}

0 个答案:

没有答案