Nazanin Nasab
Nazanin Nasab

Reputation: 625

How to Re-create the Fragment after Making Changes from its Activity?

I have a MainActivity which has a fragment names FragmentOne. i have List of items in this fragment and these data are save in my database

this MainActvity has a NavigationDrawer. i try to delete all rows from my database. it works, but after that i need to refresh my FragmentOne . i have a method named updateUI in my FragmentOne but how could i access that method? when i make that method public everything just goes wrong!

here is the part for delete and refresh my MainActivity:

DetailLab.get(getApplicationContext()).deleteAllDetail();
FragmentOne fragmentOne = new FragmentOne();
fragmentOne.getFragmentManager().beginTransaction().replace(R.id.fragment_one_layout, fragmentOne).commit();

here is whole MainActivity:

public class MainActivity extends AppCompatActivity {

private DrawerLayout mDrawerLayout;
private TabLayout tabLayout;
private ViewPager viewPager;
private int[] tabIcons = {
        R.drawable.ic_tab_note,
        R.drawable.ic_tab_calendar
};
private Detail mDetail;

private static final int TIME_DELAY = 2000;
private static long back_pressed;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //////// TOOLBAR
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    ActionBar actionBar = getSupportActionBar();
    actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);
    actionBar.setDisplayHomeAsUpEnabled(true);

    ///////// DRAWER
    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

    NavigationView navigationView =
            (NavigationView) findViewById(R.id.navigation_view);
    navigationView.setNavigationItemSelectedListener
            (new NavigationView.OnNavigationItemSelectedListener() {
                @Override
                public boolean onNavigationItemSelected(MenuItem menuItem) {
                    switch (menuItem.getItemId()) {
                        case R.id.nav_item_one:
                            return false;

                        case R.id.nav_item_two:


                            AlertDialog.Builder alert_delete = new AlertDialog.Builder(
                                    MainActivity.this);
                            alert_delete.setTitle("Alert!");
                            alert_delete.setMessage(R.string.alert_delete_all);
                            alert_delete.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {

                                    DetailLab.get(getApplicationContext()).deleteAllDetail();

                                    FragmentOne fragmentOne = new FragmentOne();
                                    fragmentOne.getFragmentManager().beginTransaction().replace(R.id.card_view, fragmentOne)
                                            .commit();

                                            dialog.dismiss();
                                }
                            });
                            alert_delete.setNegativeButton("No", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    dialog.dismiss();
                                }
                            });
                            alert_delete.show();

                            return false;

                        case R.id.nav_item_three:
                            return false;

                        case R.id.nav_item_five:
                            return false;

                        case R.id.nav_item_six:
                            return false;

                        case R.id.nav_item_seven:
                            return false;

                        case R.id.nav_item_eight:
                            AlertDialog.Builder alert = new AlertDialog.Builder(
                                    MainActivity.this);
                            alert.setIcon(R.drawable.ic_menu_send);
                            alert.setTitle("Contact Me via");
                            alert.setMessage("\[email protected]\n" +
                                    "tlgrm.me/drgnme");
                            alert.setNegativeButton("OKAY", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    dialog.dismiss();
                                }
                            });

                            alert.show();
                            return false;

                        case R.id.nav_item_nine:
                            finish();

                            default:
                                return false;
                    }
                }
            });

    viewPager = (ViewPager) findViewById(R.id.viewpager);
    setupViewPager(viewPager);

    tabLayout = (TabLayout) findViewById(R.id.tablayout);
    tabLayout.setupWithViewPager(viewPager);
    setupTabIcons();
}

private void setupTabIcons() {
    tabLayout.getTabAt(0).setIcon(tabIcons[0]);
    tabLayout.getTabAt(1).setIcon(tabIcons[1]);
}

private void setupViewPager(ViewPager viewPager) {
    ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
    adapter.addFragment(new FragmentOne(), "ONE");
    adapter.addFragment(new FragmentTwo(), "TWO");
    viewPager.setAdapter(adapter);
}

class ViewPagerAdapter extends FragmentPagerAdapter {
    private final List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();

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

    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }

    @Override
    public int getCount() {
        return mFragmentList.size();
    }

    public void addFragment(Fragment fragment, String title) {
        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return null;
    }
}


