Обновить или принудительно перерисовать фрагмент
У меня есть фрагмент, который раздувает макет XML. Мое требование - обновить размер текста во всех моих представлениях внутри фрагмента, когда моя деятельность возобновится. Я старался
fragment.getView().invalidate();
который, казалось, не делал работу. Я тоже пробовал
fragment.getView().requestLayout();
что тоже не сработало.
На другой деятельности у меня есть ListFragment, который должен сделать то же самое. Я старался
listfragment.getListView().invalidate();
который добился цели, обновив мой список и перерисовав все элементы внутри него.
Я не понимаю, почему одно работает, а другое нет.
Я также видел людей, рекомендующих инициировать транзакцию фрагмента и заменять текущий фрагмент новым, и это заставило меня задуматься
Зачем мне создавать новый фрагмент и заменять мой текущий фрагмент, когда все, что мне нужно, это обновить текст в представлениях, которые содержит мой фрагмент.
Метод транзакции фрагмента не позволит мне определить свой фрагмент в макете 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();