滑动选项卡中的ListView未更新,除非重新启动

时间:2016-11-24 10:03:10

标签: android sqlite listview swipe

在我的应用程序中,它有两个选项卡,一个是提醒,另一个是已完成任务。

OpenMP specification

单击切换按钮时,我希望将列表移动到已完成任务。

这个想法是:

  • 从sqlite
  • 获取选中的行ID
  • 根据提醒表中的id检索数据并插入已完成的表。
  • 在已完成标签中调用检索方法。

但是当我点击切换按钮并滑动到已完成时,它仍然是空的。退出应用程序后,然后滑动到选项卡,只显示数据。

如何滑动而不是退出应用并再次重新打开,如何立即将数据显示在已完成标签中?感谢

AllAdapter(提醒)

    overflow-x: scroll;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
     behaviour: ‘smooth’;

CompletedTask

 holder.toggle.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (((ToggleButton)v).isChecked()) {
                        int getPosition = (Integer) v.getTag();  // Here we get the position that we have set for the checkbox using setTag.
                        search.get(getPosition).setSelected(((ToggleButton) v).isChecked());
                        int id= search.get(getPosition).getID();
                        mdb = new MyDatabaseHelper(v.getContext());
                        database = mdb.getReadableDatabase();
                        Cursor cursor = database.rawQuery("SELECT * FROM " + MyDatabaseHelper.TABLE__TASK + " WHERE ID = ? ", new String[]{id+""}, null);
                        if (cursor != null && cursor.getCount() > 0) {
                            while (cursor.moveToNext()) {
                                String allTask = cursor.getString(cursor.getColumnIndex("Title"));
                                String name = cursor.getString(cursor.getColumnIndex("Name"));
                                String allTime = cursor.getString(cursor.getColumnIndex("Time"));
                                String allDate = cursor.getString(cursor.getColumnIndex("Date"));
                                insertDataToCompleteTab(id,name,allTask,allTime,allDate);    // insert to another table
                            } 

                        }
                    } else {
                        int getPosition = (Integer) v.getTag();  // Here we get the position that we have set for the checkbox using setTag.
                        search.get(getPosition).setSelected(((ToggleButton) v).isChecked());
                    }
                }
            });

AllAdapter

enter image description here

已完成标签

http://pastebin.com/qbLDtf4v

CompleteAdapter

http://pastebin.com/WCCbZ0h4

5 个答案:

答案 0 :(得分:4)

默认情况下,ViewPager内的最近选项卡会同时加载。之所以发生这种情况,是因为在使用切换按钮进行任何切换之前,数据已加载到第二个选项卡。要解决问题,您必须更新已完成选项卡中的数据,以防数据发生任何变化。

这可以通过以下几种方式实现:

  • 第一个片段应该在每次更改时发送一个事件,第二个片段应该订阅该事件并手动更新数据

  • 使用loader&内容提供商(或只是自定义的uri' s)。 Loader订阅任何uri更改,您的repository / dao数据库帮助程序通知这些uri有关任何更改(当调用insert / update / delete方法时)

context.getContentResolver().notifyChange(uri);

对象的加载器。

abstract class CachedLoader<T> extends AsyncTaskLoader<T> {

@Nullable
private T cachedData;

CachedLoader(Context context) {
    super(context);
}

void registerUri(Uri... observerUris) {
    for (Uri uri:observerUris) {
        getContext().getContentResolver().registerContentObserver(uri, true, createContentObserver());
    }
}

ContentObserver createContentObserver() {
    return new ForceLoadContentObserver();
}

@Override
public void deliverResult(T data) {
    super.deliverResult(data);
    this.cachedData = data;
}

@Override
public void onContentChanged() {
    super.onContentChanged();
    cachedData = null;
}

@Override
protected void onStartLoading() {
    if (!takeContentChanged() && cachedData != null) {
        deliverResult(cachedData);
        return;
    }

    forceLoad();
}

@Override
protected void onReset() {
    super.onReset();
    cachedData = null;
}
}

呼叫注册uri订阅该uri更改。

或者使用CursorLoader,因为您可以直接使用游标。正如我在更新的问题中看到的那样

我更喜欢第二种方法,但第一种方法更简单

答案 1 :(得分:3)

来自Android documentation for fragment lifecycle

仅在调用活动onResume()onPause()时才会调用系统显示的片段onResume()onPause()。它们与活动紧密结合。

因此,当标签发生变化时,您无法刷新视图。

要解决此问题,我在setUserVisibleHint找到了一个解决方案 在我的申请中,因为我们有相同的要求。 Viewpager调用片段函数,并在片段代码中实现它

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);

    // Make sure that we are currently visible
    if (this.isVisible()) {
        // If we are becoming invisible, then...
        if (!isVisibleToUser) {
            Log.d("TAG", "Stop animation and audio you are not visible");

        }
    }
}

这就是文档所说的

  

向系统提供有关此片段的UI当前是否正在提示的提示   对用户可见。此提示默认为true且持久   跨片段实例状态保存和恢复。应用程序可能将此设置为   false表示片段的UI滚动超出可见性   或者用户不直接看到。这可能会被使用   系统优先考虑碎片生命周期更新等操作   或者加载器排序行为。这个方法可以在外部调用   片段生命周期。因此没有订购保证   片段生命周期方法调用。

ViewPager在其子片段上调用它。 有关详细信息,ViewPager还会调用setMenuVisibility,如果您在显示或删除菜单时遇到问题,可以使用它。请参阅setMenuVisiblity documnet的链接,其中说明了

  

设置是否应显示此片段的菜单的提示。这是   如果您知道片段已放置在视图中,则非常有用   层次结构使用户目前无法看到它,因此任何菜单   它所拥有的物品也不应该出现。

答案 2 :(得分:3)

所以我只是将下面的代码放在我的已完成任务片段

 @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if(isVisibleToUser){
            retrieveList(name);//call the method to be refreshed
        }
        else{
            //no
        }

    }

从@Swapnil获取提示并从https://stackoverflow.com/a/40763755/5261462

回答

答案 3 :(得分:3)

将下面的代码放在片段onResumse上,就像这样

 @Override
  public void onResume() {

     super.onResume();
     retrieveList(name);
  }

答案 4 :(得分:3)

你可以做的是创建一个

的界面
public interface ReminderCompletedListener
{
    void reminderCompleted();
}

CompletedTask中创建该侦听器的实例并将其注册到您的Activity。

((MyActivity) getActivity()).setReminderCompletedListener(new ReminderCompletedListener()
{
    @Override
    public void reminderCompleted()
    {
        retrieveList(name);
    }
});

在您的“活动”中,创建一个可以从切换点击侦听器

调用的方法
((MyActivity) getActivity()).reminderCompleted();

当您从“提醒”选项卡中完成任务时,将触发“已完成”列表重新加载。从这个解决方案中获得的一个主要考虑因素是它将你的片段与你的活动直接耦合。

还有其他解决方案,你可以使用像总线(eventbus / otto)这样的东西,也可能是rxjava,如果你愿意,你可以探索那些,但我给出的香草解决方案应该可以正常工作。