在用嵌套片段替换listfragment之后,视图控件将保留



我有一个选项卡式视图活动,有3个选项卡,每个选项卡中有一个片段。这些片段由链接到视图寻呼机的FragmentPageAdapter管理。

一切都很好,直到我尝试有一个第四个片段(ServiceSpecifNotListFragment),它将是FragmentPageAdapter管理的片段之一(ServicesListFragment)的嵌套片段。

当我尝试用ServiceSpecifNotListFragment替换ServicesListFragment时。我设法用ServiceSpecifNotListFragment只替换了ServicesListFragment中的列表元素,ServicesListFragment的另一个视图控制器(按钮)仍然存在。。。。

我一直想知道问题是否在于这样一个事实:我用它的子片段替换片段的方法是transaction.replace(R.id.service_list_fragment, newFragment).commit();,而service_list_fragment是listfragment主线性布局的id,该布局包含用id:@id/android:list 定义的列表视图

最接近的问答;A我发现这是一个,但据我所知,我正确地使用了碎片容器id。

这是代码和布局:

ServicesListFragment(嵌套片段的父级)的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:orientation="vertical"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:id="@+id/service_list_fragment">
      <Button
      android:id="@+id/addServiceButton"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:text="AddService" />
     <ListView android:id="@id/android:list"
               android:layout_width="match_parent"
               android:layout_height="0dip"
               android:layout_weight="1"
               android:drawSelectorOnTop="false"/>
     <TextView android:id="@id/android:empty"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
               android:text="No data"/>
</LinearLayout>

ServiceSpecifNotListFragment(要嵌套的片段)的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:orientation="vertical"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:id="@+id/service_notif_list_fragment" >    
     <ListView android:id="@id/android:list"
               android:layout_width="match_parent"
               android:layout_height="0dip"
               android:layout_weight="1"
               android:drawSelectorOnTop="false"/>
     <TextView android:id="@id/android:empty"
               android:layout_width="match_parent"
               android:layout_height="match_parent"
               android:text="No data"/>
</LinearLayout> 

主活动xml布局(它基本上是对寻呼机的引用):

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</android.support.v4.view.ViewPager>

ServiceListFragment的源代码,对片段嵌套的调用在onListItemClick:中

public class ServicesListFragment extends ListFragment  {
    private final String TAG = "ServicesListFragment";
    Button addButton = null;
    ServiceNotifRowAdapter adapter;
    ArrayList<NotifService> list = new ArrayList<NotifService>();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Activity parent = getActivity();
        // some ommited code for populating adapter with list of stored subscriptions
            adapter = new ServiceNotifRowAdapter(getActivity().getApplicationContext(),list);
        setListAdapter(adapter);
    }
      @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.servicelist_fragment, container, false);
            addButton = (Button) rootView.findViewById(R.id.addServiceButton);
            MainActivity m = (MainActivity) getActivity();
            addButton.setOnClickListener(m);
            return rootView;
        }
      @Override
      public void onListItemClick(ListView l, View v, int position, long id) {
          NotifService  item = (NotifService) getListAdapter().getItem(position);
          Log.d(TAG, "selected service " + item.getServiceURI());

        Fragment newFragment = new ServiceSpecifNotListFragment();
        Bundle bundle = new Bundle();
        bundle.putString("service", item.getServiceURI());
        newFragment.setArguments(bundle);
                FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
                transaction.addToBackStack(null);
                transaction.replace(R.id.service_list_fragment, newFragment).commit();
      }

主要活动java代码

public class MainActivity extends FragmentActivity implements TabListener, AddServiceDialogFragmentListener
, OnClickListener{
    private final String TAG = "MQTT main activity";
    private ViewPager viewPager;
    private TabsPagerAdapter mAdapter;
    private ActionBar actionBar;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Initilization
        viewPager = (ViewPager) findViewById(R.id.pager);
        actionBar = getActionBar();
        List<Fragment> fragments = new Vector<Fragment>();
        fragments.add(Fragment.instantiate(this, StatusListFragment.class.getName()));
        fragments.add(Fragment.instantiate(this, ServicesListFragment.class.getName()));
        fragments.add(Fragment.instantiate(this, ConfigFragment.class.getName()));
        mAdapter = new TabsPagerAdapter(getSupportFragmentManager(),fragments);
        viewPager.setAdapter(mAdapter);
        actionBar.setHomeButtonEnabled(false);
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);        
        // Adding Tabs
        for (String tab_name : MqttApplication.tabs) {
            actionBar.addTab(actionBar.newTab().setText(tab_name)
                    .setTabListener(this));
        }
        /**
         * on swiping the viewpager make respective tab selected
         * */
        viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                // on changing the page
                // make respected tab selected
                actionBar.setSelectedNavigationItem(position);
            }
            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
            }
            @Override
            public void onPageScrollStateChanged(int arg0) {
            }
        });
        // lock the screen in portrait mode
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {
        // TODO Auto-generated method stub
    }
    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        viewPager.setCurrentItem(tab.getPosition());
    }
    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        // TODO Auto-generated method stub
    }

}

