2016-11-24 34 views
5

W mojej aplikacji ma dwie zakładki, jedna to Przypomnienie, a druga to Zadanie zakończone.ListView w zakładce przesunięcia nie jest aktualizowany, chyba że nastąpi ponowne uruchomienie.

enter image description here

Gdy przycisk przełączania kliknięciu, chcę to przenieść listę ukończonym zadaniu.

Pomysł są:

  • Get sprawdzenia identyfikatora wiersza z sqlite
  • pobierania danych na podstawie identyfikatora z Przypomnienie tabeli i wstawić do uzupełnionej tabeli.
  • Metoda Call Retrieve w zakładce Completed.

Ale po kliknięciu przycisku przełącznika i przesunięciu do pozycji Zakończono, nadal jest pusta. Po wyjściu z aplikacji i przesunięciu palcem do karty wyświetlają się tylko te dane.

Jak mogę od razu pokazać dane w zakładce Completed, gdy zamiast machnięcia opuścić aplikację i ponownie otworzyć? Dzięki

AllAdapter (Przypomnienie)

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

CompletedTask

retrieveList(name); 

public void retrieveList(String name) { 
     Toast.makeText(getActivity(),name,Toast.LENGTH_SHORT).show(); 
     search.clear(); 
     database = mdb.getReadableDatabase(); 
     Cursor cursor = database.rawQuery("SELECT * FROM " + MyDatabaseHelper.TABLE_TASKCOMPLETED + " WHERE Name = ? ", new String[]{name}, null); 
     if (cursor != null && cursor.getCount() > 0) { 
      while (cursor.moveToNext()) { 
       int iD = cursor.getInt(cursor.getColumnIndex("ID")); 
       String allTask = cursor.getString(cursor.getColumnIndex("Title")); 
       String allTime = cursor.getString(cursor.getColumnIndex("Time")); 
       String allDate = cursor.getString(cursor.getColumnIndex("Date")); 

       if (adapter != null) { 
        adapter.add(iD, allTask, allTime, allDate); 
        listview.setAdapter(adapter); 
        adapter.getCount(); 
//     check(); 
       } 
      } 
     } else { 
     } 
    } 

AllAdapter

http://pastebin.com/qbLDtf4v

Zakończony Tab

http://pastebin.com/WCCbZ0h4

CompleteAdapter

http://pastebin.com/QdbuTQKm

+0

Jeśli używasz list do wyświetlania danych, upewnij się, że wywołałeś metodę notifyDataSetChanged() na adapterze listy, aby zaktualizować widoki za pomocą nowych danych. –

+0

Zamiast przenosić dane z jednej tabeli do drugiej, utwórz tylko jedną tabelę zadań, która będzie miała kolumnę boolowską mówiącą zakończoną lub nie. podczas przełączania wystarczy zaktualizować to pole z tabeli. gdzie jest twój kod? –

+0

@AmrutBidri proszę sprawdzić – Hoo

Odpowiedz

3

Z Android documentation for fragment lifecycle

systemowe wyświetlane fragmenty onResume() lub onPause() zostanie wywołana tylko wówczas, gdy działalność onResume() lub onPause() nazywa. Są ściśle powiązane z Działalnością.

Z tego powodu nie można odświeżyć widoku przy zmianie karty.

Aby rozwiązać ten problem, znalazłem jedno rozwiązanie w aplikacji setUserVisibleHint w mojej aplikacji, ponieważ mieliśmy takie same wymagania. Viewpager połączenia następujących funkcji swojego fragmentu i wdrożyć go w kodzie fragment

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

     } 
    } 
} 

To co mówi dokumentacja

Ustaw wskazówkę do systemu, czy ten fragment UI jest obecnie widoczne dla użytkownika . Ta wskazówka jest ustawiona na wartość true i jest trwała. Zachowuje i odtwarza stan instancji fragmentu. Aplikacja może ustawić tę wartość na false, aby wskazać, że interfejs użytkownika fragmentu jest przewijany poza widoczność lub w inny sposób nie jest bezpośrednio widoczny dla użytkownika. Może on być używany przez system do priorytetyzacji operacji, takich jak aktualizacja cyklu życia fragmentów lub zachowanie porządku ładującego. Metoda ta może być wywołana poza cyklem życia fragmentu . iw związku z tym nie ma żadnych gwarancji dotyczących zamawiania w odniesieniu do wywołań metod cyklu fragmentacji .

ViewPager wywołuje to na swoim module podrzędnym. Aby uzyskać więcej informacji, ViewPager również dzwoni pod numer setMenuVisibility, z którego możesz korzystać w przypadku problemów z wyświetlaniem lub usuwaniem menu. link do strony setMenuVisiblity documnet, który stwierdza, że ​​

Podpowiedź, czy menu tego fragmentu powinno być widoczne. Jest to przydatne w przypadku, gdy wiesz, że fragment został umieszczony w widoku hierarchii, aby użytkownik nie mógł go obecnie zobaczyć, więc wszelkie pozycje menu, które ma, nie powinny być pokazywane.

4

Domyślnie najbliższymi kartach wewnątrz ViewPager są ładowane jednocześnie. Tak się stało, ponieważ dane zostały wczytane do drugiej zakładki przed wykonaniem jakichkolwiek przełączników za pomocą przełącznika. Aby naprawić problem, musisz zaktualizować dane w wypełnionej karcie na wypadek zmiany danych.

Można to osiągnąć kilkoma sposobami:

  • Pierwszy fragment powinien wysłać zdarzenie na każdej zmianie i drugi powinien zapisać się na tych danych zdarzeń i aktualizacji ręcznie

  • Zastosowanie ładowarka dostawca & zawartość (lub po prostu niestandardowe uri).Ładowarka prenumeruje żadnej uri zmian i repozytorium/dao pomocnicy baza powiadomić taki URI jest o każdej zmianie (kiedy insert/update/delete metody zostały nazywa)

context.getContentResolver().notifyChange(uri);

ładowarka dla swoich obiektów.

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

rejestracja połączeń do subskrypcji po zmianie URI.

Lub użyj CursorLoader, ponieważ operujesz bezpośrednio kursorami. Jak widzę w zaktualizowanym pytanie

Wolę drugie podejście, ale pierwszy z nich jest prostsze

+0

Nie rozumiem Cię :( – Hoo

3

Więc po prostu umieścić poniżej kod w moim Zakończone fragmentu Task

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

    } 

Getting wskazówkę od @Swapnil i odpowiedź od https://stackoverflow.com/a/40763755/5261462

3

umieścić poniżej kod na fragmencie onResumse jak ten

@Override 
    public void onResume() { 

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

Co można zrobić, to utworzyć interfejs zgodny z

public interface ReminderCompletedListener 
{ 
    void reminderCompleted(); 
} 

W CompletedTask utwórz instancję tego słuchacza i zarejestruj go w swojej aktywności.

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

W swojej działalności utworzyć metody, które można połączyć z przełącznikiem click słuchacza

((MyActivity) getActivity()).reminderCompleted(); 

To wyzwoli Zakończono Przeładuj podczas wykonywania zadania od karcie przypomnienia. Jednym z głównych czynników, które należy wziąć z tego rozwiązania, jest bezpośrednie powiązanie fragmentów z aktywnością.

Są również inne rozwiązania tego problemu, możesz używać rzeczy takich jak autobus (eventbus/otto), prawdopodobnie również rxjava, możesz je przeglądać, jeśli chcesz, ale rozwiązanie waniliowe, które podałem, powinno wykonać pracę dobrze .