@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();

    switch (id) {
        case android.R.id.home:
            mDrawerLayout.openDrawer(GravityCompat.START);
            return true;
    }
    return super.onOptionsItemSelected(item);
}


@Override
public void onBackPressed() {
    if (back_pressed + TIME_DELAY > System.currentTimeMillis()) {
        super.onBackPressed();
    }
    else {
        Toast.makeText(getBaseContext(), "Press once morE for eXit",
                Toast.LENGTH_SHORT)
                .show();
    }
    back_pressed = System.currentTimeMillis();
}
}

here is my method for delete all rows from database in another class called DetailLab :

public void deleteAllDetail() {
        mDatabase.delete(DetailTable.NAME, null, null); }

and this is my FragmentOne:

public class FragmentOne extends Fragment {
    private static final String SAVED_NUMBER_VISIBLE = "number";

    private RecyclerView mDetailRecyclerView;
    private DetailAdapter mAdapter;
    private boolean mNumberVisible;
    private View view;

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

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

        mDetailRecyclerView = (RecyclerView)
                view.findViewById(R.id.detail_recycler_view);

        LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
        layoutManager.setReverseLayout(true); //This will reverse the data order but not scroll the RecyclerView to the last item
        layoutManager.setStackFromEnd(true); //For keeping data order same and simply scrolling the RecyclerView to the last item
        mDetailRecyclerView.setLayoutManager(layoutManager);

        if (savedInstanceState != null) {
            mNumberVisible =
                    savedInstanceState.getBoolean(SAVED_NUMBER_VISIBLE);
        }

        FloatingActionButton fab =
                (FloatingActionButton) view.findViewById(R.id.fab);

        /////////// change the fab color in normal state
        int darkColorValue = Color.parseColor("#2b3f62");
        fab.setBackgroundTintList(ColorStateList.valueOf(darkColorValue));

