Android 通知RecyclerView适配器数据库已更改
我的Android 通知RecyclerView适配器数据库已更改,android,database,android-fragments,android-adapter,android-recyclerview,Android,Database,Android Fragments,Android Adapter,Android Recyclerview,我的main活动调用一个片段 @Override public void onNavigationDrawerItemSelected(int position) { // update the main content by replacing fragments FragmentManager fragmentManager = getSupportFragmentManager(); fragmentManager.beginTransaction()
main活动
调用一个片段
@Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, PlaceholderFragment.newInstance(position + 1),
"placeHolderFragmentTag")
.commit();
}
占位符片段
用适配器填充回收视图
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dbHelper = new DatabaseHelper(getActivity().getApplicationContext());
dbHelper.getWritableDatabase();
dbHelper.openDataBase();
adapterUpcomingGames = new AdapterUpcomingGames(retrieveGames(dbHelper.getUpcomingGames()));
}
适配器PCominggames
。适配器从用户输入的数据库中获取数据,即即将到来的体育赛事的列表
@Override // still placeholderFragment
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity().getApplicationContext()));
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
switch(getArguments().getInt(ARG_SECTION_NUMBER))
{
case 1: // This will be upcoming games
mRecyclerView.setAdapter(adapterUpcomingGames);
break;
case 2: // This will be past games
AdapterPastGames adapterPastGames;
adapterPastGames = new AdapterPastGames(retrieveGames(dbHelper.getPastGames()));
mRecyclerView.setAdapter(adapterPastGames);
break;
default: // Default is, well, anything that will work.
adapterUpcomingGames1 = new AdapterUpcomingGames(retrieveGames(dbHelper.getGames()));
mRecyclerView.setAdapter(adapterUpcomingGames1);
}
newGame.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0){
Intent createGame = new Intent(getActivity(),
ActivityCreateGame.class);
startActivity(createGame);
adapterUpcomingGames.notifyDataSetChanged();
}
});
setRetainInstance(true);
}
在该视图中,有一个按钮用于添加游戏,即修改数据库。我通过调用一个新活动来实现这一点,activityCreateGame
,它承载一个片段
@Override // activityCreateGame
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_game);
fragmentCreateGame = new FragmentCreateGame();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.attach(fragmentCreateGame)
.replace(R.id.newGameContainer, fragmentCreateGame)
.commit();
restoreActionBar();
}
fragmentCreateGame
,允许用户输入所需信息,然后将其附加到数据库中。用户使用该活动中导航栏上的选项保存此信息
@Override // activityCreateGame
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case android.R.id.home:
finish();
break;
case R.id.action_save:
// check if an error has occured
if (fragmentCreateGame.CreateNewGame())
{
Toast toast = Toast.makeText(this, R.string.toast_success_game_create,
Toast.LENGTH_SHORT);
toast.show();
finish();
}
else{
Toast toast = Toast.makeText(this, R.string.toast_failed_game_create,
Toast.LENGTH_SHORT);
toast.show();
}
break;
}
return super.onOptionsItemSelected(item);
}
该操作将完成
activityCreateGame
。现在,我如何通知适配器,回到占位符片段
中,数据库已经更新,从而更新回收视图
以更新自身?通过查看您的代码,我可以为您想出三种解决方案。按照(我的意见)解决方案的质量从最低到最佳的顺序
fragmentCreateGame
移动到第一个活动托管的位置build.gradle
中,将其添加到依赖项中
dependencies {
....
compile 'com.squareup:otto:1.3.6'
....
}
在需要通知的活动中,在onCreate的开头添加以下内容:
Bus bus = new Bus();
bus.register(this);
然后,创建一个“事件”类。它只是您传递给订阅者以通知订阅者的对象。您也可以向这些添加信息,以传递更多信息
public class SomeCoolEvent{
private String yourWisdom;
public SomeCoolEvent(String yourWisdom){
this.yourWisdom = yourWisdom;
}
public String getWisdom(){
return yourWisdom;
}
}
然后,在您正在做一些事情通知其他类的类中,执行以下操作:
Bus bus = new Bus();
bus.post(new SomeCoolEvent(yourWisdomStringFromThisClass));
现在,回到您的第一个活动,添加一个用@Subscribe
@Subscribe
public void onAnyMethodNameYouWantCauseItDoesntMatter(SomeCoolEvent event){
//this will be called when ANY class calls bus.post(SomeCoolEvent)
String boomYouAreNotified = event.getWisdom();
}
在您的@Subscribe
方法中,没有什么需要注意的。
*方法名并不重要,所以请给它一些对您有意义的东西。我喜欢在它前面加上“on
”,因为它就像一个回调。
*方法必须是public
并返回void
。
*您没有显式调用此方法,因此某些IDE可能会显示它未使用。Android studio将允许您使用“ALT+ENTER”来修复此问题,然后选择“\u忽略使用Subscribe注释的方法的警告”。
*您应该在销毁时调用bus.unregister(this)
。
*你可以让多个班级听一篇文章
现在,如果您开始在不同的线程上运行,事情可能会变得更加复杂。如果你这样做了,在我提供的Otto页面底部有一些解决方案在一些代码中帮助理解它的声音,从接口中考虑一个定制的侦听器,或者我想知道是否可能有类似的东西。我已经添加了一些代码,但我也会看一看。奥托现在可能有点超过我了。但我会看看的。做了一些修改,我的ActivityForResult运行得很好,但是RecyclerView没有更新。适配器似乎正在更改NOTIFYDATASETCHANGE,但视图没有更新。@JoshuaSutherland,因为您没有向适配器添加任何项目。创建适配器时,您正在查询数据库。这对第一个有效。但是当你调用notifiyDataSetChanged时,它不会再调用它。您需要创建数据的ArrayList,然后创建适配器,并传入此列表。然后将新数据添加到此列表,然后调用notifyDataSetChanged.OK。这是有道理的。那么,在这种情况下,什么是最好的呢?我应该重新查询数据库的结果吗?好的。请注意适配器、listView和list的实例。如果您重新查询列表,并将列表设置为您的结果,您的适配器可能在“查看”此更改时遇到问题。如果是这样,只需重新创建适配器并将其设置为列表视图。因此,如果可以管理所有实例,只需将项目添加到列表中即可。没有将它们设置到列表中。