2012-11-26 26 views
24

Vào dự án của tôi Tôi đang sử dụng trình xem với ba tab có tên History, Main, Map. Main hoạt động chứa Timer, đồng hồ bấm giờ, v.v. Bản đồ hiển thị bản đồ google. và vào Lịch sử ngay bây giờ tôi chỉ đang sử dụng Textview đơn giản.Cách giải quyết cho người xem: Trẻ được chỉ định đã có cha/mẹ. Bạn phải gọi removeView() trên phụ huynh của trẻ trước tiên

ViewPager hướng dòng chảy: Lịch sử - chính - Bản đồ

tôi đặt chính như mục hiện tại (Bydefault hiển thị thẻ chính) Now khi tôi swipe từ chính>Bản đồBản đồ>Main hoạt động hoàn hảo của nó. nhưng khi swipe từ chính>Lịch sử không có lỗi nhưng trở lại từ Lịch sử để chính (Lịch sử>chính) eclipse cho tôi lỗi như:

E/AndroidRuntime( 533): java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. 

Và FYI Tôi đang sử dụng intent into Map Activity. Vui lòng kiểm tra mã bên dưới.Xin vui lòng cho tôi biết cách khắc phục sự cố của tôi.

lớp ViewPager:

@Override 
    public Fragment getItem(int position) { 
     // return SwipeyTabFragment.newInstance(TITLES[position]); 

     Fragment f = new Fragment(); 

     switch (position) { 
     case 0: 
      f = History.newInstance(position); 
      break; 
     case 1: 
      f = Main.newInstance(position); 
      break; 
     case 2: 
      f = Map.newInstance(position); 
      break; 

     } 

     return f; 

    } 

History.class:

public class History extends Fragment { 

public static Fragment newInstance(int position) { 
    History f = new History(); 
    Bundle args = new Bundle(); 

    args.putInt("title", position); 
    f.setArguments(args); 
    return f; 

} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
    ViewGroup root = (ViewGroup) inflater.inflate(R.layout.history, null); 


    ((TextView) root.findViewById(R.id.text)).setText("Hello"); 
    return root; 
} 

} 

Main.class:

public class Main extends Fragment implements GPSCallback { 

...... 

public static Fragment newInstance(int position) { 
    Main f = new Main(); 
    Bundle args = new Bundle(); 

    args.putInt("title", position); 
    f.setArguments(args); 
    return f; 

} 

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

    final ViewGroup root = (ViewGroup) inflater 
      .inflate(R.layout.main, null); 

    ....... 

    return root; 
} 

    ........ 
} 

Map.class:

public class Map extends Fragment { 

private static final String KEY_STATE_BUNDLE = "localActivityManagerState"; 

private LocalActivityManager mLocalActivityManager; 

protected LocalActivityManager getLocalActivityManager() { 
    return mLocalActivityManager; 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    Bundle state = null; 
    if (savedInstanceState != null) { 
     state = savedInstanceState.getBundle(KEY_STATE_BUNDLE); 
    } 

    mLocalActivityManager = new LocalActivityManager(getActivity(), true); 
    mLocalActivityManager.dispatchCreate(state); 
} 



public static Fragment newInstance(int position) { 
    Map f = new Map(); 
    Bundle args = new Bundle(); 

    args.putInt("title", position); 
    f.setArguments(args); 
    return f; 

} 


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

     Intent i = new Intent(getActivity(), MapViewActivity.class); 
     // Intent i = new Intent(getActivity(), hellogooglemap.class); 
     Window w = mLocalActivityManager.startActivity("tag", i); 

     View currentView=w.getDecorView(); 
     currentView.setVisibility(View.VISIBLE); 
     currentView.setFocusableInTouchMode(true); 
     ((ViewGroup) currentView).setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); 
     return currentView; 


     /*ViewGroup root = (ViewGroup) inflater.inflate(R.layout.history, null); 


     ((TextView) root.findViewById(R.id.text)).setText("Hello"); 
     return root;*/ 

} 


