Как обновить фрагмент, который имеет Gridview, заполненный Sqlite

У меня есть ViewPager с двумя вкладками, которые содержат фрагмент. Внутри первого фрагмента у меня есть Gridview, который заполняется Sqlite Db.

У меня есть специальный alertdialog в моей Activity, который является родителем фрагментов.

Когда alertdialog закрывается, он либо добавляет/удаляет/обновляет 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.
    }
});
...

Как я могу выполнить обновление, выполните следующие действия:

//on dismiss, refresh the Fragment, which in turn will display the updated GridView.

Ответ 1

FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.detach(frag).attach(frag).commit(); //frag is my Fragment instance...

Каждый раз, когда диалог закрывался, и это делало трюк... простым и легким!

Ответ 2

Вы можете использовать Intents и Intent Filters с помощью Broadcast Receiver  для этого.

  • Создайте экземпляр BroadcastReceiver в фрагменте, где вы хотите обновить данные.
  • Создайте IntentFilter и установите для него строку действия (возможно, "db.update" ) и зарегистрируйте ее в контексте вашего приложения (вы можете сделать это через свой фрагмент, вызвав getActivity(). getApplicationContext(). registerReceiver (приемник, фильтр).
  • В вашем AlertDialog после обновления базы данных создайте намерение с той же строкой действия, что и вы, выше (в нашем случае, "db.update" ) и используйте контекст для отправки (getActivity(). getApplicationContext(). sendBroadcast (намерение)). Ваш метод BroadcastReceiver onReceive() будет вызываться в вашем фрагменте, и вы можете вызвать этот метод для обновления или перезагрузки данных. См. Пример кода ниже:

Скажите, что это ваш фрагмент

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);
}  }

Затем в вашем AlertDialog, как вы это делали выше, отправьте намерение этому получателю:

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();
            }
        });
        ...

Не забывайте отменить регистрацию своего широковещательного приемника при уничтожении фрагмента. Вызов getActivity(). GetApplicationContext(). UnregisterReceiver (получатель); в методе onDestroy().

Следует также отметить, что метод onReceive() вашего широковещательного приемника всегда будет вызываться в основном потоке, даже если вы отправляете свое намерение из фонового потока.

Ответ 3

Вот трюк, который я использую для доступа к фрагментам внутри ViewPager в моем пользовательском представленииPagerAdapter, я добавляю два метода

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));
    }
}

то в вашей деятельности или где вы можете получить доступ к customViewPager

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

после этого добавьте метод в RefreshData вашего Fragment (если вам нравится имя!), и в нем обновите сетку Надеемся на эту помощь.