本文介绍了Android的碎片状态,只在后退按钮恢复,不能当我从列表视图中选择一个随机片段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个列表视图栏,我根据列表视图用户选择显示片段。

这就是我如何替换片段

 公共无效switchFragment(片段片段,布尔addBackStack){
        尝试{
            FragmentManager经理= getSupportFragmentManager();
            FragmentTransaction英尺= manager.beginTransaction();            ft.replace(R.id.content,片段);
            currentFragment =片段;
           //如果(addBackStack)
                ft.addToBackStack(NULL);
            ft.commit();
        }赶上(例外五){        }
    }

这是我的样品片段code.Now当我更换片段我在保存的onPause实例的状态,并在恢复onresume,但它只有当我preSS后退按钮的工作原理。当我手动从列表视图导航回片段,片段状态不restored.Why?

 公共类片段1扩展BaseFragment {    INT currentFragmentInd = 1;    私人按钮startButton;
    私人按钮endButton;
    私人长期savedStartTime;
    私人TextView的setStartText;
    私人TextView的setEndText;
    私人字符串开始时间;
    私人字符串结束时间;    公众诠释getIndex(){
        MyApplication.getApplication()setCurrentChild(0)。
        MyApplication.getApplication()setCurrentGroup(0)。
        返回currentFragmentInd;
    }    @覆盖
    公共无效onActivityCreated(捆绑savedInstanceState){
        super.onActivityCreated(savedInstanceState);
        如果(savedInstanceState!= NULL)
        {        }
    }    @覆盖
    公共无效onResume(){
        super.onResume();
        setStartText =(TextView中)getActivity()findViewById(R.id.MAtextView2)。
        setEndText =(TextView中)getActivity()findViewById(R.id.MAtextView3)。
        setEndText.setText(结束时间);
        setStartText.setText(开始时间);
    }    @覆盖
    公共无效的onPause(){
        super.onPause();
        setStartText =(TextView中)getActivity()findViewById(R.id.MAtextView2)。
        setEndText =(TextView中)getActivity()findViewById(R.id.MAtextView3)。
        。开始时间= setStartText.getText()的toString();
        。ENDTIME = setEndText.getText()的toString();    }    @覆盖
    公共无效的onSaveInstanceState(捆绑outState){
        super.onSaveInstanceState(outState);
    }    的FrameLayout的FrameLayout;
    @覆盖
    公共查看onCreateView(LayoutInflater充气器,容器的ViewGroup,
                             捆绑savedInstanceState){
        查看内容查看= inflater.inflate(R.layout.layout1,空,假);        ((MainActivity)getActivity())openList(0,0);
        如果(savedInstanceState == NULL){        }        startButton =(按钮)contentView.findViewById(R.id.button);
        endButton =(按钮)contentView.findViewById(R.id.button2);
        endButton.setEnabled(假);        setStartText =(TextView中)contentView.findViewById(R.id.MAtextView2);
        setEndText =(TextView中)contentView.findViewById(R.id.MAtextView3);        startButton.setOnClickListener(新View.OnClickListener(){
            公共无效的onClick(视图v){
                    现在时间=新时代();
                    now.setToNow();
            }
        });        endButton.setOnClickListener(新View.OnClickListener(){
            公共无效的onClick(视图v){                    现在时间=新时代();
                    now.setToNow();                    setEndText.setText(now.hour +:+ now.minute);
            }
        });
        返回内容查看;
    }
}


解决方案

晚重播,但可以帮助别人。
这是因为当你点击一个列表视图项您创建的片段的新inctance。
我想送你去switchFragment(片段片段)的片段,使用的是新的关键字创建的。
因此,一个片段犯规的这个新的实例握住你的旧数据。

