OnPageScrolled ViewPager Android期间出现IllegalStateException

时间:2015-05-24 19:51:25

标签: android android-viewpager illegalstateexception fragmentpageradapter

我正在尝试使用以下链接here

创建一个无限滚动的carousal

现在我使用了这个并根据需要进行了修改。但事情出了问题我无法解决。这是我的代码:

    package com.greycodes.orissatourism.destinations;
    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentActivity;
    import android.support.v4.view.ViewPager;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;

    import com.greycodes.orissatourism.Carousel.MyPagerAdapter;
    import com.greycodes.orissatourism.R;

    public class DestinationsFragment extends Fragment {
    public DestinationsFragment(){
      }
    public final static int PAGES = 5;
// You can choose a bigger number for LOOPS, but you know, nobody will fling
// more than 1000 times just in order to test your "infinite" ViewPager :D 
public final static int LOOPS = 1000; 
public final static int FIRST_PAGE = PAGES * LOOPS / 2;
public final static float BIG_SCALE = 1.0f;
public final static float SMALL_SCALE = 0.7f;
public final static float DIFF_SCALE = BIG_SCALE - SMALL_SCALE;

public MyPagerAdapter adapter;
public ViewPager pager;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    View rootView = inflater.inflate(R.layout.activity_5,container,false);
    pager = (ViewPager) rootView.findViewById(R.id.myviewpager);

    adapter = new MyPagerAdapter(getFragmentManager(),pager.getId());
    pager.setAdapter(adapter);
    pager.setOnPageChangeListener(adapter);


    // Set current item to the middle page so we can fling to both
    // directions left and right
    pager.setCurrentItem(FIRST_PAGE,true);

    // Necessary or the pager will only have one extra page to show
    // make this at least however many pages you can see
    pager.setOffscreenPageLimit(10);

    // Set margin for pages as a negative number, so a part of next and 
    // previous pages will be showed
    //pager.setPageMargin(-200);
    return rootView;
   }
   @Override
   public void onResume(){
    super.onResume();
 getActivity().setTitle("Destinations");
 }  
}

这是适配器

package com.greycodes.orissatourism.Carousel;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;

import com.greycodes.orissatourism.HomeActivity;
import com.greycodes.orissatourism.R;
import com.greycodes.orissatourism.destinations.DestinationsFragment;

public class MyPagerAdapter extends FragmentPagerAdapter implements
    ViewPager.OnPageChangeListener {

private MyLinearLayout cur = null;
private MyLinearLayout next = null;
private FragmentManager fm;
private long id;
private float scale;

public MyPagerAdapter(FragmentManager fm,long id) {
    super(fm);
    this.fm = fm;
    this.id=id;
}

@Override
public Fragment getItem(int position) 
{
    // make the first pager bigger than others
    if (position == DestinationsFragment.FIRST_PAGE)
        scale = DestinationsFragment.BIG_SCALE;
    else
        scale = DestinationsFragment.SMALL_SCALE;

    position = position % DestinationsFragment.PAGES;
    Fragment f=new MyFragment();
    Bundle b=new Bundle();
    b.putInt("pos", position);
    b.putFloat("scale", scale);
    f.setArguments(b);
    return f;
}

@Override
public int getCount()
{       
    return DestinationsFragment.PAGES * DestinationsFragment.LOOPS;
}
@Override
public float getPageWidth(int position){
    return 0.33f;
}

@Override
public void onPageScrolled(int position, float positionOffset,
        int positionOffsetPixels) 
{   
    if (positionOffset >= 0f && positionOffset <= 1f)
    {
        cur = getRootView(position);
        next = getRootView(position +1);

        cur.setScaleBoth(DestinationsFragment.BIG_SCALE 
                - DestinationsFragment.DIFF_SCALE * positionOffset);
        next.setScaleBoth(DestinationsFragment.SMALL_SCALE 
                + DestinationsFragment.DIFF_SCALE * positionOffset);
    }
}

@Override
public void onPageSelected(int position) {}

@Override
public void onPageScrollStateChanged(int state) {}

private MyLinearLayout getRootView(int position)
{
    return (MyLinearLayout) 
            fm.findFragmentByTag(this.getFragmentTag(position))
            .getView().findViewById(R.id.root);
}
private String getFragmentTag(int position)
{
    return "android:switcher:" +id+ ":" + position;
 }
}