标签页适配器

public class TabsPagerAdapter extends FragmentPagerAdapter {
    private List<Fragment> fragments;
    private FragmentManager fm;
    private final String TAG = "TabsPagerAdapter";

    public TabsPagerAdapter(FragmentManager fm,List<Fragment> fragments) {
        super(fm);
        this.fm = fm;
        this.fragments = fragments;
    }
    @Override
    public Fragment getItem(int index) {
           return  this.fragments.get(index);
    }
    @Override
    public int getCount() {
        return this.fragments.size();
    }
    // 0 - Status, 1 Service, 2 Config (due to the order in which they have been added)
    public Fragment findFragmentByPosition(int position) {
        return fm.findFragmentByTag(
                "android:switcher:" + R.id.pager + ":"
                        + this.getItemId(position));
    }
}

只是一个替代解决方案:在代码中实现回调,并要求视图寻呼机在ServiceListFragment中单击项目时加载SpecificListNotFragment。看一看,试试看!

 public class ServicesListFragment extends ListFragment  {
    private final String TAG = "ServicesListFragment";
    Button addButton = null;
    ServiceNotifRowAdapter adapter;
    ArrayList<NotifService> list = new ArrayList<NotifService>();
    private onListItemClickCallbackListener mCallback;
    public interface onListItemClickCallbackListener {
        public void replaceFragmentToServiveListNot();
    }
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Activity parent = getActivity();
        mCallback = parent; // remember to imlement onListItemClickCallbackListener in activity else it will give error
        // some ommited code for populating adapter with list of stored subscriptions
            adapter = new ServiceNotifRowAdapter(getActivity().getApplicationContext(),list);
        setListAdapter(adapter);
    }
      @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.servicelist_fragment, container, false);
            addButton = (Button) rootView.findViewById(R.id.addServiceButton);
            MainActivity m = (MainActivity) getActivity();
            addButton.setOnClickListener(m);
            return rootView;
        }
      @Override
      public void onListItemClick(ListView l, View v, int position, long id) {
          NotifService  item = (NotifService) getListAdapter().getItem(position);
          Log.d(TAG, "selected service " + item.getServiceURI());
            mCallback.replaceFragmentToServiveListNot();
      }
     }

     public class MainActivity extends FragmentActivity implements TabListener, AddServiceDialogFragmentListener
, OnClickListener,onListItemClickCallbackListener {
    private final String TAG = "MQTT main activity";
    private ViewPager viewPager;
    private TabsPagerAdapter mAdapter;
    private ActionBar actionBar;
    List<Fragment> fragments;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Initilization
        viewPager = (ViewPager) findViewById(R.id.pager);
        actionBar = getActionBar();
        fragments = new Vector<Fragment>();
        fragments.add(Fragment.instantiate(this, StatusListFragment.class.getName()));
        fragments.add(Fragment.instantiate(this, ServicesListFragment.class.getName()));
        fragments.add(Fragment.instantiate(this, ConfigFragment.class.getName()));
        mAdapter = new TabsPagerAdapter(getSupportFragmentManager(),fragments);
        viewPager.setAdapter(mAdapter);
        actionBar.setHomeButtonEnabled(false);
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);        
        // Adding Tabs
        for (String tab_name : MqttApplication.tabs) {
            actionBar.addTab(actionBar.newTab().setText(tab_name)
                    .setTabListener(this));
        }
        /**
         * on swiping the viewpager make respective tab selected
         * */
        viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                // on changing the page
                // make respected tab selected
                actionBar.setSelectedNavigationItem(position);
            }
            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
            }
            @Override
            public void onPageScrollStateChanged(int arg0) {
            }
        });
        // lock the screen in portrait mode
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {
        // TODO Auto-generated method stub
    }
    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        viewPager.setCurrentItem(tab.getPosition());
    }
    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        // TODO Auto-generated method stub
    }
    @Override
    public void replaceFragmentToServiveListNot() {
        fragments.removeAll(fragments);
        fragments.add(Fragment.instantiate(this, StatusListFragment.class.getName()));
        fragments.add(Fragment.instantiate(this, ServiceSpecifNotListFragment.class.getName()));
        fragments.add(Fragment.instantiate(this, ConfigFragment.class.getName()));
        mAdapter.notifyDataSetChanged();
    }

}

最新更新