Обновить или принудительно перерисовать фрагмент

У меня есть фрагмент, который раздувает макет XML. Мое требование - обновить размер текста во всех моих представлениях внутри фрагмента, когда моя деятельность возобновится. Я старался

    fragment.getView().invalidate();

который, казалось, не делал работу. Я тоже пробовал

    fragment.getView().requestLayout();

что тоже не сработало.

На другой деятельности у меня есть ListFragment, который должен сделать то же самое. Я старался

    listfragment.getListView().invalidate();

который добился цели, обновив мой список и перерисовав все элементы внутри него.

Я не понимаю, почему одно работает, а другое нет.

Я также видел людей, рекомендующих инициировать транзакцию фрагмента и заменять текущий фрагмент новым, и это заставило меня задуматься

  1. Зачем мне создавать новый фрагмент и заменять мой текущий фрагмент, когда все, что мне нужно, это обновить текст в представлениях, которые содержит мой фрагмент.

  2. Метод транзакции фрагмента не позволит мне определить свой фрагмент в макете XML моей деятельности, и мне придется программно вставлять фрагмент в правильное положение.

Есть ли простой подход к этому?

8 ответов

Я не думаю, что есть способ для этого. Фрагмент перестраивает свой интерфейс на onCreateView()... но это происходит, когда фрагмент создается или воссоздается.

Вам нужно будет реализовать собственный метод updateUI или указать, какие элементы и как они должны обновлять. Это довольно хорошая практика, так как вам нужно делать это, когда фрагмент создается в любом случае.

Однако, если этого недостаточно, вы можете сделать что-то вроде замены фрагмента тем же самым, заставив его вызвать onCreateView()

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

НОТА

Чтобы обновить ListView вам нужно позвонить notifyDataSetChanged() на адаптере ListView.

В моем случае,detach а также attach работать на меня.

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

detach().detach() не работает после обновления библиотеки поддержки 25.1.0 (может быть раньше). Это решение прекрасно работает после обновления:

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

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

Используйте следующий код для обновления фрагмента снова:

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

Это сработало для меня из фрагмента:

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

Чтобы решить проблему, я использую это:

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

Давайте посмотрим на исходный код ниже. Здесь фрагмент называется DirectoryOfEbooks. После завершения фоновой задачи я заменяю фрейм текущим фрагментом. поэтому фрагмент обновляется и перезагружает свои данные

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

        }
    }

    }

Я использую удалить и заменить оба для обновления содержимого фрагмента, как

final FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.remove(resetFragment).commit();
fragmentTransaction.replace(R.id.frame_container,resetFragment).commit();
Другие вопросы по тегам