使用FragmentStatePagerAdapter出现“指定的子项已经有父项”错误。

3
我尝试了一些与类似问题的解决方案,但它们似乎都不能在我的情况下工作。我的情况略有不同,因为我不是从xml中获取surfaceview,而是通过一个SurfaceView类创建它,并将其添加到FrameLayout中。我这样做是因为我希望在创建surface时使用mediaplayer。
日志记录
    07-12 11:02:28.221: E/AndroidRuntime(7055): FATAL EXCEPTION: main
07-12 11:02:28.221: E/AndroidRuntime(7055): java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.view.ViewGroup.addViewInner(ViewGroup.java:3337)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.view.ViewGroup.addView(ViewGroup.java:3208)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.view.ViewGroup.addView(ViewGroup.java:3165)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.view.ViewGroup.addView(ViewGroup.java:3145)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.support.v4.app.NoSaveStateFrameLayout.wrap(NoSaveStateFrameLayout.java:40)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:915)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1444)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:461)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:163)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.support.v4.view.ViewPager.populate(ViewPager.java:1064)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.support.v4.view.ViewPager.populate(ViewPager.java:911)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1432)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.view.View.measure(View.java:12892)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:594)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:376)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.view.View.measure(View.java:12892)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4698)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.view.View.measure(View.java:12892)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.widget.LinearLayout.measureVertical(LinearLayout.java:812)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.widget.LinearLayout.onMeasure(LinearLayout.java:553)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.view.View.measure(View.java:12892)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4698)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2268)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.view.View.measure(View.java:12892)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1159)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2545)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.os.Handler.dispatchMessage(Handler.java:99)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.os.Looper.loop(Looper.java:137)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at android.app.ActivityThread.main(ActivityThread.java:4507)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at java.lang.reflect.Method.invokeNative(Native Method)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at java.lang.reflect.Method.invoke(Method.java:511)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
07-12 11:02:28.221: E/AndroidRuntime(7055):     at dalvik.system.NativeStart.main(Native Method)

我的代码如下:

VideoFragment.java

public class VideoFragment extends Fragment{
private static final String TAG = "Fuck this";
static String vpath;
static Context cxt;
static int pos;
static VideoFragment newInstance(int position, Cursor cursor, Context context) {
    pos = position;

    cursor.moveToPosition(position);
    vpath = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.DATA));
    cxt = context;
    VideoFragment f = new VideoFragment();

    Bundle args = new Bundle();
    args.putInt("position", position);
    f.setArguments(args);

    return f;
}


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //mNum = getArguments() != null ? getArguments().getInt("num") : 1;

}

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

    View v = inflater.inflate(R.layout.full_image, container, false);

    FrameLayout preview = (FrameLayout) v.findViewById(R.id.framelayout);

    VidView vidview = new VidView(cxt);
    preview.addView(vidview, pos);
    return preview;


}

public class VidView extends SurfaceView implements SurfaceHolder.Callback {
    MediaPlayer player;
    public VidView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        player = new MediaPlayer();

        player.setDisplay(holder);

    try {
        player.setDataSource(vpath);
        player.prepare();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    }
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {  
        if (player != null){
            if ( player.isPlaying() )
                player.stop();
        player.reset();
        player.release();
        player = null;
        }

    }
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)   { 

    }

}

活动和FragmentStatePagerAdapater

public class FullImageActivity extends FragmentActivity  {


private static final String TAG = "MediaPlayer shit";
//MediaPlayer player;
//SurfaceView surfaceview;
SurfaceHolder surfaceHolder;
Gridview gridview = new Gridview();
int width;
int height;
Cursor cursor;
ViewPager viewpager;
PagerAdapter pageradapter;
String path;
int position;
String[] projection = { GridviewData.ROWID, GridviewData.BITMAPPATH, GridviewData.VIDEOFILEPATH};
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.image_pager);

    Intent i = getIntent();

    position = i.getExtras().getInt("position");
    path = i.getExtras().getString("videopath");


    cursor = getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, 
                                gridview.mediaColumns, 
                                MediaStore.Video.Media.DATA + " like ?", 
                                new String[] {Environment.getExternalStorageDirectory().getPath() + "/Reelcam/TheReelcams/%"}, 
                                null); 

    pageradapter = new PagerAdapter(getSupportFragmentManager());
    viewpager = (ViewPager) findViewById(R.id.pager);
    //viewpager.setOffscreenPageLimit(1);
    viewpager.setAdapter(pageradapter);

}


@Override
protected void onPause() {

    super.onPause();
}
@Override
protected void onResume() {
    //surfaceview.setVisibility(View.VISIBLE);
    super.onResume();
}


@Override
protected void onDestroy() {
    cursor.close();
    super.onDestroy();
}

public class PagerAdapter extends FragmentStatePagerAdapter{
    public PagerAdapter(FragmentManager fm) {
        super(fm);
        // TODO Auto-generated constructor stub
    }

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

    @Override
    public Fragment getItem(int position) {
        Log.i(TAG, "in getitem");
        return VideoFragment.newInstance(position, cursor, getApplicationContext());
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return cursor.getCount();
    }

}

1
在询问错误时,请发布logcat输出。 - S.D.
3个回答

12

这里:

View v = inflater.inflate(R.layout.full_image, container, false);

FrameLayout preview = (FrameLayout) v.findViewById(R.id.framelayout);

. . . . . . 

return preview;

你正在将full_image布局充满到v中。但是,你返回了另一个id为frameLayout的视图,这个视图可能已经在布局中有父视图(可能是v)。改为返回v

确保返回的视图没有父视图。查看R.layout.full_image,看看R.id.framelayout是否已经包含在一个ViewGroup中。


是的,问题已经解决了。谢谢。现在它返回一个黑屏,你有什么想法吗? - Papajohn000
1
@Papajohn000 首先,使用SDK中的HierarchyViewer工具确认所有UI是否正常显示。现在,将注意力集中在如何使东西出现在那个SurfaceView上。 - S.D.

0
这是解决方案:
public class FragmentItem extends Android.Support.V4.App.Fragment
{
    View rootView;
    TextView textView;

    public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        if (rootView != null) 
        {
            ViewGroup parent = (ViewGroup)rootView.Parent;
            parent.RemoveView(rootView);
        } else {
            rootView = inflater.Inflate(Resource.Layout.FragmentItem, container, false);
            textView = rootView.FindViewById<TextView>(Resource.Id.textViewDisplay);            
        }
        return rootView;
    }
}

-1
你的具体错误在哪一行?这通常是由于多次将子项添加到父项引起的。例如,当您不断将您的SurfaceView添加到片段中,并将SurfaceView的内容设置为新内容时,片段仍然看到相同的元素。为避免此问题,请只设置一次即可。
surfaceview = new SurfaceView()

将SurfaceView设置为新内容并将其添加回片段中。

希望这可以帮助到您。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接