@Override 
    public void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
     outState.putBundle(KEY_STATE_BUNDLE, 
       mLocalActivityManager.saveInstanceState()); 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     mLocalActivityManager.dispatchResume(); 
    } 

    @Override 
    public void onPause() { 
     super.onPause(); 
     mLocalActivityManager.dispatchPause(getActivity().isFinishing()); 
    } 

    @Override 
    public void onStop() { 
     super.onStop(); 
     mLocalActivityManager.dispatchStop(); 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     mLocalActivityManager.dispatchDestroy(getActivity().isFinishing()); 
    } 

} 

Logcat:

E/AndroidRuntime( 533): java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first. 
E/AndroidRuntime( 533): at android.view.ViewGroup.addViewInner(ViewGroup.java:1976) 
E/AndroidRuntime( 533): at android.view.ViewGroup.addView(ViewGroup.java:1871) 
E/AndroidRuntime( 533): at android.view.ViewGroup.addView(ViewGroup.java:1828) 
E/AndroidRuntime( 533): at android.view.ViewGroup.addView(ViewGroup.java:1808) 
E/AndroidRuntime( 533): at android.support.v4.app.NoSaveStateFrameLayout.wrap(NoSaveStateFrameLayout.java:40) 
E/AndroidRuntime( 533): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:874) 
E/AndroidRuntime( 533): at android.support.v4.app.FragmentManagerImpl.attachFragment(FragmentManager.java:1240) 
E/AndroidRuntime( 533): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:612) 
E/AndroidRuntime( 533): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1416) 
E/AndroidRuntime( 533): at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:431) 
E/AndroidRuntime( 533): at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:139) 
E/AndroidRuntime( 533): at android.support.v4.view.ViewPager.populate(ViewPager.java:804) 
E/AndroidRuntime( 533): at android.support.v4.view.ViewPager.completeScroll(ViewPager.java:1280) 
E/AndroidRuntime( 533): at android.support.v4.view.ViewPager.computeScroll(ViewPager.java:1176) 
E/AndroidRuntime( 533): at android.view.ViewGroup.drawChild(ViewGroup.java:1562) 
E/AndroidRuntime( 533): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
E/AndroidRuntime( 533): at android.view.ViewGroup.drawChild(ViewGroup.java:1644) 
E/AndroidRuntime( 533): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
E/AndroidRuntime( 533): at android.view.View.draw(View.java:6883) 
E/AndroidRuntime( 533): at android.widget.FrameLayout.draw(FrameLayout.java:357) 
E/AndroidRuntime( 533): at android.view.ViewGroup.drawChild(ViewGroup.java:1646) 
E/AndroidRuntime( 533): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
E/AndroidRuntime( 533): at android.view.ViewGroup.drawChild(ViewGroup.java:1644) 
E/AndroidRuntime( 533): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373) 
E/AndroidRuntime( 533): at android.view.View.draw(View.java:6883) 
E/AndroidRuntime( 533): at android.widget.FrameLayout.draw(FrameLayout.java:357) 
E/AndroidRuntime( 533): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1862) 
E/AndroidRuntime( 533): at android.view.ViewRoot.draw(ViewRoot.java:1522) 
E/AndroidRuntime( 533): at android.view.ViewRoot.performTraversals(ViewRoot.java:1258) 
E/AndroidRuntime( 533): at android.view.ViewRoot.handleMessage(ViewRoot.java:1859) 
E/AndroidRuntime( 533): at android.os.Handler.dispatchMessage(Handler.java:99) 
E/AndroidRuntime( 533): at android.os.Looper.loop(Looper.java:130) 
E/AndroidRuntime( 533): at android.app.ActivityThread.main(ActivityThread.java:3683) 
E/AndroidRuntime( 533): at java.lang.reflect.Method.invokeNative(Native Method) 
E/AndroidRuntime( 533): at java.lang.reflect.Method.invoke(Method.java:507) 
E/AndroidRuntime( 533): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 
E/AndroidRuntime( 533): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 
E/AndroidRuntime( 533): at dalvik.system.NativeStart.main(Native Method) 
W/ActivityManager( 68): Force finishing activity  com.android.gps/.viewpager.SwipeyTabsSampleActivity 
W/ActivityManager( 68): Activity pause timeout for HistoryRecord{40716740 com.android.gps/.viewpager.SwipeyTabsSampleActivity} 