这是我如何解决这一点。可能有更好的方法,但因为没有人回答,我会给我的解决方案。


  1. 当您更换片段(ft.replace,片段),给一个字符串引用该事务:-ft.replace(R.id.content,片段,FRAGMENT_NAME);

  2. 当您将片段添加到使用addToBackStack(空)的backstack;把你的片段的名称,你必须空:-ft.addToBackStack(FRAGMENT_NAME);

  3. 创建它告诉你,如果该片段已创建的,因此存在着在后面栈的方法:

    公共布尔isTagInBackStack(字符串标签){

      Log.i(TAGisTagInBackStack()开始);
        INT X;
        布尔toReturn = FALSE;
        INT backStackCount = getSupportFragmentManager()getBackStackEntryCount()。
        Log.i(TAGbackStackCount =+ backStackCount);    为(X = 0; X&下; backStackCount; X ++){
            Log.i(TAG,Iter项目=+ X ++ getSupportFragmentManager()getBackStackEntryAt(X).getName());
            如果(标记== getSupportFragmentManager()。getBackStackEntryAt(X).getName()){
                toReturn = TRUE;        }    }    Log.i(TAGisTagInBackStack()结束,toReturn =+ toReturn);
        返回toReturn;
    }


  4. 现在您在backstack创建片段检查的新实例之前,如果一个名为backstack项FRAGMENT_NAME的存在。
    如果存在的话,可以使用,而不是创建一个新的该项目(片段)。

     如果(isTagInBackStack(FRAGMENT_NAME)){
        Log.i(TAG,标签是BackStack !!!!断枝是=+ getSupportFragmentManager()findFragmentByTag(FRAGMENT_NAME)。);    FragmentTransaction交易= getSupportFragmentManager()调用BeginTransaction()。
        transaction.replace(R.id.main_activity_container,getSupportFragmentManager()findFragmentByTag(FRAGMENT_NAME)。);
        transaction.addToBackStack(FRAGMENT_NAME);
        器transaction.commit();
    }其他{
        创建片段(出现这种情况还是第一次。
    }


Hi i have a listview sidebar and i am displaying fragments based on user selection in listview.

This is how i am replacing fragments

public void switchFragment(Fragment fragment, boolean addBackStack) {
        try {
            FragmentManager manager = getSupportFragmentManager();
            FragmentTransaction ft = manager.beginTransaction();

            ft.replace(R.id.content, fragment);
            currentFragment = fragment;
           //if (addBackStack)
                ft.addToBackStack(null);
            ft.commit();
        } catch (Exception e) {

        }
    }

This is my sample fragment code.Now when i replace fragments i am saving instance state in onpause and restoring it in onresume but it only works when i press back button. When i manually navigate back to fragment from listview ,fragment state is not restored.Why?

public class Fragment1 extends BaseFragment {   

    int currentFragmentInd = 1;  

    private Button startButton;
    private  Button endButton;
    private long savedStartTime;
    private TextView setStartText;
    private TextView setEndText;
    private String starttime;
    private String endtime;

    public int getIndex() {
        MyApplication.getApplication().setCurrentChild(0);
        MyApplication.getApplication().setCurrentGroup(0);
        return currentFragmentInd;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        if (savedInstanceState !=null)
        {      



        }
    }

    @Override
    public void onResume() {
        super.onResume();
        setStartText= (TextView)getActivity().findViewById(R.id.MAtextView2);
        setEndText= (TextView)getActivity().findViewById(R.id.MAtextView3);
        setEndText.setText(endtime);
        setStartText.setText(starttime);
    }

    @Override
    public void onPause() {
        super.onPause();
        setStartText= (TextView)getActivity().findViewById(R.id.MAtextView2);
        setEndText= (TextView)getActivity().findViewById(R.id.MAtextView3);
        starttime=setStartText.getText().toString();
        endtime=setEndText.getText().toString();

    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);


    }

    FrameLayout frameLayout;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View contentView = inflater.inflate(R.layout.layout1, null, false);

        ((MainActivity) getActivity()).openList(0, 0);




        if (savedInstanceState == null) {

        }





        startButton= (Button) contentView.findViewById(R.id.button);
        endButton= (Button) contentView.findViewById(R.id.button2);
        endButton.setEnabled(false);

        setStartText= (TextView)contentView.findViewById(R.id.MAtextView2);
        setEndText= (TextView)contentView.findViewById(R.id.MAtextView3);





        startButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {


                    Time now = new Time();
                    now.setToNow();




            }
        });



        endButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {

                    Time now = new Time();
                    now.setToNow();

                    setEndText.setText(now.hour+" : "+now.minute);


            }
        });


        return contentView;
    }




}
解决方案

Late replay but might help somebody else. This happens because when you click a listview item you create a new inctance of that fragment. "I assume the fragment you send to switchFragment(Fragment fragment), is created using a 'new' keyword."Therefore this new instance of a fragment doesnt hold your old data.

This is how I solved this. There are probably better ways, but since nobody replied, I will give my solution.

  1. When you replace the fragment (ft.replace, fragment), give a string reference to that transaction: -ft.replace(R.id.content, fragment, "FRAGMENT_NAME");
  2. When you add the fragment to the backstack with addToBackStack(null); put the name of your fragment where you have null.: -ft.addToBackStack("FRAGMENT_NAME");
  3. Create a method which tells you if that fragment has already been created, and therefore exists in the back stack.:

    public boolean isTagInBackStack(String tag){

        Log.i(TAG, "isTagInBackStack() Start");
        int x;
        boolean toReturn = false;
        int backStackCount = getSupportFragmentManager().getBackStackEntryCount();
        Log.i(TAG, "backStackCount = " + backStackCount);
    
        for (x = 0; x < backStackCount; x++){
            Log.i(TAG, "Iter = " + x +" "+ getSupportFragmentManager().getBackStackEntryAt(x).getName());
            if (tag == getSupportFragmentManager().getBackStackEntryAt(x).getName()){
                toReturn = true;
    
            }
    
        }
    
        Log.i(TAG, "isTagInBackStack() End, toReturn = " + toReturn);
        return toReturn;
    }
    

  4. Now before you create a new instance of that fragment check in the backstack if a backstack item named "FRAGMENT_NAME" exists.if it exists, use that item (fragment) instead of creating a new one.

    if (isTagInBackStack("FRAGMENT_NAME")){
        Log.i(TAG, "Tag is in BackStack!!!! frag is = " + getSupportFragmentManager().findFragmentByTag("FRAGMENT_NAME"));
    
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.main_activity_container, getSupportFragmentManager().findFragmentByTag("FRAGMENT_NAME"));
        transaction.addToBackStack("FRAGMENT_NAME");
        transaction.commit();
    }else{
        Create the fragment (this happens the first time. 
    }
    

这篇关于Android的碎片状态,只在后退按钮恢复,不能当我从列表视图中选择一个随机片段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-03 13:16