2016-11-07 1 views
0

중첩 된 조각이있는 프로젝트 (https://github.com/checklist/NestedFragmentsRecycler)가 있습니다. FragmentA는 MainActivity에 있으며 어댑터가있는 RecyclerView를 포함합니다. 어댑터의 각 항목은 FragmentB를 반환합니다. FragmentB를 위치에로드하는 데 ID를 부여해야하며 고유해야하므로 고유 한 ID를 생성합니다. 첫 번째 조각이 잘 표시되어 있지만, 불행하게도, 내가 스크롤을 시작하는 순간, 내 고유 ID를 찾을 수 없다는 예외가 얻을 :RecyclerView가있는 Android 중첩 조각

W/ResourceType에 : 자원 이름을 가져올 때 없음 패키지 식별자를 수 0x00000004 E/FragmentManager : ID 0x4에 대한보기가 없습니다. FragmentB : {30cad9b # 3 id = 0x4} mStopped = false mReallyStopped = false D/FragmentManager :
mLoadersStarted = true D/FragmentManager : a2d5538의 활성 조각 :,D/FragmentManager # 0 : FragmentA {6,948,911 # 0 식 0x7f0b0056} D/FragmentManager : mFragmentId = # 7f0b0056 mContainerId = # 7f0b0056 MTAG NULL = D/FragmentManager : mState = 5 mIndex = 0 mWho = 로이드 : 절편 0 mBackStackNesting = 0 D/FragmentManager :
가 mAdded = TRUE mRemoving = 거짓 mFromLayout = 거짓 mInLayout = 거짓 D/FragmentManager : mHidden = 거짓 mDetached = 거짓 mMenuVisible = TRUE mHasMenu FALSE = D/FragmentManager :
mRetainInstance = 거짓 mRetaining = false mUserVisibleHint = true D/FragmentManager : mFragmentManager = FragmentManager {a2d5538 in HostCallbacks {327ba76}} D/FragmentManager :
mHost = 및 [email protected] D/FragmentManager : mArguments = 번들 [{}] D/조각 관리자 :
mContainer = android.widget.FrameLayout {ffe8877 VE ..... .... .... 128,32-2432,1496 # 7f0b0056 app : id/fragmentA D/FragmentManager :
mView = android.widget.LinearLayout {ffe8ce4 VE ..... ........ 0,0-2304,1464} D/FragmentManager :
mInnerView = android.widget.LinearLayout {ffe8ce4 VE ..... ... 0,0-2304,1464} D/FragmentManager : 하위 조각 관리자 {aa7a54d FragmentA {6948911}의 : D/FragmentManager : 활성 조각 있음 aa7a54d : D/FragmentManager : # 0 : 조각 B {44d0802 # 0 id = 0x1},363,210 D/FragmentManager : mFragmentId = 1 mContainerId = 1 MTAG NULL = D/FragmentManager : mState = 5 mIndex = 0 mWho = 로이드 : 단편 : 0 : 0 mBackStackNesting = 0 D/FragmentManager :
mAdded = TRUE mRemoving = 거짓 mFromLayout = 거짓 mInLayout = 거짓 D/FragmentManager : mHidden = 거짓 mDetached = 거짓 mMenuVisible = TRUE mHasMenu FALSE = D/FragmentManager :
mRetainInstance = 거짓 mRetaining = 거짓 mUserVisibleHint = TRUE D/FragmentManager :
mFragmentManager = FragmentManager {6948911} 조각에 D/조각 관리자 :
mHost = android.support.v4.app.FragmentActivity $ HostCallbac 327ba76 D/FragmentManager @ KS : mParentFragment = FragmentA {6,948,911 # 0 식 0x7f0b0056} D/FragmentManager :
mArguments = 번들 [{TEXT =이 조각 B이다 : 0}] D/FragmentManager :
mContainer = 로이드 .widget.FrameLayout {c93513 VE ..... ........ 0,0-800,1464 # 1} D/조각 관리자 :
mView = android.widget.LinearLayout {3899350 VE ..... ........ 0,0-800,1464} D/FragmentManager :
mInnerView = android.widget.LinearLayout {3899350 VE ..... ........ 0,0-800,1464} D/FragmentManager : 자식 프래그먼트 관리자 {c564949 in FragmentB {44d0802 }} D/FragmentManager :
FragmentManager의 기타 상태 : D/FragmentManager :
[email protected]a76 D/FragmentManager :
mContainer = android.support.v4.app . 조각 $ 1 @ 287a24e D/FragmentM anager : mParent = FragmentB {44d0802 # 0 ID = 0x1을} D/FragmentManager : mCurState = 5 mStateSaved = 거짓 mDestroyed FALSE = D/FragmentManager : 1 : FragmentB {d880f6f # 1 식을 0x2} D/FragmentManager :
mFragmentId = 2 mContainerId = 2 MTAG NULL = D/FragmentManager :
mState = 5 mIndex = 1 mWho = 로이드 : 단편 : 0 : 1 mBackStackNesting = 0 D/FragmentManager : mAdded = TRUE mRemoving = 거짓 mFromLayout = 거짓 mInLayout FALSE = D/FragmentManager :
mHidden = 거짓 mDetached = 거짓 mMenuVisible = TRUE mHasMenu = 거짓 D/FragmentManager : mRetainInstance = 거짓 mRetaining = 거짓 mUserVisibleHint = TRUE D/FragmentManager : 012,380,073 1백62경7천5백52조3천1백49억6천45만3천2백10 mFragmentManager = {FragmentManager aa7a54d에 FragmentA {6948911}} D/FragmentManager :
[email protected]a76 D/FragmentManager : mParentFragment FragmentA = {# 0 6,948,911 식 0x37f0b0056} D/FragmentManager :
mArguments = 번들 [{TEXT = 조각 B : 1}] D/조각 관리자 :
mContainer = android.widget.FrameLayout {67c947c VE ..... ...... .. 0,0-800,1464 # 2} D/조각 관리자 :
mView = android.widget.LinearLayout {c313105 VE ..... ........ 0,0-800,1464 } D/조각 관리자 :
mInnerView = android.widget.LinearLayout {c313105 VE ..... ..... 0,0-800,1464} D/FragmentManager : 자식 조각 관리자 {d880f6f}의 조각 모음 {cbf955a} : D/FragmentManager :
FragmentManager의 기타 상태 : D/FragmentManager :
[email protected]a76 D/FragmentManager :
mContainer android.support.v4.app.Fragment = $ @ 1 ab0338b D/FragmentManager : mParent = FragmentB {d880f6f # 1 식을 0x2} D/FragmentManager : mCurState = 5 mStateSaved = 거짓 mDestroyed FALSE = D/FragmentManager : 2 : FragmentB {53c7c68 # 2의 ID = 0x3으로} D/FragmentManager :
mFragmentId = # 3 mContainerId = # 3 MTAG NULL = D/FragmentManager :
mState = 5 mIndex = 2 mWho = 로이드 : 단편 : 0 : 2 mBackStackNesting = 0 D/FragmentManager : mAdded = TRUE mRemoving = 거짓 mFromLayout = 거짓 mInLayout FALSE = D/FragmentManager :
mHidden = 거짓 mDetached = 거짓 mMenuVisible = TRUE mHasMenu = 거짓 D/FragmentManager : mRetainInstance = 거짓 mRetaining = 거짓 mUserVisibleHint = TRUE D/FragmentManager :에
mFragmentManager = FragmentManager {aa7a54d 조각 {6948911}} D/조각 관리자 :
mHost = android.support.v4.app.FragmentActivity $ HostCallbacks 327ba76 D/FragmentManager @ mParentFragment = FragmentA {6,948,911 # 0 식 0x7f0b0056} D/FragmentManager :
mArguments = 번들 [{TEXT =이 조각 B 인 2}] D/FragmentManager :
mContainer = android.widget.FrameLayout {918d881 VE ..... ..... 0,0-800,1464 # 3} D/조각 관리자 :
mView = android.widget.LinearLayout {651ad26 VE. ........ 0,0-800,1464} D/조각 관리자 :
mInnerView = android.widget.LinearLayout {651ad26 VE ..... ........ 0,0-800,1464} D/FragmentManager : 자식 FragmentManager {4c7d67 in FragmentB {53c7c68}} : D/FragmentManag ER :
FragmentManager의 기타 상태 : D/FragmentManager :
[email protected]a76 D/FragmentManager :
[email protected] D/FragmentManager : mParent = FragmentB {53c7c68 2 ID = 0x3으로} D/FragmentManager : mCurState = 5 mStateSaved = 거짓 mDestroyed FALSE = D/FragmentManager : 3 : FragmentB {30cad9b # 3 식을 0x4} D/FragmentManager :
mFragmentId = 4 mContainerId = 4 mTag = null D/FragmentManager :
mState = 1 mIndex = 3 mWho = android : fragment : 0 : 3 mBackStackNesting = 0,D/FragmentManager : mAdded = TRUE mRemoving = 거짓 mFromLayout = 거짓 mInLayout FALSE = D/FragmentManager :
mHidden = 거짓 mDetached = 거짓 mMenuVisible = TRUE mHasMenu = 거짓 D/FragmentManager : mRetainInstance = 거짓 mRetaining = 거짓 mUserVisibleHint = 참 D/FragmentManager :
mFragmentManager FragmentManager = {aa7a54d에 FragmentA {6948911}} D/FragmentManager :
[email protected]a76 D/FragmentManager : mParentFragment = {6,948,911 FragmentA # 0 id = 0x7f0b0056} D/조각 관리자 :
mArguments = 번들 [{TEXT = 이것은 Fragm입니다. 엔트 B : 3}] D/FragmentManager :
라이트 파편 : D/FragmentManager # 0 : FragmentB {44d0802 # 0 ID = 0x1을} D/FragmentManager : 1 : FragmentB {d880f6f 1 식을 0x2} D/FragmentManager : 2 : FragmentB {53c7c68 # 2의 ID = 0x3으로} D/FragmentManager : 3 : FragmentB {30cad9b # 3 식을 0x4} D/FragmentManager : FragmentManager의 기타 상태 : D/FragmentManager :
mHost = [email protected] D/FragmentManager :
[email protected] D/FragmentManager : mParent FragmentA = {# 0 6,948,911 식 0x7f0b0056 } D/FragmentManager : mCurS 테이트 = 5 mStateSaved = 거짓 mDestroyed FALSE = D/FragmentManager : 추가 파편 : D/FragmentManager # 0 : FragmentA {6,948,911 # 0 식 0x7f0b0056} D/FragmentManager : FragmentManager의 기타 상태 : D/FragmentManager :
[email protected]a76 D/FragmentManager :
mContainer = android.support.v4.app.FragmentActivity $ HostCallbacks @ 327ba76 D/FragmentManager : mCurState = 5 mStateSaved = false mDestroyed = false부분 코드 캐시 수집, 코드 = 30KB, 데이터 = 27KB I/art : 코드 캐시 수집 후 코드 = 29KB , 데이터 = 27KB I/art : 128KB D/FragmentManager에 대한 코드 캐쉬 용량이 증가 : 계층 구조보기 : D/FragmentManager : com.android.internal.policy.DecorView {99b75b2 VE .... ... 0,0 -2560,1800} D/FragmentManager :
android.widget.LinearLayout {eb98903 VE .... ... 0,0-2560,1704} D/FragmentManager : android.view.ViewStub {8107080 GE ... ... 0,0-0,0 # 10203ef android : id/action_mode_bar_stub} D/조각 관리자 :
andro id.widget.FrameLayout {44716b9 VE .... ... 0,48-2560,1704} D/조각 관리자 :
android.support.v7.widget.ActionBarOverlayLayout {7473afe VE .... ... 0,0-2560,1656 # 7f0b0044 응용 프로그램 : ID/decor_content_parent} D/FragmentManager :
이 android.support.v7.widget.ContentFrameLayout {bc1b25f는 VE ... ... 0,128-2560,1656 # 1020002 안드로이드 : ID/컨텐츠} D/FragmentManager :
android.widget.RelativeLayout {a4c14ac이 .... VE ... 0,0-2560,1528

7f0b0055 응용 프로그램 : ID/activity_main} D/FragmentManager : 안드로이드. 위젯 .FrameLayout {ffe8877 VE .... ... 128,32-2432,1496

012 3,516,

7f0b0056 응용 프로그램 : ID/fragmentA} D/FragmentManager : android.widget.LinearLayout {ffe8ce4는 VE ... ... 0,0-2304,1464}

D/FragmentManager :
android.support .v7.widget.RecyclerView {9b96575 VFEDH ... F .. 0,0-2304,1464 # 7f0b0057 app : id/listView} D/조각 관리자 :
android.widget.LinearLayout {e58090a VE .... .. -19,0-781,1464} W/ResourceType : 리소스 이름을 가져올 때 패키지 식별자가 없습니다. 숫자 0x00000001 D/FragmentManager :
android.widget.FrameLayout {c93513 VE .... ... 0, 0-800,1464 # 1},210 D/FragmentManager :
android.widget.LinearLayout {3,899,350은 VE ... ...} 0,0-800,1464 D/FragmentManager :
android.support.v7.widget.AppCompatTextView {5f9157b의 V. ED .... ... 0,0-254,38 # 7f0b0070 app : id/textView} D/조각 관리자 :
android.widget.LinearLayout {7bbcf98 VE .... ... 781,0-1581 , 1464} W/ResourceType : 리소스 이름을 가져올 때 패키지 식별자가 없습니다. 숫자 0x00000002 D/FragmentManager :
android.widget.FrameLayout {67c947c VE .... ... 0,0-800,1464 # 2} D/조각 관리자 :
android.widget.LinearLayout {c313105 VE .... ... 0 , 0-800,1464} D/FragmentManager :
android.support.v7.widget.AppCompatTextView {bc7e3f1 V.ED .... ... 0,0-254,38 # 7f0b0070 app : id/textView } D/FragmentManager :
android.widget.LinearLayout {8f5abd6 VE .... 1535,0-2381,1464} W/ResourceType : 리소스 이름을 가져올 때 패키지 식별자가 없습니다. 숫자 0x00000003 D/FragmentManager :
android.widget.FrameLayout {918d881 VE .... ... 0,0-800,1464 # 3 D/FragmentManager :
android.widget.LinearLayout {651ad26 VE .... ... 0 , 0-800,1464} D/FragmentManager :
android.support.v7.widget.AppCompatTextView {8798e57 V.ED .... ... 0,0-254,38 # 7f0b0070 app : id/textView} D/FragmentManager :
android.support.v7.widget.ActionBarContainer {36a4d44 V.ED .... ... 0,0-2560,128 # 7f0b0045 app : id/action_bar_container} D/조각 관리자 : android.support.v7.widget.Toolbar {e65ce2d VE .... .. 0,0-2560,128

7f0b0046 앱 : ID/action_bar} D/FragmentManager : android.support.v7.widget.AppCompatTextView {9f8af62 V.ED .... ...

48 , 37-153,91} D/FragmentManager :
android.support.v7.widget.ActionMenuView {c1eb8f3 VE .... ... 2544,0-2544,128} D/FragmentManager :
android.support.v7.widget.ActionBarContextView {460f9b0 GE .... ... 0,0-0,0 # 7f0b0047 app : id/action_context_bar} D/FragmentManager :
android.view.View {77e2029 V.ED .... ... 0,1704-2560,1800 # 1020030 android : id/navigationBarBackground} D/FragmentManager :
android.view.View {7365fae V.ED .... ... 0,0-2560,48 # 102002f android : id/statusBarBackground} D/AndroidRuntime : VM 종료 중 E/AndroidRuntime : 치명적 예외 : 메인 프로세스 : example.com .demo, PID : 8156 java.lang.IllegalArgumentException : 조각에 대한 ID 0x4 (알 수 없음)에 대한보기가 없습니다. FragmentB {30cad9b # 3 id = 0x4} android.support.v4.app.FragmentManagerImpl.moveToState (FragmentManager.java:1107) android.support.v4.app.FragmentManagerImpl.moveToState (FragmentManager.java:1295) at android. support.v4.app.BackStackRecord.run (BackStackRecord.java:801) android.support.v4.app.FragmentManagerImpl.execPendingActions (FragmentManager.java:1682) android.support.v4.app.FragmentManagerImpl $ 1.run (FragmentManager.java:541) android.os.Handler.handleCallback (Handler.java:751)에서 android.os.Handler.dispatchMessage (Handler.java:95)에서 android.os.Looper.loop에서 (루퍼 .java : 154) android.app.ActivityThread.main (ActivityThread.java:6119) at java.lang.reflect.Method.invoke (네이티브 메소드) com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:886) at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:776) 타겟 VM, 주소 연결 끊김 : '로컬 호스트 : 8616', 전송 : '소켓'

2 개 개의 주요 클래스 FragmentAAdapter 및 FragmentB가 (당신이 다른 클래스의 경우를 볼 수 있습니다 당신은) 망할 놈의 repo에, 필요

public class FragmentAAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{ 

FragmentA fragmentA; 
Activity activity; 
RecyclerView listView; 

public FragmentAAdapter(FragmentA fragmentA, Activity activity, RecyclerView listView) { 
    this.fragmentA = fragmentA; 
    this.activity = activity; 
    this.listView = listView; 
} 


@Override 
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_b, parent, false); 
    RecyclerView.ViewHolder vh = new BoardViewHolder(v, this); 
    return vh; 
} 

@Override 
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 
    if (holder instanceof BoardViewHolder){ 
     BoardViewHolder pHolder = (BoardViewHolder)holder; 
     pHolder.onBindViewHolder(position); 
    } 
} 

@Override 
public int getItemCount() { 
    return 10; 
} 

public class BoardViewHolder extends RecyclerView.ViewHolder { 

    FragmentAAdapter adapter; 
    FragmentB fragmentB; 
    View view; 

    public BoardViewHolder(View itemView, FragmentAAdapter adapter) { 
     super(itemView); 

     this.view = itemView; 
     this.adapter = adapter; 
    } 

    public void onBindViewHolder(int position) { 

     FragmentManager fm = fragmentA.getChildFragmentManager(); 
     if (fragmentB==null) { 
      Bundle bundle = new Bundle(); 
      bundle.putString("TEXT", "This is Fragment B:" + position); 
      fragmentB = FragmentB.getInstance(bundle); 

      int boardId = generateViewId(); 
      // switch the id of the board to be unique 
      View board = view.findViewById(R.id.board); 
      board.setId(boardId); 

      // now flip fragmentB 
      FragmentTransaction ft = fm.beginTransaction(); 
      ft.replace(boardId, fragmentB); 
      ft.commit(); 
     } 
    } 
} 

private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1); 

public static int generateViewId() { 
    for (;;) { 
     final int result = sNextGeneratedId.get(); 
     // aapt-generated IDs have the high byte nonzero; clamp to the range under that. 
     int newValue = result + 1; 
     if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0. 
     if (sNextGeneratedId.compareAndSet(result, newValue)) { 
      return result; 
     } 
    } 
} 

}

및 FragmentB :

public class FragmentB extends Fragment { 

View root; 

Activity activity; 

String text; 
private TextView textView; 

public static FragmentB getInstance(Bundle bundle) { 
    FragmentB instance = new FragmentB(); 
    instance.setArguments(bundle); 
    return instance; 
} 

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

    activity = (Activity) getActivity(); 

    if (getArguments()!=null) { 
     text = getArguments().getString("TEXT"); 

    } 
} 

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

    root = inflater.inflate(R.layout.row, null, false); 

    textView = (TextView)root.findViewById(R.id.textView); 
    textView.setText(text); 

    return root; 
} 

}

전체 코드 : https://github.com/checklist/NestedFragmentsRecycler

감사합니다!

+0

onCreateViewHolder''내부에 새로운 ID를 생성 조각을 사용하지 않는를하지'onBindViewHolder' : 당신은 많은 소지자 많은 ID를 필요/당신은 이미 – pskink

+0

보기를 가지고 있는데 어떤 스크롤을하기 전에 동일한 예외 인 – checklist

+0

을 얻었습니다.'adb shell dumpsys activity top? '명령의 결과는 무엇입니까? – pskink

답변

1

많은 영혼을 검색 한 후 조각 내에서 ID를 생성 할 수 없음을 확인할 수 있습니다. 그렇게하면 UI가 렌더링되는 동안 Android가 혼란스러워지고 앱이 다운됩니다.

나는 동적으로 생성되어 단편과 같은 동작으로 배치 된 라디오 버튼과 그룹에 대한 ID를 생성 한 다른 프로젝트에서 이것을 시도했습니다. 두 솔루션 : 가 - 당신은 IDS 생성 할 필요가 없습니다 프로그래밍 방식으로 만들지 마십시오 -