【问题标题】:How to update a Fragment that has a Gridview populated from Sqlite如何更新具有从 Sqlite 填充的 Gridview 的片段
【发布时间】:2016-10-17 21:19:55
【问题描述】:

我有一个带有两个选项卡的 ViewPager,其中包含片段。在第一个片段中,我有一个使用 Sqlite Db 填充的 Gridview。

我的 Activity 中有一个自定义警报对话框,它是 Fragments 的父级。

当 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.

【问题讨论】:

  • 当您完成任何操作时,您可以再次调用适配器,(否则在执行操作时,您可以调用一个广播并在片段/活动中处理此广播并通知给gridview)。我不知道上面是解决方案,你可以试试!好问题
  • 你能给我看看示例代码吗?我在哪里调用适配器?
  • 再次设置viewpager代码调用
  • AlertDialog 何时关闭?

标签: android sqlite android-fragments


【解决方案1】:

您可以将Intents and Intent FiltersBroadcast Receiver 一起使用 为此。

  1. 在要更新数据的片段中创建一个 BroadcastReceiver 实例。
  2. 创建一个 IntentFilter 并为其设置一个操作字符串(可能是“db.update”)并将其注册到您的应用程序上下文中(您可以通过调用 getActivity().getApplicationContext().registerReceiver 通过您的片段执行此操作(接收器,过滤器)。
  3. 在您的 AlertDialog 中,更新数据库后,使用您在上面设置的相同操作字符串(在我们的示例中为“db.update”)创建一个 Intent,并使用上下文将其发送出去(getActivity(). getApplicationContext().sendBroadcast(intent))。您的 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();
            }
        });
        ...

当您的片段被销毁时,不要忘记取消注册您的广播接收器。在您的 onDestroy() 方法中调用 getActivity().getApplicationContext().unregisterReceiver(receiver);

我还应该指出,您的广播接收器的 onReceive() 方法将始终在主线程上调用,即使您从后台线程发送您的意图。

【讨论】:

  • Intent里面的db.update,是基于我在做什么?
  • @Si8 是的。不过,它不一定是db.update,它可以是您要注意的任何字符串。例如,每次打开蓝牙设备时,android.bluetooth.adapter.action.STATE_CHANGED 就会在整个安卓系统中广播。您只知道广播该操作时,蓝牙肯定发生了一些变化,因此您可以在那里执行一些操作,例如刷新蓝牙设备列表或依赖于该状态更改的操作。
  • refreshFragment() 里面会有什么?我会测试一下。我是否再次执行查询以更新 GridView?如果我有db.adddb.delete,我必须有多个接收器?
  • @Si8 用于刷新网格视图的逻辑。您是在 gridview 中使用光标适配器,还是在普通数组适配器中使用从数据库加载的项目列表?
  • refreshFragment() 不是现有方法,我只是把它放在那里意味着它应该是您再次重新加载数据的功能。在您的片段中创建一个名为refreshFragment() 的新方法,然后您可以移动从DatabaseHelper 获取数据的代码并将其设置为该函数的网格视图。见pastebin.com/kipAXEe7
【解决方案2】:

这是我用来访问 ViewPager 中的片段的技巧 在我的自定义 viewPagerAdapter 中,我添加了两个方法

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

之后,在 YourFragment refreshData 中添加一个方法(如果您喜欢这个名字!)并在其中刷新网格 希望对您有所帮助

【讨论】:

    【解决方案3】:
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    ft.detach(frag).attach(frag).commit(); //frag is my Fragment instance...
    

    每次对话框关闭时,它都会成功...简单易行!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-02
      • 1970-01-01
      相关资源
      最近更新 更多