简体   繁体   中英

Android: fragment doesn't refresh if database is empty and first entry is added

EDIT OF 03/07/2015

I made some other progress. Now I have this issue. If database is EMPTY (no value inside) and I insert first value, fragment doesn't refresh.

If there is value in the textview (for example, I reload manually the fragment switching another fragment via menu or closing app or changing rotation) and I insert new value, textviews are refreshed instant.

I post some other code, thank you for your help:

DashboardFragment.java

public class DashboardFragment extends Fragment {

    private DateManager db = null;
    private String last_event;
    private TextView counter_day_placeholder,next_event_placeholder,no_data_found;
    private String timeZone;
    private View v;

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        JodaTimeAndroid.init(getActivity());
        timeZone = SupportDate.getTimezone();

    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        v = inflater.inflate(R.layout.dashboard_fragment,container,false);

        setDashboard();
        setFab();

        return v;
    }

    private void setFab(){
        // BUTTON
        FloatingActionButton newEventButton = (FloatingActionButton) v.findViewById(R.id.set_new_event);
        newEventButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Calendar c = Calendar.getInstance();
                int mYear = c.get(Calendar.YEAR);
                int mMonth = c.get(Calendar.MONTH);
                int mDay = c.get(Calendar.DAY_OF_MONTH);

                DatePickerDialog dialog = new DatePickerDialog(getActivity(), datePickerListener, mYear, mMonth, mDay);

                /*dialog.setButton(DatePickerDialog.BUTTON_POSITIVE, "OK", dialog);
                dialog.setButton(DialogInterface.BUTTON_POSITIVE,"OK",dialog.onDateChanged(DatePicker view););*/
                dialog.show();
            }
        });
    }

    private void setDashboard(){
        last_event = getLastEvent();
        counter_day_placeholder = (TextView) v.findViewById(R.id.counter_day_placeholder);
        next_event_placeholder = (TextView) v.findViewById(R.id.next_event_placeholder);
        if (last_event!=null){

            String next_event = SupportDate.addDayToDate(last_event, null, 28);
            int day_to_next_event = SupportDate.getDifferenceBetweenDatesInDay(next_event, null, timeZone);

            next_event = SupportDate.formatDate(next_event,null,null);
            next_event_placeholder.setText(next_event);

            counter_day_placeholder.setText(Integer.toString(day_to_next_event));
        }
        else
        {
            no_data_found = (TextView) v.findViewById(R.id.no_data_found);
            no_data_found.setVisibility(View.VISIBLE);
            counter_day_placeholder.setVisibility(View.GONE);
            next_event_placeholder.setVisibility(View.GONE);
        }

    }

    private DatePickerDialog.OnDateSetListener datePickerListener
            = new DatePickerDialog.OnDateSetListener() {

        // when dialog box is closed, below method will be called.
        public void onDateSet(DatePicker view, int selectedYear,
                              int selectedMonth, int selectedDay) {

            String stringYear = Integer.toString(selectedYear);

            selectedMonth = selectedMonth+1;

            String stringMonth = Integer.toString(selectedMonth);

            if (stringMonth.length()==1){
                stringMonth = "0"+stringMonth;
            }

            String stringDay = Integer.toString(selectedDay);

            if (stringDay.length()==1){
                stringDay = "0"+stringDay;
            }

            String date = stringYear+"-"+stringMonth+"-"+stringDay+" 00:00:00";
            setEvent(date);
            //last_event = getLastEvent();
            setDashboard();

        }
    };

    private String getLastEvent(){
        last_event = null;
        db=new DateManager(getActivity());
        Cursor cursor=db.getLastEvent();
        if (cursor.getCount()>0){
            cursor.moveToFirst();
            last_event = cursor.getString(1);
        }
        return last_event;
    }

    private void setEvent(String date){

        if (date==null){
            date = SupportDate.getCurrentDate(null,null);
        }
        db=new DateManager(getActivity());
        db.save(date);
    }

}

This is dashboardfragment.xml. Basically, if no event is in database, I remove all textviews but display that with ID no data found (that simply display a text "No data found, please insert one event").

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/relative_layout_dashboard_fragment">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/no_data_found"
        android:textAppearance="@style/TextAppearance.AppCompat.Headline"
        android:id="@+id/no_data_found"
        android:visibility="gone"
        android:layout_alignTop="@+id/view_anchor"
        android:layout_centerHorizontal="true" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="@style/TextAppearance.AppCompat.Display4"
        android:id="@+id/counter_day_placeholder"
        android:text="-50"
        android:layout_above="@+id/view_anchor"
        android:layout_centerHorizontal="true" />

    <View
        android:layout_width="5dp"
        android:layout_height="5dp"
        android:layout_alignWithParentIfMissing="false"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:id="@+id/view_anchor" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="@style/TextAppearance.AppCompat.Title"
        android:id="@+id/next_event_placeholder"
        android:text="01/01/2015"
        android:layout_below="@+id/view_anchor"
        android:layout_centerHorizontal="true" />


    <android.support.design.widget.FloatingActionButton
        android:id="@+id/set_new_event"
        android:src="@drawable/ic_add_white_24dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/fab_layout_margin"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true" />


