2013-03-07 15 views
39

Mam fragment, który nadyma układ xml. Moim wymaganiem jest aktualizacja rozmiaru tekstu we wszystkich moich widokach wewnątrz mojego fragmentu, gdy moja aktywność zostanie wznowiona. Próbowałem wykonać jedną z następujących czynności:Odśwież lub wymuś przerysowanie fragmentu.

która nie działała. Próbowałem również

fragment.getView().requestLayout(); 

który również nie działa.

Na innej czynności mam ListFragment, który musi zrobić to samo. Próbowałem

listfragment.getListView().invalidate(); 

który wystarczyły, orzeźwiający mojego widoku listy i przerysowywania wszystkie elementy wewnątrz niego.

Nie rozumiem, dlaczego jeden działa, ale nie drugi.

widziałem też ludzi zalecających inicjowanie transakcji fragment i zastąpienie obecnego fragment z nowym, i to trzymało mnie zastanawiasz

  1. Dlaczego należy utworzyć zupełnie nowy fragment i zastąpić mój obecny fragment, gdy wszystko, czego potrzebuję, to odświeżenie tekstu na widokach, które zawiera mój fragment.

  2. Metoda transakcji fragmentu uniemożliwi mi zdefiniowanie mojego fragmentu w układzie xml mojej aktywności i będę musiał programowo wstawić fragment we właściwym miejscu.

Czy istnieje proste podejście do tego?

+0

Aktualizacja znaną właściwością 'TextView' jak rozmiar tekstu nie jest to rodzaj rzeczy powinieneś wywołać 'invalidate()' for; struktura robi to dla ciebie, gdy właściwość się zmienia. Być może pokaż kod, w którym aktualizujesz właściwości tekstu; problem jest tam bardziej prawdopodobny. Jedyny przypadek, w którym powinieneś kiedykolwiek koniecznie ręcznie "unieważnić()" widok, to własność niestandardowa, o której Android nie wie. – Devunwired

+0

Fragment odpowiada za ładowanie danych we wszystkich widokach, które zawiera, a podczas zapełniania tych danych sprawdza rozmiar tekstu ustawiony przez użytkownika w Preferencjach iw tym momencie ustawia ten rozmiar. Wierzę, że jeśli rozmiar zmieni się znacząco, widoki muszą się dostosować, aby zawinąć zawartość, a więc trzeba przerysować. I nawet jeśli jest to właściwość niestandardowa zamiast rozmiaru tekstu, jak zmusić widok fragmentu do przerysowania samego siebie? – ps2010

+0

Ponownie, po ustawieniu wartości tekstu system widoku/układu wie, że musi ponownie zmierzyć i ponownie narysować. Wystarczy spojrzeć na 'setRawTextSize()' w źródłach TextView (linia 2406) ... co wywołuje się po aktualizacji właściwości? https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/widget/TextView.java Również, na bok, 'invalidate()' nie wymusza wyświetleń aby się dostosować, 'requestLayout()' robi to. – Devunwired

Odpowiedz

24

Nie sądzę, że istnieje na to metoda. Fragment odbudowuje jego interfejs użytkownika onCreateView() ... ale dzieje się tak, gdy fragment zostanie utworzony lub odtworzony.

Będziesz musiał zaimplementować własną metodę updateUI lub określić, jakie elementy i jak powinny być aktualizowane. Jest to raczej dobra praktyka, ponieważ musisz to zrobić, gdy fragment zostanie utworzony.

Jednak jeśli to nie wystarczy, można zrobić coś jak zastąpienie fragmentu z tego samego jednego zmuszając go nazwać onCreateView()

FragmentTransaction tr = getFragmentManager().beginTransaction(); 
tr.replace(R.id.your_fragment_container, yourFragmentInstance); 
tr.commit() 

UWAGA

Aby odświeżyć ListView trzeba zadzwonić notifyDataSetChanged() na Adapter ListView.

+0

Dla mojego przypadku użycia, dodanie widoku ponownie wykonało lewę. –

+0

Każda pomoc tutaj: http://stackoverflow.com/questions/40095826/how-to-update-a-fragment-that-has-a-gridview-populated-od-sqlite/40096402?noredirect=1#comment67569523_40096402 – Si8

19

W moim przypadku dla mnie działają detach i attach.

