Подтвердить что ты не робот

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

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

    fragment.getView().invalidate();

который, похоже, не работал. Я также пробовал

    fragment.getView().requestLayout();

который тоже не работает.

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

    listfragment.getListView().invalidate();

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

Примечание

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

Ответ 2

В моем случае detach и attach работают для меня.

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

Ответ 3

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

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

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

Ответ 4

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

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

Ответ 5

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

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

Ответ 6

рассмотрим приведенный ниже исходный код. Здесь имя фрагмента - 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();
            }

        }
    }

    }

Ответ 7

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

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

Ответ 8

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

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