</RelativeLayout>

=======================================================================

Old post, leaved historical data

I need to refresh my fragment, because user can insert new data from fragment itself. So, when he/she closes the DatePickerDialog and data is inserted in Sqllite, I need to show new values.

This is the snippet from nav drawer to attach the fragment:

case R.id.dashboard:

                        DashboardFragment dashboardFragment = new DashboardFragment();
                        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
                        fragmentTransaction.replace(R.id.frame, dashboardFragment,"DASHBOARD_FRAGMENT");
                        fragmentTransaction.commit();
                        return true;

My code doesn't refresh (neither I have error in log). Thank you very much.

public class DashboardFragment extends Fragment {

    private DateManager db = null;
    private String last_event;
    private TextView counter_day_placeholder,next_event_placeholder,no_data_found;
    private String timeZone;

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        JodaTimeAndroid.init(getActivity());
        //setEvent(null);
        last_event = getLastEvent();
        timeZone = SupportDate.getTimezone();

    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.dashboard_fragment,container,false);

        setDashboard(v);
        setFab(v);

        return v;
    }

    private void setFab(View v){
        // BUTTON
        FloatingActionButton newEventButton = (FloatingActionButton) v.findViewById(R.id.set_new_event);
        newEventButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Calendar c = Calendar.getInstance();
                int mYear = c.get(Calendar.YEAR);
                int mMonth = c.get(Calendar.MONTH);
                int mDay = c.get(Calendar.DAY_OF_MONTH);

                DatePickerDialog dialog = new DatePickerDialog(getActivity(), datePickerListener, mYear, mMonth, mDay);

                /*dialog.setButton(DatePickerDialog.BUTTON_POSITIVE, "OK", dialog);
                dialog.setButton(DialogInterface.BUTTON_POSITIVE,"OK",dialog.onDateChanged(DatePicker view););*/
                dialog.show();
            }
        });
    }

    private void setDashboard(View v){
        counter_day_placeholder = (TextView) v.findViewById(R.id.counter_day_placeholder);
        next_event_placeholder = (TextView) v.findViewById(R.id.next_event_placeholder);
        if (last_event!=null){

            String next_event = SupportDate.addDayToDate(last_event, null, 28);
            int day_to_next_event = SupportDate.getDifferenceBetweenDatesInDay(next_event, null, timeZone);

            next_event = SupportDate.formatDate(next_event,null,null);
            next_event_placeholder.setText(next_event);

            counter_day_placeholder.setText(Integer.toString(day_to_next_event));
        }
        else
        {
            no_data_found = (TextView) v.findViewById(R.id.no_data_found);
            no_data_found.setVisibility(View.VISIBLE);
            counter_day_placeholder.setVisibility(View.GONE);
            next_event_placeholder.setVisibility(View.GONE);
        }

    }

    private DatePickerDialog.OnDateSetListener datePickerListener
            = new DatePickerDialog.OnDateSetListener() {

        // when dialog box is closed, below method will be called.
        public void onDateSet(DatePicker view, int selectedYear,
                              int selectedMonth, int selectedDay) {

            String stringYear = Integer.toString(selectedYear);

            selectedMonth = selectedMonth+1;

            String stringMonth = Integer.toString(selectedMonth);

            if (stringMonth.length()==1){
                stringMonth = "0"+stringMonth;
            }

            String stringDay = Integer.toString(selectedDay);

            if (stringDay.length()==1){
                stringDay = "0"+stringDay;
            }

            String date = stringYear+"-"+stringMonth+"-"+stringDay+" 00:00:00";
            setEvent(date);

            // REFRESH FRAGMENT    

            Fragment fragment = getFragmentManager().findFragmentByTag("DASHBOARD_FRAGMENT");
            FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
            fragmentTransaction.replace(R.id.frame, fragment,"DASHBOARD_FRAGMENT");
            fragmentTransaction.commit();


        }
    };

    private String getLastEvent(){
        last_event = null;
        db=new DateManager(getActivity());
        Cursor cursor=db.getLastEvent();
        if (cursor.getCount()>0){
            cursor.moveToFirst();
            last_event = cursor.getString(1);
        }
        return last_event;
    }

    private void setEvent(String date){

        if (date==null){
            date = SupportDate.getCurrentDate(null,null);
        }
        db=new DateManager(getActivity());
        db.save(date);
    }

}