getSupportFragmentManager() 
       .beginTransaction() 
       .detach(contentFragment) 
       .attach(contentFragment) 
       .commit(); 
+0

@ swooby Dlaczego dokładnie? –

+0

Oryginalny tekst został zaktualizowany w/moim komentarzem, dzięki czemu mój komentarz nie jest już odpowiedni, więc go usuwam. – swooby

+9

to rozwiązanie uszkadza mój plecak – ElizaS

1

Aby rozwiązać ten problem, użyj tego:

Fragment frg = null; 
frg = getFragmentManager().findFragmentByTag("Feedback"); 
final android.support.v4.app.FragmentTransaction ft = getFragmentManager().beginTransaction(); 
ft.detach(frg); 
ft.attach(frg); 
ft.commit(); 
+0

Gdzie jest tag? Jak go znaleźć? Dodaję coś do Sqlite Db. Chciałbym odświeżyć Fragment z Acvitiy, kiedy już to zrobię. – Si8

3

detach().detach() nie działa po aktualizacji biblioteki wsparcie 25.1.0 (może być wcześniej). To rozwiązanie działa prawidłowo po aktualizacji:

getSupportFragmentManager() 
    .beginTransaction() 
    .detach(oldFragment) 
    .commitNowAllowingStateLoss(); 

getSupportFragmentManager() 
    .beginTransaction() 
    .attach(oldFragment) 
    .commitAllowingStateLoss(); 
+0

Wszystko działało przed aktualizacją do nowszej wersji biblioteki pomocy technicznej, ale to rozwiązanie uratowało mnie! Szybka uwaga - musiałem użyć 'runOnUiThread()', aby użyć 'commitNowAllowingStateLoss', ale nie byłoby bez niego. –

-1

używam usunąć i zastąpić zarówno dla orzeźwiającym treści Fragment jak

final FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 
fragmentTransaction.remove(resetFragment).commit(); 
fragmentTransaction.replace(R.id.frame_container,resetFragment).commit(); 
+0

Twoja sugestia powoduje awarię aplikacji. –

1

ten pracował dla mnie od wewnątrz Fragment:

Fragment frg = null; 
    Class fragmentClass; 
    fragmentClass = MainFragment.class; 
try { 
     frg = (android.support.v4.app.Fragment)  fragmentClass.newInstance(); 
    }catch(Exception ex){ 
     ex.printStackTrace(); 
    } 
       getFragmentManager().beginTransaction().replace(R.id.flContent, frg).commit(); 
0

zobaczmy poniższy kod źródłowy. Tutaj nazwa fragmentu to DirectoryOfEbooks. Po wykonaniu zadania w tle zastępuję ramkę bieżącym fragmentem. więc fragment zostanie odświeżony i przeładowuje jego dane

import android.app.ProgressDialog; 
    import android.content.DialogInterface; 
    import android.database.Cursor; 
    import android.database.sqlite.SQLiteDatabase; 
    import android.os.AsyncTask; 
    import android.os.Bundle; 
    import android.support.v4.app.Fragment; 
    import android.support.v4.app.FragmentTransaction; 
    import android.support.v4.view.MenuItemCompat; 
    import android.support.v7.app.AlertDialog; 
    import android.support.v7.widget.DefaultItemAnimator; 
    import android.support.v7.widget.GridLayoutManager; 
    import android.support.v7.widget.LinearLayoutManager; 
    import android.support.v7.widget.RecyclerView; 
    import android.support.v7.widget.SearchView; 
    import android.view.LayoutInflater; 
    import android.view.Menu; 
    import android.view.MenuInflater; 
    import android.view.MenuItem; 
    import android.view.View; 
    import android.view.ViewGroup; 
    import android.widget.TextView; 
    import android.widget.Toast; 

    import com.github.mikephil.charting.data.LineRadarDataSet; 

    import java.util.ArrayList; 
    import java.util.List; 


    /** 
    * A simple {@link Fragment} subclass. 
    */ 
    public class DirectoryOfEbooks extends Fragment { 

     RecyclerView recyclerView; 
     branchesAdapter adapter; 
     LinearLayoutManager linearLayoutManager; 
     Cursor c; 
     FragmentTransaction fragmentTransaction; 
     SQLiteDatabase db; 
     List<branch_sync> directoryarraylist; 

     public DirectoryOfEbooks() { 
      // Required empty public constructor 
     } 
     @Override 
     public View onCreateView(LayoutInflater inflater, ViewGroup container, 
           Bundle savedInstanceState) { 


      View view = inflater.inflate(R.layout.fragment_directory_of_ebooks, container, false); 
      directoryarraylist = new ArrayList<>(); 
      db = getActivity().openOrCreateDatabase("notify", android.content.Context.MODE_PRIVATE, null); 
      c = db.rawQuery("select * FROM branch; ", null); 

      if (c.getCount() != 0) { 
       c.moveToFirst(); 
       while (true) { 
        //String ISBN = c.getString(c.getColumnIndex("ISBN")); 
        String branch = c.getString(c.getColumnIndex("branch")); 

        branch_sync branchSync = new branch_sync(branch); 
        directoryarraylist.add(branchSync); 
        if (c.isLast()) 
         break; 
        else 
         c.moveToNext(); 
       } 

       recyclerView = (RecyclerView) view.findViewById(R.id.directoryOfEbooks); 
       adapter = new branchesAdapter(directoryarraylist, this.getContext()); 
       adapter.setHasStableIds(true); 
       recyclerView.setItemAnimator(new DefaultItemAnimator()); 
       System.out.println("ebooks"); 
       recyclerView.setHasFixedSize(true); 
       linearLayoutManager = new LinearLayoutManager(this.getContext()); 
       recyclerView.setLayoutManager(linearLayoutManager); 
       recyclerView.setAdapter(adapter); 
       System.out.println(adapter.getItemCount()+"adpater count"); 

      } 
      // Inflate the layout for this fragment 
      return view; 
     } 
     public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      //setContentView(R.layout.fragment_books); 
      setHasOptionsMenu(true); 
     } 
     public void onPrepareOptionsMenu(Menu menu) { 
      MenuInflater inflater = getActivity().getMenuInflater(); 
      inflater.inflate(R.menu.refresh, menu); 
      MenuItem menuItem = menu.findItem(R.id.refresh1); 
      menuItem.setVisible(true); 
     } 
     public boolean onOptionsItemSelected(MenuItem item) { 
      if (item.getItemId() == R.id.refresh1) { 
       new AlertDialog.Builder(getContext()).setMessage("Refresh takes more than a Minute").setPositiveButton("Refresh Now", new DialogInterface.OnClickListener() { 

        public void onClick(DialogInterface dialog, int which) { 

         new refreshebooks().execute(); 
        } 
       }).setNegativeButton("Refresh Later", new DialogInterface.OnClickListener() { 
        public void onClick(DialogInterface dialog, int which) { 

        } 
       }).setCancelable(false).show(); 

      } 
      return super.onOptionsItemSelected(item); 
     } 

    public class refreshebooks extends AsyncTask<String,String,String>{ 
     ProgressDialog progressDialog; 
     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
      progressDialog=new ProgressDialog(getContext()); 
      progressDialog.setMessage("\tRefreshing Ebooks ....."); 
      progressDialog.setCancelable(false); 
      progressDialog.show(); 
     } 

     @Override 
     protected String doInBackground(String... params) { 
      Ebooksync syncEbooks=new Ebooksync(); 
      String status=syncEbooks.syncdata(getContext()); 
      return status; 

     } 

     @Override 
     protected void onPostExecute(String s) { 
      super.onPostExecute(s); 
      if(s.equals("error")){ 
       progressDialog.dismiss(); 
       Toast.makeText(getContext(),"Refresh Failed",Toast.LENGTH_SHORT).show(); 
      } 
      else{ 
       fragmentTransaction = getActivity().getSupportFragmentManager().beginTransaction(); 
       fragmentTransaction.replace(R.id.mainframe, new DirectoryOfEbooks()); 
       fragmentTransaction.commit(); 
       progressDialog.dismiss(); 
       adapter.notifyDataSetChanged(); 
       Toast.makeText(getContext(),"Refresh Successfull",Toast.LENGTH_SHORT).show(); 
      } 

     } 
    } 

    } 
0

użyć następującego kodu do orzeźwiającym fragmentu ponownie:

FragmentTransaction ftr = getFragmentManager().beginTransaction();       
ftr.detach(EnterYourFragmentName.this).attach(EnterYourFragmentName.this).commit();