Cảm ơn.

EDIT:

Nếu không có ý định vào hoạt động Bản đồ nó hoạt động pwrfect.I có nghĩa là khi tôi đang sử dụng tương tự như lịch sử vào bản đồ không có bất kỳ lỗi.

Trả lời

27

Tôi cũng phải đối mặt với vấn đề này.

Bạn có thể giải quyết nó bằng cách chỉ cần thêm dòng mViewPager.setOffscreenPageLimit(3);

public class SwipeyTabsSampleActivity extends FragmentActivity { 

... 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    setContentView(R.layout.main); 

    mViewPager = (ViewPager) findViewById(R.id.viewpager); 
    mTabs = (SwipeyTabs) findViewById(R.id.swipeytabs); 

    SwipeyTabsPagerAdapter adapter = new SwipeyTabsPagerAdapter(this, 
      getSupportFragmentManager()); 
    mViewPager.setAdapter(adapter); 

    mViewPager.setOffscreenPageLimit(3); <------ Add this one 
} 

} 

Good Luck.

35

tôi đã cùng một vấn đề khi tôi sử dụng

View res = inflater.inflate(R.layout.fragment_guide_search, container); 

bên Fragment.onCreateView (...

Bạn phải gọi

View res = inflater.inflate(R.layout.fragment_guide_search, container, false); 

hoặc

View res = inflater.inflate(R.layout.fragment_guide_search, null); 
+0

Với mô tả từ tài liệu, điều này có ý nghĩa hoàn hảo và đã khắc phục được sự cố của tôi. – CoatedMoose

+1

cho tôi :) Xem res = inflater.inflate (R.layout.fragment_guide_search, null); – cV2

+0

đối với tôi, tùy chọn thứ hai quá – androidevil

4

Đầu tiên , câu trả lời của RB Patel để chèn đồng de (hiển thị bên dưới), làm việc như một sự quyến rũ, nhưng khi tôi đọc về tính năng này, tôi nhận ra nó được dự định là một tối ưu tiềm năng và thực sự không phải là giải pháp cho lỗi này.

mViewPager.setOffscreenPageLimit(3); 

Các trang web cho nhà phát triển Android nói như sau về phương pháp này:

setOffscreenPageLimit (int giới hạn) - Đặt số trang sẽ được giữ lại để hai bên của trang hiện trong giao diện hệ thống phân cấp ở trạng thái không hoạt động.

Dường như điều này chỉ đặt giới hạn số trang được lưu vào bộ nhớ cache sang phải hoặc trái của trang hiện tại. Trong trường hợp của tôi, đây chỉ là sự trợ giúp của ban nhạc cho vấn đề, có lỗi dừng lại và mọi thứ hoạt động suôn sẻ, nhưng tôi vẫn có mã xấu ẩn trong chương trình của tôi mà chỉ đơn giản là không được thực hiện. Tôi tin rằng phương pháp này được dự định sẽ được sử dụng như một tối ưu hóa và không phải là một sửa chữa thực tế cho lỗi này.

Tôi đã gặp sự cố này khi cố gắng quá tải phương thức instantiateItem() trong lớp tùy chỉnh mở rộng PagerAdapter. Lỗi của tôi đã được ném sau khi tôi sẽ điều hướng trở lại tab/trang mà trước đó tôi đã truy cập/khởi tạo.

Tôi mới sử dụng Android nhưng tôi sẽ cố hết sức để giải thích giải pháp của mình. Dòng mà ném lỗi này là như sau:

v.addView(child); 

Nếu tôi hiểu điều này một cách chính xác, nó đã bị nghẹt thở vì đứa trẻ đã được khởi tạo trước đó và được chỉ định một phụ huynh.

Khi tôi điều hướng trở lại trang xem/trang đã truy cập trước đây, tôi đã cố gắng thêm chế độ xem đã có bố cục bố cục gốc vào Bố cục mới, do đó sẽ xảy ra lỗi.

Giải pháp: Tôi vừa kiểm tra xem liệu chế độ xem con tôi đã cố gắng hiển thị (khởi tạo) đã được khởi tạo ở nơi khác bằng cách xem liệu nó có đặt chế độ xem gốc hay không. Nếu chế độ xem con đã được tạo, thì tôi chỉ sử dụng bố cục của chế độ xem con thay vì tạo Bố cục mới.

