【问题标题】:Refresh or force redraw the fragment刷新或强制重绘片段
【发布时间】:2013-03-07 03:53:23
【问题描述】:

我有一个扩展 xml 布局的片段。我的要求是在我的活动恢复时更新片段内所有视图的文本大小。我试过了

    fragment.getView().invalidate();

这似乎没有做这项工作。我也试过了

    fragment.getView().requestLayout();

这也没用。

在另一个活动中,我有一个 ListFragment 需要做同样的事情。我试过了

    listfragment.getListView().invalidate();

成功了,刷新了我的列表视图并重绘了其中的所有项目。

我不明白为什么一个有效,而另一个无效。

我还看到有人建议发起 片段事务 并用新片段替换当前片段,这让我感到疑惑

  1. 当我只需要刷新我的片段包含的视图上的文本时,我为什么要创建一个全新的片段并替换我当前的片段。

  2. 片段事务方法将阻止我在我的活动的布局 xml 中定义我的片段,我必须以编程方式将片段插入到正确的位置。

有什么简单的方法吗?

【问题讨论】:

  • 更新 TextView 之类的文本大小的已知属性不是您应该调用 invalidate() 的那种事情;当属性更改时,框架会为您执行此操作。也许显示您正在更新文本属性的代码;问题更可能存在。唯一需要手动 invalidate() 视图的情况是创建 Android 不知道的自定义属性。
  • 片段负责在它包含的所有视图中加载数据,并且在填充该数据时,它正在检查用户从首选项设置的文本大小,当时它正在设置该大小。我相信如果大小发生显着变化,视图必须自行调整以包装内容,因此需要重绘。而且即使是自定义属性而不是文本大小,我们如何强制片段视图重绘自身?
  • 再次,当您设置文本值时,视图/布局系统知道它需要重新测量和重新绘制。只需查看 TextView 源代码中的setRawTextSize()(第 2406 行)...属性更新后会调用什么? android.googlesource.com/platform/frameworks/base/+/refs/heads/… 另外,顺便说一句,invalidate() 不会强制视图自行调整,requestLayout() 会这样做。
  • 奇怪的是 requestLayout 在这种情况下对我不起作用。我现在明白你所说的关于更改文本大小的内容,但我想知道是否需要重新绘制片段视图,我将如何实现?
  • 我遇到了同样的问题。根据这里未回答的问题的数量,我想知道我是否真的了解 View 元素应该如何工作。

标签: android android-fragments


【解决方案1】:

我认为没有办法做到这一点。片段在 onCreateView() 上重建它的 UI ...但是在创建或重新创建片段时会发生这种情况。

您必须实现自己的 updateUI 方法,或者在哪里指定哪些元素以及它们应该如何更新。这是一个很好的做法,因为无论如何在创建片段时都需要这样做。

但是,如果这还不够,你可以做一些事情,比如用相同的片段替换片段,强制它调用onCreateView()

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

注意

要刷新 ListView,您需要在 ListView 的适配器上调用 notifyDataSetChanged()

【讨论】:

【解决方案2】:

就我而言,detachattach 有效:

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

【讨论】:

  • 原文已更新我的评论,使我的评论不再相关,所以我将其删除。
  • 这个解决方案损坏了我的后台
  • 是的,我只需要刷新一个适配器,分离和重新连接似乎有点过头了(即使它看起来是唯一的解决方案)
【解决方案3】:

使用以下代码再次刷新片段:

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

【讨论】:

    【解决方案4】:

    detach().detach() 在支持库更新 25.1.0(可能更早)后无法正常工作。 此解决方案在更新后运行良好:

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

    【讨论】:

    • 在更新到更新的支持库版本之前一切正常,但这个解决方案救了我!快速说明——我必须使用runOnUiThread() 才能使用commitNowAllowingStateLoss,但没有它就行不通。
    【解决方案5】:

    为了解决这个问题,我用这个:

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

    【讨论】:

    • 标签在哪里?我如何找到它?我正在向 Sqlite Db 添加一些内容。完成后,我想从活动中刷新片段。
    【解决方案6】:

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

    【讨论】:

      【解决方案7】:

      我正在使用 remove 和 replace 来刷新 Fragment 的内容,例如

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

      【讨论】:

      • 您的建议导致应用崩溃。
      【解决方案8】:

      让我们看看下面的源代码。这里片段名称是 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();
                  }
      
              }
          }
      
          }
      

      【讨论】:

        猜你喜欢
        • 2013-08-30
        • 2014-04-26
        • 2013-11-03
        • 2012-02-09
        • 1970-01-01
        • 1970-01-01
        • 2017-08-30
        • 1970-01-01
        相关资源
        最近更新 更多