        ///////// change the fab color in pressed state
        int color = Color.parseColor("#f4ac1c");
        fab.setRippleColor(color);

        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick (View v) {
                Detail detail = new Detail();
                DetailLab.get(getActivity()).addDetail(detail);
                Intent intent = DetailPagerActivity
                        .newIntent(getActivity(), detail.getId());
                startActivity(intent);
            }
        });

        updateUI();
        return view;
    }

    @Override
    public void onResume() {
        super.onResume();
        updateUI();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean(SAVED_NUMBER_VISIBLE, mNumberVisible);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        inflater.inflate(R.menu.fragment_one_layout, menu);
        MenuItem numberItem = menu.findItem(R.id.show_numbers);
        if (mNumberVisible) {
            numberItem.setTitle(R.string.hide_numbers);
        } else {
            numberItem.setTitle(R.string.show_numbers);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {

            case R.id.show_numbers:
                mNumberVisible = !mNumberVisible;
                getActivity().invalidateOptionsMenu();
                updateNumbers();
                return true;

            default:
                return super.onOptionsItemSelected(item);
        }
    }

    private void updateNumbers() {
        DetailLab detailLab = DetailLab.get(getActivity());
        int detailCount = detailLab.getDetails().size();
        String number = getResources().getQuantityString
                (R.plurals.number_plural, detailCount, detailCount);


        if (!mNumberVisible) {
            number = null;
        }

        AppCompatActivity activity = (AppCompatActivity) getActivity();
        activity.getSupportActionBar().setSubtitle(number);
    }

    private void updateUI() {
        DetailLab detailLab = DetailLab.get(getActivity());
        List<Detail> details = detailLab.getDetails();
        if (details.size() == 0) {
            TextView t = (TextView) view.findViewById(R.id.empty);
            t.setText(R.string.empty_view);
            t.setVisibility(View.VISIBLE);
        } else {
            TextView t = (TextView) view.findViewById(R.id.empty);
            t.setVisibility(View.GONE);
        }

//            Toast.makeText(getContext(), "zero", Toast.LENGTH_SHORT).show();
        if (mAdapter == null) {
            mAdapter = new DetailAdapter(details);
            mDetailRecyclerView.setAdapter(mAdapter);

        } else {
            mAdapter.setDetails(details);
            mAdapter.notifyDataSetChanged();
        }

        updateNumbers();

    }

    private class DetailHolder extends RecyclerView.ViewHolder
            implements View.OnClickListener, View.OnLongClickListener {
        private TextView mTitleTextView;
        //        private TextView mDateTextView;
        private Detail mDetail;
        private RatingBar mRatingBar;

        public DetailHolder(LayoutInflater inflater, ViewGroup parent) {
            super(inflater.inflate(R.layout.list_item_detail,
                    parent, false));

            itemView.setOnClickListener(this);
            itemView.setOnLongClickListener(this);
            mTitleTextView = (TextView) itemView.findViewById(R.id.detail_title);
//            mDateTextView = (TextView) itemView.findViewById(R.id.detail_date);
            mRatingBar = (RatingBar) itemView.findViewById(R.id.ratingBar);

        }

        public void bind(Detail detail) {
            mDetail = detail;
            mTitleTextView.setText(mDetail.getTitle());
            mRatingBar.setRating(mDetail.getRate());
        }

        @Override
        public void onClick(View view) {
            Intent intent = DetailPagerActivity.newIntent(getActivity(),
                    mDetail.getId());
            startActivity(intent);
        }

        @Override
        public boolean onLongClick(View v) {

            AlertDialog.Builder alert = new AlertDialog.Builder(
                    getActivity());
            alert.setMessage(R.string.alert);
            alert.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    DetailLab.get(getActivity()).deleteDetail(mDetail);
                    updateUI();
                    updateNumbers();
                    dialog.dismiss();
                }
            });
            alert.setNegativeButton("No", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            });
            alert.show();
            return true;
        }
    }

    private class DetailAdapter extends RecyclerView.Adapter<DetailHolder> {
        private List<Detail> mDetails;

        public DetailAdapter(List<Detail> details) {
            mDetails = details;
        }

        @Override
        public DetailHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            LayoutInflater layoutInflater =
                    LayoutInflater.from(getActivity());

            return new DetailHolder(layoutInflater, parent);
        }

        @Override
        public void onBindViewHolder(DetailHolder holder, int position) {
            Detail detail = mDetails.get(position);
            holder.bind(detail);
        }

        @Override
        public int getItemCount() {
            return mDetails.size();
        }

        public void setDetails(List<Detail> details) {
            mDetails = details;
        }
    }
}

and here is my layout for FragmentOne :

<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:id="@+id/fragment_one_layout">

    <android.support.v7.widget.CardView
    android:id="@+id/card_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/detail_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/empty"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="50dp"
        android:textAlignment="center"
        android:textSize="20sp"/>
</android.support.v7.widget.CardView>

<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginRight="24dp"
android:layout_marginBottom="24dp"
android:src="@drawable/ic_menu_add"
android:scaleType="center"
app:elevation="8dp"
app:borderWidth="0dp"
    />

my logcat:

  FATAL EXCEPTION: main
Process: com.drgnme.listhamrah, PID: 23454
java.lang.NullPointerException: Attempt to invoke virtual method 'android.support.v4.app.FragmentTransaction android.support.v4.app.FragmentManager.beginTransaction()' on a null object reference
at com.drgnme.listhamrah.MainActivity$1$1.onClick(MainActivity.java:76)
at android.support.v7.app.AlertController$ButtonHandler.handleMessage(AlertController.java:161)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5451)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

Upvotes: 1

Views: 4523

Answers (2)

0123
0123

Reputation: 85

So you delete everything from the database, but the changes won't be reflected in your UI since your using a local list within the adapter. Once you clear your database you also need to call mDetails.clear() and notifyDataSetChanged() on the adapter, this will clear the list without having to refresh the fragment.

Upvotes: 0

Amaury Medeiros
Amaury Medeiros

Reputation: 2233

Replace getFragmentManager() with getSupportFragmentManager(). Your activity should extend FragmentActivity. Then you're going to have something like:

FragmentOne fragmentOne = new FragmentOne();
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_one_layout, fragmentOne).commit();

Upvotes: 1

Related Questions