Đây là mã của tôi (Tôi xin lỗi nếu nó xúc phạm bất kỳ chuyên gia):

@Override 
public Object instantiateItem(View container, int position) { 
    LinearLayout v = new LinearLayout(mContext); 

    //the view being loaded (unless it already was then we have to handle it) 
    View child = mViews.get(position); 

    //If the child view was loaded already then it will have a parent view it belongs to 
    //We return the parent view instead of adding the child to the LinearLayout we just created and returning that new layout. 
    if(child.getParent() != null) { 
     View parent = (View) child.getParent(); 
     ((ViewPager) container).addView(parent); 
     return parent; 
    } 

    //first time instantiating a child view/page 
    v.addView(child);    

    // These lines execute the first time a given page is instantiated 
    ((ViewPager) container).addView(v); 

    return v; 
} 
+0

mViewPager.setOffscreenPageLimit (3); cứu cuộc đời tôi! Cảm ơn rất nhiều! – L93

+0

trả về cha mẹ vẫn có ngoại lệ –

1

Đây là giải pháp của tôi (được sử dụng trong mỗi đoạn san hô), cho phép cả hai êm ái và tránh các vấn đề bộ nhớ:

... 
private LayoutInflater mInflater; 
private WeakReference<View> mRootView = null; 
... 

@Override 
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) 
    { 
    if (inflater != null) 
    mInflater = inflater; 
    else 
    mInflater = LayoutInflater.from(getActivity()); 
    View rootView = mRootView == null ? null : mRootView.get(); 
    if (rootView != null) 
     { 
     final ViewParent parent = rootView.getParent(); 
     if (parent != null && parent instanceof ViewGroup) 
     ((ViewGroup) parent).removeView(rootView); 
     } 
    else 
     { 
     rootView = mInflater.inflate(R.layout.fragment_test, null, false); 
     mRootView = new WeakReference<View>(rootView); 
     } 
    return rootView; 
    } 
1
@Override 
public Object instantiateItem(View arg0, int arg1) { 
    Log.d("instantiateItem", ""+arg0+" "+arg1); 
    try { 
     if(mListViews.get(arg1).getParent()==null) 
      ((ViewPager) arg0).addView(mListViews.get(arg1), 0); 
     else{ 
      // I am new to android, it is strange that the view to be added is already bound to a parent 
      // Through trials and error I solve this problem with the following codes 
      // Add that the element of mlistviews is listview in pagerview; 
      ((ViewGroup)mListViews.get(arg1).getParent()).removeView(mListViews.get(arg1)); 

      ((ViewPager) arg0).addView(mListViews.get(arg1), 0); 
     } 
    } catch (Exception e) { 
     Log.d("parent=", ""+mListViews.get(arg1).getParent()); 
     e.printStackTrace(); 
    } 
    return mListViews.get(arg1); 
} 
0

nếu bạn đang làm việc với FragmentPagerAdapter thì chỉ cần sử dụng phương thức destroyItem bên trong FragmentPagerAdapter.

@Override 
public void destroyItem(ViewGroup container, int position, Object object) 
{ 
     FragmentTransaction ft=fm.beginTransaction(); 
     ft.remove((Fragment) object); 
     ft.commit(); 
} 

setOffscreenPageLimit (int limit) tiêu thụ nhiều bộ nhớ hơn và trong một số trường hợp không hoạt động hoàn hảo. trạng thái giữ lại của nó ở hai bên xem mô tả. setOffscreenPageLimit (int limit) - Đặt số trang cần được giữ lại ở hai bên của trang hiện tại trong hệ thống phân cấp khung nhìn ở trạng thái không hoạt động.

0

// nếu chế độ xem con được thêm đã được ràng buộc với cha mẹ, sau đó xóa con khỏi cha mẹ và sau đó thêm lại vào vùng chứa.

if (v.getParent() != null) { 
    ((ViewGroup) v.getParent()).removeView(v); 
} 
container.addView(v); 
Các vấn đề liên quan