这是Myfragment

 package com.greycodes.orissatourism.Carousel;

 import android.os.Bundle; 
 import android.support.v4.app.Fragment;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.LinearLayout;
 import android.widget.TextView;

 import com.greycodes.orissatourism.R;

 public class MyFragment extends Fragment {
  public MyFragment(){}

 private MyLinearLayout l;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
     View rootView=inflater.inflate(R.layout.viewpager_item, container,false);
     l = (MyLinearLayout) rootView.findViewById(R.id.root);
    int pos = this.getArguments().getInt("pos");
    TextView tv = (TextView) l.findViewById(R.id.text);
    tv.setText("Position = " + pos);

    //MyLinearLayout root = (MyLinearLayout) l.findViewById(R.id.root);
    float scale = this.getArguments().getFloat("scale");
    l.setScaleBoth(scale);

    return l;
}
@Override
public void onDestroyView(){
    super.onDestroyView();
    if(l!=null){
        ViewGroup viewGroup=(ViewGroup)l.getParent();
        if(viewGroup!=null){
            viewGroup.removeAllViews();
        }
    }
}

}

这是MyLinearLayout

package com.greycodes.orissatourism.Carousel;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.widget.LinearLayout;

import com.greycodes.orissatourism.destinations.DestinationsFragment;

public class MyLinearLayout extends LinearLayout {
    private float scale = DestinationsFragment.BIG_SCALE;

   public MyLinearLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public MyLinearLayout(Context context) {
    super(context);
}

public void setScaleBoth(float scale)
{
    this.scale = scale;
    this.invalidate();  // If you want to see the scale every time you set
                        // scale you need to have this line here, 
                        // invalidate() function will call onDraw(Canvas)
                        // to redraw the view for you
}

@Override
protected void onDraw(Canvas canvas) {
    // The main mechanism to display scale animation, you can customize it
    // as your needs
    int w = this.getWidth();
    int h = this.getHeight();
    canvas.scale(scale, scale, w/2, h/2);

    super.onDraw(canvas);
}
}

这是logcat输出

 05-25 10:15:20.765  32481-32481/com.greycodes.orissatourism     E/AndroidRuntime﹕ FATAL EXCEPTION: main
  Process: com.greycodes.orissatourism, PID: 32481
  java.lang.IllegalStateException: The specified child already has a  parent. You must call removeView() on the child's parent first.
        at android.view.ViewGroup.addViewInner(ViewGroup.java:3937)
        at android.view.ViewGroup.addView(ViewGroup.java:3787)
        at android.support.v4.view.ViewPager.addView(ViewPager.java:1308)
        at android.view.ViewGroup.addView(ViewGroup.java:3728)
        at android.view.ViewGroup.addView(ViewGroup.java:3701)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:970)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1138)
        at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:740)
        at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1501)
        at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:490)
        at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
        at android.support.v4.view.ViewPager.populate(ViewPager.java:1072)
        at android.support.v4.view.ViewPager.populate(ViewPager.java:918)
        at android.support.v4.view.ViewPager$3.run(ViewPager.java:248)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
        at android.view.Choreographer.doCallbacks(Choreographer.java:580)
        at android.view.Choreographer.doFrame(Choreographer.java:549)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5289)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)

我对此感到非常沮丧。我用另一个代码做得很好。但是当我增加尺寸而不是缩放时,那个有一个滞后。

1 个答案:

答案 0 :(得分:0)

我自己解决了。但我不确定问题是什么。如果有人发现原因,对某人会有所帮助。