【问题标题】:Maintain fragment's view state维护片段的视图状态
【发布时间】:2014-07-15 08:08:29
【问题描述】:

我已经看到Link1 解决这个问题,但可以正确理解。我有一个加载列表的片段。当我单击列表项时,它会打开另一个活动。但我按下后退按钮它再次加载列表。我希望它与之前的滚动位置相同。在上面提到的链接中,它指定使用标志,但我没有明白这一点。

public class MainActivity extends Activity { 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_dashboard); 
    android.app.Fragment fragment = new MeFragment();    
    getFragmentManager().beginTransaction().replace(R.id.layout_FragmentsContainer, fragment).addToBackStack(null).commit();
   }
}

public class MeFragment extends Fragment
{
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)  
  {
    return inflater.inflate(R.layout.fragment_me, container, false);
  }
  @Override
  public void onActivityCreated(Bundle savedInstanceState) {  
    super.onActivityCreated(savedInstanceState);

    meLV = (ListView) getView().findViewById(R.id.lv_Inbox);
    loadingListProgress = (ProgressBar) getView().findViewById(R.id.progress_LoadingList);  
    meList = new ArrayList<Message>();
    meAdapter = new MessagesListAdapter(getActivity(), meList);  
    //addFooter();
    meLV.setAdapter(meAdapter);
    meLV.setOnItemClickListener(this); 
    pageCount = 0;
    loadmoreProgressDialog = new ProgressDialog(getActivity()); 
    loadmoreProgressDialog.setTitle("Please wait ..."); 
    loadmoreProgressDialog.setMessage("Loading more ...");  
    loadmoreProgressDialog.setCancelable(true);
    loadUserMessages(); 
    meLV.setOnScrollListener(new EndlessScrollListener() {
        @Override
        public void onLoadMore(int page, int totalItemsCount) {
            // TODO Auto-generated method stub
            //addFooter();
            loadmoreProgressDialog.show();
            loadUserMessages();
        }
    }); 
  }  
  @Override
  public void onItemClick(AdapterView<?> parent, View view, int position,
        long id) {
    // TODO Auto-generated method stub
    Utils.showToast_msg(getActivity(), "MessageItemClicked"); 
    ReferralDetailFragment fragment = new ReferralDetailFragment();    
    getFragmentManager().beginTransaction().replace(R.id.layout_FragmentsContainer, fragment).addToBackStack(null).commit();

  }
} 

public class ReferralDetailFragment extends Fragment implements OnClickListener {

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)  
{
    View view = inflater.inflate(R.layout.fragment_referraldetail,container, false);
    linkToAcknowledge   = (TextView) view.findViewById(R.id.lbl_Link_to_Acknowledge);
    return view;  
  }
}

【问题讨论】:

  • 让我彻底解释一下。我在一个活动中加载一个片段A(它从网络加载一个列表)。当用户点击列表项时,它会在同一活动中加载另一个片段B来代替片段A
  • 是的,这就是我需要的。能否请您发布代码 sn-p 您是如何做到的?
  • 我已经用所有完整的代码编辑了帖子,你可以看看有什么问题
  • 我写了一个全新的答案,检查一下,我们应该删除所有那些无用的 cmets。
  • @NoumanBhatti-hey 如果您找到解决方案,请告诉我。

标签: android android-fragments savestate


【解决方案1】:

我在我的应用程序中为此实现了一个简单的解决方案,基本上当您再次按下返回到片段时,会调用 onCreateView()。在 onCreateView() 中你已经完成了所有的初始化,所以我们改变

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)  
{
    View view = inflater.inflate(R.layout.fragment_me, container, false);
    /*
     *Whatever you want to do
     *
     */
    return view;  
}

到:

View view;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)  
{
    if(view==null){

        view = inflater.inflate(R.layout.fragment_me, container, false);
        /*
         *Whatever you want to do
         *
         */
    }
    else{
         ((ViewGroup)view.getParent()).removeView(view);
    }
    return view;  
}

在这里,我们将 View 视图移到外面并使其成为类变量。所以如果是第一次调用fragment,则为null并进行初始化,否则转至else black。 Else 块是必需的,因为onCreateView() 会将它返回的任何内容添加为视图父级的子级,因此由于视图已经存在,我们将其删除,onCreateView 会自动再次添加它。

【讨论】:

    【解决方案2】:

    根据我们在cmets中的交流,我完全删除了我的答案并重新写了一个新的。

    我从我的一个应用程序中复制/粘贴代码并删除无用的内容并更改名称。希望没有太多的打字错误,这是让它工作的最低要求。

    当我从 SecondFragment 弹回 FirstFragment 时,FirstFragment 的滚动位置与我单击某个项目加载 SecondFragment 时的位置相同。

    请注意,我不会扩展 FragmentActivity。我有一个加载片段的活动。

    扩展/修改以满足您的需求。

    主要活动:

    public class MainActivity extends Activity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_layout);
        }
    }
    

    FirstFragment 类:

    public class FirstFragment extends Fragment implements OnItemClickListener {
        private ListView mListView;
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            return inflater.inflate(R.layout.first_fragment_layout, container, false);
        }
    
        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
    
            mListView = (ListView) getView().findViewById(R.id.listview_first_fragment);
            mListView.setAdapter(mAdapter); // depends on your adapter
            mListView.setOnItemClickListener(this);
        }
    
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            mListView.setItemChecked(position, true);
    
            //in case you need, set the bundle here, for example pass the position
            Bundle arguments = new Bundle();
            arguments.putInt("position", position);
            SecondFragment secondFragment = new SecondFragment();
            secondFragment.setArguments(arguments);
    
            getFragmentManager().beginTransaction().replace(R.id.fragment_container, secondFragment).addToBackStack(null).commit();
        }
    }
    

    SecondFragment 类:

    public class SecondFragment extends Fragment {
        private Integer mPosition;
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            return inflater.inflate(R.layout.second_fragment_layout, container, false);
        }
    
        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
    
            Bundle arguments = getArguments();
            if (arguments == null) {
                mPosition= 0;
            } else {
                mPosition= arguments.getInt("Position");
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      您想要实现的目标可以在savedInstanceState 的帮助下完成。我也遇到过这种问题,我在过渡时使用add() 方法而不是replace() 解决了这个问题。 如果你可以改变你的方法或者已经不使用add(),那就试一试。 如果add() 方法没有解决问题,请检查savedInstanceState 的实现。

      1. correctly save instance state.

      2. How to save states of fragment views.

      【讨论】:

        猜你喜欢
        • 2014-09-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-08
        • 1970-01-01
        相关资源
        最近更新 更多