【问题标题】:View controls remain after listfragment is replaced by nested fragmentlistfragment 被嵌套片段替换后视图控件仍然存在
【发布时间】:2013-11-28 17:00:50
【问题描述】:

我有一个选项卡式视图活动,其中包含 3 个选项卡和每个选项卡中的一个片段。这些片段由链接到查看器的FragmentPageAdapter 管理。

一切正常,直到我尝试拥有第 4 个片段 (ServiceSpecifNotListFragment),它是由 @987654323 管理的片段之一 (ServicesListFragment) 的嵌套片段@。

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

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

我找到的最接近的问答是this one,但据我所知,我正确使用了片段容器 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布局(基本上是对pager的引用):

<?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));
    }

}

【问题讨论】:

  • 能否请您发布您用于加载父片段的 xml 和 java 文件?即您已实现片段寻呼机适配器的文件

标签: java android android-layout android-fragments android-listfragment


【解决方案1】:

只是一个替代解决方案:在您的代码中实现回调,并要求您的视图寻呼机在 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();
    }


}

【讨论】:

  • 我在这里尝试过,但是没有用...我想知道 FragmentPagerAdapter 是否以某种方式使旧片段保持活动状态,因为我没有看到有关重新创建片段的任何日志记录, 虽然我看到 replaceFragmentToServiveListNot 已被调用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-22
相关资源
最近更新 更多