** EDIT **

I did change code following Shooky answer, but fragment doesn't refresh. Moved the view as class member, without luck. I can refresh the fragment only with change orientation (obviously). This is my second test code:

public class DashboardFragment extends Fragment {

    private DateManager db = null;
    private String last_event;
    private TextView counter_day_placeholder,next_event_placeholder,no_data_found;
    private String timeZone;
    private View v;

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        JodaTimeAndroid.init(getActivity());
        //setEvent(null);
        last_event = getLastEvent();
        timeZone = SupportDate.getTimezone();

    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        v = inflater.inflate(R.layout.dashboard_fragment,container,false);

        setDashboard();
        setFab();

        return v;
    }

    private void setFab(){
        // BUTTON
        FloatingActionButton newEventButton = (FloatingActionButton) v.findViewById(R.id.set_new_event);
        newEventButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Calendar c = Calendar.getInstance();
                int mYear = c.get(Calendar.YEAR);
                int mMonth = c.get(Calendar.MONTH);
                int mDay = c.get(Calendar.DAY_OF_MONTH);

                DatePickerDialog dialog = new DatePickerDialog(getActivity(), datePickerListener, mYear, mMonth, mDay);

                /*dialog.setButton(DatePickerDialog.BUTTON_POSITIVE, "OK", dialog);
                dialog.setButton(DialogInterface.BUTTON_POSITIVE,"OK",dialog.onDateChanged(DatePicker view););*/
                dialog.show();
            }
        });
    }

    private void setDashboard(){
        counter_day_placeholder = (TextView) v.findViewById(R.id.counter_day_placeholder);
        next_event_placeholder = (TextView) v.findViewById(R.id.next_event_placeholder);
        if (last_event!=null){

            String next_event = SupportDate.addDayToDate(last_event, null, 28);
            int day_to_next_event = SupportDate.getDifferenceBetweenDatesInDay(next_event, null, timeZone);

            next_event = SupportDate.formatDate(next_event,null,null);
            next_event_placeholder.setText(next_event);

            counter_day_placeholder.setText(Integer.toString(day_to_next_event));
        }
        else
        {
            no_data_found = (TextView) v.findViewById(R.id.no_data_found);
            no_data_found.setVisibility(View.VISIBLE);
            counter_day_placeholder.setVisibility(View.GONE);
            next_event_placeholder.setVisibility(View.GONE);
        }

    }

    private DatePickerDialog.OnDateSetListener datePickerListener
            = new DatePickerDialog.OnDateSetListener() {

        // when dialog box is closed, below method will be called.
        public void onDateSet(DatePicker view, int selectedYear,
                              int selectedMonth, int selectedDay) {

            String stringYear = Integer.toString(selectedYear);

            selectedMonth = selectedMonth+1;

            String stringMonth = Integer.toString(selectedMonth);

            if (stringMonth.length()==1){
                stringMonth = "0"+stringMonth;
            }

            String stringDay = Integer.toString(selectedDay);

            if (stringDay.length()==1){
                stringDay = "0"+stringDay;
            }

            String date = stringYear+"-"+stringMonth+"-"+stringDay+" 00:00:00";
            setEvent(date);
            last_event = getLastEvent();
            setDashboard();

        }
    };

    private String getLastEvent(){
        last_event = null;
        db=new DateManager(getActivity());
        Cursor cursor=db.getLastEvent();
        if (cursor.getCount()>0){
            cursor.moveToFirst();
            last_event = cursor.getString(1);
        }
        return last_event;
    }

    private void setEvent(String date){

        if (date==null){
            date = SupportDate.getCurrentDate(null,null);
        }
        db=new DateManager(getActivity());
        db.save(date);
    }

}

The reason your fragment is not refreshing is because you are simply getting the reference to the existing fragment and attempting to replace it with itself. This will not cause the onCreate or onCreateView functions to get called again.

Recreating the fragment however is a very heavy and unnecessary operation for what you are trying to do. It appears from your code that you can simply refresh your data in the following way

last_event = getLastEvent();
setDashboard(v);

To do this you will need to hold a reference to "v" by declaring it as a class variable like so

private DateManager db = null;
private String last_event;
private TextView counter_day_placeholder,next_event_placeholder,no_data_found;
private String timeZone;
private View v;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM