【问题标题】:ViewPager can not remove view in a fragmentViewPager 无法删除片段中的视图
【发布时间】:2016-06-24 20:18:39
【问题描述】:

一个名为 NewsCenterFragment 的片段将替换 DrawerActivity 中的 FramLayout。问题是当我将 viewPager 滑动到下一张幻灯片时程序会崩溃。给出的异常是:java.lang.IllegalStateException: The specified child has a parent.You must call removeView() on the child's parent first.

public class DrawerActivity extends AppCompatActivity
    implements NavigationView.OnNavigationItemSelectedListener,Serializable {
private FragmentManager fm;
private NavigationView navigationView;
private NewsMenu data;
private RadioGroup radioGroup;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_drawer);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    radioGroup = (RadioGroup) findViewById(R.id.content_drawer_radioGroup);
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.setDrawerListener(toggle);
    toggle.syncState();

    navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);
    checkCacheForNewsCenterSlideBar();
    changeNewsSlideBar();
    Fragment homeFragment = new HomeFragment();
    fm = getFragmentManager();
    fm.beginTransaction().replace(R.id.content_drawer_content,homeFragment).commit();
    getSupportActionBar().setTitle("Home page");
    radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            switch (checkedId){

                case R.id.content_drawer_radioGroup_shouye:
                    Fragment homeFragment = new HomeFragment();
                    fm.beginTransaction().replace(R.id.content_drawer_content,homeFragment).commit();
                    getSupportActionBar().setTitle("Home page");
                    break;
                case R.id.content_drawer_radioGroup_newscenter:

                    Fragment newsCenterFragment = new NewsCenterFragment(findNewsTabTitle(),DrawerActivity.this);
                    fm.beginTransaction().replace(R.id.content_drawer_content,newsCenterFragment).commit();
                    getSupportActionBar().setTitle("News center");
                    break;
                case R.id.content_drawer_radioGroup_smartservice:

                    break;
                case R.id.content_drawer_radioGroup_goveraffairs:

                    break;
                case R.id.content_drawer_radioGroup_setting:

                    break;
            }
        }
    });
}

public class NewsCenterFragment extends Fragment {
private ViewPager viewPager;
private Activity mActivity;
private ArrayList<String> title;
private ArrayList<View> views;

public NewsCenterFragment(ArrayList<String> title, Activity activity){
    this.title = title;
    this.mActivity = activity;
}


@Override
public View onCreateView(LayoutInflater layoutInflater, ViewGroup container, Bundle savedInstanceState) {

    LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService(mActivity.LAYOUT_INFLATER_SERVICE);
    View view = inflater.inflate(R.layout.fragment_newscenter_layout,container,false);

    viewPager = (ViewPager) view.findViewById(R.id.fragment_newscenter_viewPager);
    views = new ArrayList<View>();
    View tempLayout = inflater.inflate(R.layout.news_title_layout,container,false);


    for(int i=0;i<title.size();i++){
        views.add(tempLayout);
    }
    viewPager.setAdapter(new NewsMenuDetailAdapter());
    return view;
}
class NewsMenuDetailAdapter extends PagerAdapter{

    @Override
    public int getCount() {
        return views.size();
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view==(LinearLayout)object;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {


        String tabTitle = title.get(position);
               View view = views.get(position);
                TextView textView = (TextView) view.findViewById(R.id.news_title_layout_title);
                textView.setText(tabTitle);
       container.addView(view);
        return view;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((LinearLayout)object);
    }

}

}

java.lang.IllegalStateException:指定的孩子已经有一个父母。您必须先在孩子的父母上调用 removeView()。

我已经搜索了几个小时的解决方案。请帮帮我。非常感谢。

【问题讨论】:

  • DrawerActivity不需要实现viewPager?

标签: android android-fragments android-viewpager


【解决方案1】:

您的 views array 中似乎有 N 个对一个对象的引用:

View tempLayout = inflater.inflate(R.layout.news_title_layout,container,false);

for(int i=0;i<title.size();i++){
    views.add(tempLayout);
}

因此,当您的适配器开始返回项目时,它第一次成功附加了此视图 (tempLayout),但第二次它失败了,因为 tempLayout (i.e. views[i]) 已经有上一次调用 instantiateItem 的父级。

您应该提供另一个膨胀视图或在调用 container.add() 之前调用 ((ViewGroup)child.getParent()).removeView(child)

【讨论】:

  • 但我想在 viewPager 中添加几个相同的布局。我可以这样做吗?或者 viewPager 中的每个布局都必须不同,一个布局文件只能在 viewPager 中存在一次?
  • @BruceHe,只需使用具有相同布局的其他视图即可。例如,在 for-loop 填充视图数组中移动 tmpLayout 的膨胀。问题是在你的数组中 N 引用了一个对象。改为使用一种布局使其成为 N 个对象。
  • for(int i=0;i
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多