How to update a Fragment that has a Gridview populated from Sqlite
Asked Answered
D

3

1

I have a ViewPager with two tabs which holds fragment. Inside the first fragment, I have a Gridview which is being populated with Sqlite Db.

I have an custom alertdialog in my Activity, which is the parent of the Fragments.

When the alertdialog closes, it either adds/removes/updates the Sqlite Db:

DataBaseHelper dbh = DataBaseHelper(this);
...
positiveButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        dbh.addVal(new TheData(editName.getText().toString(), editAge.getText().toString())); //adds a row to the Sqlite Db
        dialog.dismiss();
        //on dismiss, refresh the Fragment, which in turn will display the updated GridView.
    }
});
...

How can I update complete the following:

//on dismiss, refresh the Fragment, which in turn will display the updated GridView.
Durant answered 17/10, 2016 at 21:19 Comment(6)
take a look at https://mcmap.net/q/57531/-getting-the-current-fragment-instance-in-the-viewpagerGale
when you done any operation then you can call again to adapter, (otherwise when operation is performed then you can call one broadcast and handle this broadcast in fragment/activity and notify to gridview). I dont know above is solution, you can try ! good questionConserve
Can you please show me sample code? Where am I calling the adapter?Durant
set viewpager code call againConserve
When the AlertDialog closes?Durant
Ideally you should have a listener on db and your view should automatically get updated if there is a change in db. That being said you can use EventBus for communication in your app. Here is one greenrobot.github.io/EventBusPartnership
D
0
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.detach(frag).attach(frag).commit(); //frag is my Fragment instance...

Each time the dialog closed and it did the trick... simple and easy!

Durant answered 27/10, 2016 at 1:32 Comment(0)
T
1

You could use Intents and Intent Filters with a Broadcast Receiver for this.

  1. Create a BroadcastReceiver instance in the fragment where you want to update the data.
  2. Create an IntentFilter and set an action string (maybe 'db.update') to it and register it with your application context (you could do this via your fragment by calling getActivity().getApplicationContext().registerReceiver(receiver, filter).
  3. In your AlertDialog, after you update your database, create an Intent with the same action string you set above (in our case, 'db.update') and use context to send it out (getActivity().getApplicationContext().sendBroadcast(intent)). Your BroadcastReceiver's onReceive() method would be called in your fragment and you can call the method to refresh or reload your data there. See sample code below:

Say this is your fragment

public class YourFragment extends Fragment {

private GridView mGridView;
private BaseAdapter mAdapter;
private BroadcastReceiver mReceiver;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    //inflate view as usual
    View view = inflater.inflate(R.layout.yourlayour, container, false);
    ...

    //create instance of broadcast receiver
    mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) { //when intent is receiver, this method is called
            if(intent.getAction().contentEquals("db.update")){
                //update intent received, call method to refresh your content loader
                refreshFragment();
            }
        }
    };

    //create a new intent filter
    IntentFilter mDataUpdateFilter = new IntentFilter("db.update");

    //register our broadcast receiver and intent filter
    getActivity().getApplicationContext().registerReceiver(mReceiver, mDataUpdateFilter);
    return view;
}

@Override
public void onDestroy() {
    super.onDestroy();
    //never forget to unregister the receiver when you're done, it could cause your app to crash
    //if it receives an intent and calls null pointing methods in your code
    getActivity().getApplicationContext().unregisterReceiver(mReceiver);
}  }

Then in your AlertDialog as you did above, send the intent to this receiver by:

DataBaseHelper dbh = DataBaseHelper(this);
        ...
        positiveButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dbh.addVal(new TheData(editName.getText().toString(), editAge.getText().toString())); //adds a row to the Sqlite Db


                //Create an intent with our action
                Intent updateIntent = new Intent("db.update");

                //send the intent by
                getContext().getApplicationContext().sendBroadcast(updateIntent);
                dialog.dismiss();
            }
        });
        ...

Don't forget to unregister your broadcast receiver when your fragment is destroyed. Call getActivity().getApplicationContext().unregisterReceiver(receiver); in your onDestroy() method.

I should also point out that the onReceive() method of your broadcast receiver would always be called on the main thread, even if you send your intent from a background thread.

Tadeo answered 17/10, 2016 at 22:2 Comment(12)
The db.update inside Intent, is that based on what I am doing?Durant
@Durant Yeah. It doesn't have to be db.update though, it could be any string that you want to watch out for. For example, every time your bluetooth device is switched on, android.bluetooth.adapter.action.STATE_CHANGED is broadcast all over android. You just know that when that action is broadcast, some change must have happened to bluetooth, so you could do something there like refresh a list of bluetooth devices or something that depends on that state change.Tadeo
What would go inside refreshFragment()? I will test it out. Do I execute the query again to update the GridView? And If I have db.add and db.delete, I have to have multiple receiver?Durant
@Durant the logic you use to refresh your gridview. Are you using a cursor adapter with your gridview or a normal array adapter with a list of items loaded from the database?Tadeo
So what I did was put a Toast to see if the fragment executes the function but it doesn't.Durant
refreshFragment() is not an existing method, I just put it there meaning it should be the function where you reload your data again. create a new method called refreshFragment() in your fragment, then you can move your code which gets the data from your DatabaseHelper and sets it to the grid view to that function. See pastebin.com/kipAXEe7Tadeo
Seems like I can't use getActivity() inside my AlertDialog methodDurant
I had to end up using just sendBroadcast() Testing out my code with your edit and also kept the activity code the same.Durant
@Durant sorry about that, AlertDialog doesn't let you getActivity() (I don't know how I missed that). Use getContext().getApplicationContext().sendBroadcast(updateIntent); instead.Tadeo
Let us continue this discussion in chat.Tadeo
OK great. I will meet you there.Durant
Any idea left to implement?Durant
I
0

Here is a trick that i use to access Fragments inside a ViewPager in my custom viewPagerAdapter, i add two methods

public class CustomViewPagerAdapter extends FragmentPagerAdapter {
    .....
    private String getFragmentTag(int viewId, int index) {
            return "android:switcher:" + viewId + ":" + index;
    }

    //mFragManager is a reference to FragmentManager
    public Fragment getFragmentByTag(int containerId, int position) {
        return mFragManager.findFragmentByTag(getFragmentTag(containerId, position));
    }
}

then in your activity or wherever you can access the customViewPager

YourFragment frag = (YourFragment) customViewPager
                            .getFragmentByTag(YouViewPager.getId(), position);

after that, add a method in YourFragment refreshData (if you like the name!) and in it refresh the grid Hope this help

Intensify answered 18/10, 2016 at 0:3 Comment(0)
D
0
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.detach(frag).attach(frag).commit(); //frag is my Fragment instance...

Each time the dialog closed and it did the trick... simple and easy!

Durant answered 27/10, 2016 at 1:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.