2017-08-17 2 views
0

ich habe eine Activity mit 02 tabLayoutAbsturz auf Rotation mit diesem Fehler: Fragment wurde noch nicht angebracht

i First Fragment in meinem ersten Tab hinzugefügt, alles war ganz gut, da ich meine Second Fragment in der zweiten Registerkarte hinzugefügt

mein Second Fragment funktioniert, aber wenn ich das Gerät drehen werde es Absturz sein, hier ist mein Codes und Logcat ..

i versuchte befestigen meine FragmentTwo meine MainActivity in diff verschiedene Möglichkeiten .. kann mir jemand sagen, was ist WroNg & & Wie kann ich das richtig machen?

Danke in Advance.

Hauptaktivität:

public class MainActivity extends AppCompatActivity { 
    private DrawerLayout mDrawerLayout; 
    private TabLayout tabLayout; 
    private ViewPager viewPager; 
    private int[] tabIcons = { 
      R.drawable.ic_tab_note, 
      R.drawable.ic_tab_calendar 
    }; 

    private static final int TIME_DELAY = 2000; 
    private static long back_pressed; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     //////// TOOLBAR 
     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 
     ActionBar actionBar = getSupportActionBar(); 
     actionBar.setHomeAsUpIndicator(R.drawable.ic_menu); 
     actionBar.setDisplayHomeAsUpEnabled(true); 

     ///////// DRAWER 
     mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); 
     NavigationView navigationView = 
       (NavigationView) findViewById(R.id.navigation_view); 
     navigationView.setNavigationItemSelectedListener 
       (new NavigationView.OnNavigationItemSelectedListener() { 
        @Override 
        public boolean onNavigationItemSelected(MenuItem menuItem) { 
         menuItem.setChecked(true); 
         mDrawerLayout.closeDrawers(); 
         Toast.makeText(MainActivity.this, 
           menuItem.getTitle(), 
           Toast.LENGTH_LONG).show(); 
         return true; 
        } 
       }); 

     viewPager = (ViewPager) findViewById(R.id.viewpager); 
     setupViewPager(viewPager); 

     tabLayout = (TabLayout) findViewById(R.id.tablayout); 
     tabLayout.setupWithViewPager(viewPager); 
    } 


    private void setupViewPager(ViewPager viewPager) { 
     ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager()); 
     adapter.addFragment(new FragmentOne(), "ONE"); 
     adapter.addFragment(new FragmentTwo(), "TWO"); 
     viewPager.setAdapter(adapter); 
    } 

    class ViewPagerAdapter extends FragmentPagerAdapter { 
     private final List<Fragment> mFragmentList = new ArrayList<>(); 
     private final List<String> mFragmentTitleList = new ArrayList<>(); 

     public ViewPagerAdapter(FragmentManager manager) { 
      super(manager); 
     } 

     @Override 
     public Fragment getItem(int position) { 
      return mFragmentList.get(position); 
     } 

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

     public void addFragment(Fragment fragment, String title) { 
      mFragmentList.add(fragment); 
      mFragmentTitleList.add(title); 
     } 

     @Override 
     public CharSequence getPageTitle(int position) { 
//   return mFragmentTitleList.get(position); 
      return null; 
     } 
    } 

} 

FragmentTwo:

import ir.mirrajabi.persiancalendar.PersianCalendarView; 
import ir.mirrajabi.persiancalendar.core.PersianCalendarHandler; 
import ir.mirrajabi.persiancalendar.core.interfaces.OnDayClickedListener; 
import ir.mirrajabi.persiancalendar.core.interfaces.OnMonthChangedListener; 
import ir.mirrajabi.persiancalendar.core.models.CalendarEvent; 
import ir.mirrajabi.persiancalendar.core.models.PersianDate; 

public class FragmentTwo extends Fragment { 
    private View view; 

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

    @Override 
    public View onCreateView(LayoutInflater inflater, 
          ViewGroup container, 
          Bundle savedInstanceState) { 
     view = inflater.inflate(R.layout.fragment_two_layout, 
       container, false); 

     final PersianCalendarView persianCalendarView = (PersianCalendarView) view.findViewById(R.id.persian_calendar); 
     final PersianCalendarHandler calendar = persianCalendarView.getCalendar(); 
     final PersianDate today = calendar.getToday(); 
     calendar.addLocalEvent(new CalendarEvent(
       today, "Custom event", false 
     )); 
     calendar.addLocalEvent(new CalendarEvent(
       today.clone().rollDay(2, true), "Custom event 2", true 
     )); 
     calendar.setOnMonthChangedListener(new OnMonthChangedListener() { 
      @Override 
      public void onChanged(PersianDate date) { 
       Toast.makeText(getActivity(), calendar.getMonthName(date), Toast.LENGTH_SHORT).show(); 
      } 
     }); 
     persianCalendarView.setOnDayClickedListener(new OnDayClickedListener() { 
      @Override 
      public void onClick(PersianDate date) { 
       for (CalendarEvent e : calendar.getAllEventsForDay(date)) 
        Toast.makeText(getActivity(), e.getTitle(), Toast.LENGTH_LONG).show(); 


       calendar.addLocalEvent(new CalendarEvent(
         today.clone().rollDay(2, false), "Some event that will be added in runtime", false 
       )); 
       persianCalendarView.update(); 
      } 
     }); 

     calendar.setHighlightOfficialEvents(false); 
     TextView txtDayMonth = (TextView) view.findViewById(R.id.txt_day_month); 
     TextView txtYear = (TextView) view.findViewById(R.id.txt_year); 

     String dayAndMonth = calendar.getWeekDayName(today) + calendar.formatNumber(today.getDayOfMonth()) 
       + calendar.getMonthName(today); 
     txtDayMonth.setText(dayAndMonth); 
     txtYear.setText(calendar.formatNumber(today.getYear())); 

     calendar.setColorBackground(getResources().getColor(android.R.color.holo_blue_dark)); 
     persianCalendarView.update(); 


     return view; 
    } 

} 

und hier ist mein activity_main.xml:

<android.support.v4.widget.DrawerLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:id="@+id/drawer_layout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:fitsSystemWindows="true"> 

    <RelativeLayout 
     android:id="@+id/base2" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"> 

     <LinearLayout 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:orientation="vertical"> 

    <android.support.v7.widget.Toolbar 
     android:id="@+id/toolbar" 
     android:layout_width="match_parent" 
     android:layout_height="?attr/actionBarSize" 
     android:background="?attr/colorPrimary" 
     android:theme="@style/ThemeOverlay.AppCompat.Dark"/> 

     <android.support.design.widget.TabLayout 
      android:id="@+id/tablayout" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:background="?attr/colorPrimary" 
      app:tabGravity="fill" 
      android:theme="@style/ThemeOverlay.AppCompat.Dark"/> 

      <RelativeLayout 
       android:id="@+id/relativee" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content"> 

     <android.support.v4.view.ViewPager 
      android:id="@+id/viewpager" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      layout_weight="1"/> 
      </RelativeLayout> 
     </LinearLayout> 
    </RelativeLayout> 

    <android.support.design.widget.NavigationView 
     android:id="@+id/navigation_view" 
     android:layout_width="wrap_content" 
     android:layout_height="match_parent" 
     android:layout_gravity="start" 
     app:headerLayout="@layout/drawer_header" 
     app:menu="@menu/drawer"/> 
</android.support.v4.widget.DrawerLayout> 

und hier ist fragment_two_layout.xml

Logcat:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.drgnme.listhamrah/com.drgnme.listhamrah.MainActivity}: java.lang.IllegalStateException: Fragment has not been attached yet. 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2434) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2494) 
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4095) 
at android.app.ActivityThread.access$1000(ActivityThread.java:153) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1353) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5451) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
Caused by: java.lang.IllegalStateException: Fragment has not been attached yet. 
at android.support.v4.app.Fragment.instantiateChildFragmentManager(Fragment.java:2195) 
at android.support.v4.app.Fragment.getChildFragmentManager(Fragment.java:745) 
at ir.mirrajabi.persiancalendar.core.fragments.CalendarFragment.createViewPagers(CalendarFragment.java:55) 
at ir.mirrajabi.persiancalendar.core.fragments.CalendarFragment.access$000(CalendarFragment.java:27) 
at ir.mirrajabi.persiancalendar.core.fragments.CalendarFragment$1.update(CalendarFragment.java:46) 
at ir.mirrajabi.persiancalendar.PersianCalendarView.update(PersianCalendarView.java:116) 
at com.drgnme.listhamrah.FragmentTwo.onCreateView(FragmentTwo.java:87) 
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2239) 
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1332) 
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1574) 
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1641) 
at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:2959) 
at android.support.v4.app.FragmentController.dispatchActivityCreated(FragmentController.java:201) 
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:550) 
at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:177) 
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1238) 
at android.app.Activity.performStart(Activity.java:6340) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2397) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2494)  
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4095)  
at android.app.ActivityThread.access$1000(ActivityThread.java:153)  
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1353)  
at android.os.Handler.dispatchMessage(Handler.java:102)  
at android.os.Looper.loop(Looper.java:148)  
at android.app.ActivityThread.main(ActivityThread.java:5451)  
at java.lang.reflect.Method.invoke(Native Method)  
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)  
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

Antwort

0

Problem ist nicht in Ihrer App, Problem ist in Persien nCalendar Lib,

Sie werden PersianCalendarView in Ihrem Layout in der Fragment-Klasse aufblasen, wenn Sie ihre Implementierung in PersianCalendarView.java überprüfen, 1. Sie sind ein Layout aufblasen und sie versuchen, ein Fragment in diesem Layout in diesem FragmentManager und seine Arbeit hinzuzufügen fein. 2. aber nicht nur, dass in diesem Fragment versuchen, ViewPager mit getChildFragmentManager() Problem hinzuzufügen kommt ihr nur.

Sie können fragen warum? In bereits hinzugefügt ein FragmentManager dieses Fragment dieser Zeit seine Arbeit gut, aber jetzt ist es abstürzt, denn das ist, können Sie den Unterschied zwischen diesen 2 FragmnetManger überprüfen in this S0 Answer

Für dieses Problem können Sie 3 Dinge tun, 1. Können Sie erstellen Ticket für sie und warten auf das Ergebnis 2. Sie können das Problem beheben 3. Anstatt im Layout hinzufügen, erstellen Sie einfach eine ViewGroup in Fragment und wenn OnActivtyCreated aufgerufen, können Sie diese Layout Runtime hinzufügen.

EDITED

ich diese Probe versucht, und ich versuchte, es in Fragment hinzuzufügen, Problem ich konfrontiert, eigentlich das Calendar Fragment noch nicht angebracht ist, wenn unser Fragment an die Aktivität gebunden, so wie ich bereits erwähnt in Lösung 3, dass wir es in onActivtyCreated hinzufügen können, ist das falsch.

Dann, wie können wir vorübergehend lösen?

Ich löste durch Hinzufügen der Ansicht in onStart (Ich weiß, das ist der falsche Ort wird dies mehrere Zeit im Lebenszyklus von Fragment aufrufen), aber wir können einige Logik hinzufügen und wir können diese Kalenderansicht nur einmal für die Erstellung hinzufügen es funktioniert jetzt, bis das dev in ihrer lib repariert.

Mein Beispiel:

Mein Fragment Layout:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
      xmlns:tools="http://schemas.android.com/tools" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      tools:context="ir.mirrajabi.pc.sample.BlankFragment"> 

    <LinearLayout 
     android:id="@+id/calendar_container" 
     android:layout_width="match_parent" 
     android:layout_height="290dp" 
     android:orientation="vertical"/> 

    <TextView 
     android:id="@+id/txt_day_month" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center_horizontal" 
     android:textColor="#f0f2f3" 
     android:textSize="30sp"/> 

    <TextView 
     android:id="@+id/txt_year" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center_horizontal" 
     android:textColor="#c6d9e2" 
     android:textSize="20sp"/> 

</FrameLayout> 

Fragment Code

public class BlankFragment extends Fragment { 

    private LinearLayout mLinearLayout; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.fragment_blank, container, false); 

     mLinearLayout= (LinearLayout) view.findViewById(R.id.calendar_container); 

     return view; 
    } 

    @Override 
    public void onStart() { 
     super.onStart(); 

     final PersianCalendarView persianCalendarView = new PersianCalendarView(getContext()); 

     // All your remaining PersianCalendarView implementation code here 
     mLinearLayout.addView(persianCalendarView); 
    } 
} 

Hinweis:

If you take above approach, Please add some logic and make sure it's not adding multiple time when onStart calls in the Fragment.

+0

hmmm, danke für deine information .. ich habe den eindruck dass es besser ist die 03 lösung auszuprobieren die du mir gegeben hast; (ich bin irgendwie neu in android) also könntest du mehr darüber erklären? so kann ich mein Problem beheben –

+0

@DRGNme, ich aktualisierte mein Beispiel.gucken –

+0

ja es funktionierte, danke! .. auch ich fand den Entwickler dieser Bibliothek, so gab er mir die Lösung hier –

0

Verschieben Sie alle die folgenden Code onActivityCreated():

final PersianCalendarView persianCalendarView = (PersianCalendarView) view.findViewById(R.id.persian_calendar); 
     final PersianCalendarHandler calendar = persianCalendarView.getCalendar(); 
     final PersianDate today = calendar.getToday(); 
     calendar.addLocalEvent(new CalendarEvent(
       today, "Custom event", false 
     )); 
     calendar.addLocalEvent(new CalendarEvent(
       today.clone().rollDay(2, true), "Custom event 2", true 
     )); 
     calendar.setOnMonthChangedListener(new OnMonthChangedListener() { 
      @Override 
      public void onChanged(PersianDate date) { 
       Toast.makeText(getActivity(), calendar.getMonthName(date), Toast.LENGTH_SHORT).show(); 
      } 
     }); 
     persianCalendarView.setOnDayClickedListener(new OnDayClickedListener() { 
      @Override 
      public void onClick(PersianDate date) { 
       for (CalendarEvent e : calendar.getAllEventsForDay(date)) 
        Toast.makeText(getActivity(), e.getTitle(), Toast.LENGTH_LONG).show(); 


       calendar.addLocalEvent(new CalendarEvent(
         today.clone().rollDay(2, false), "Some event that will be added in runtime", false 
       )); 
       persianCalendarView.update(); 
      } 
     }); 

     calendar.setHighlightOfficialEvents(false); 
     TextView txtDayMonth = (TextView) view.findViewById(R.id.txt_day_month); 
     TextView txtYear = (TextView) view.findViewById(R.id.txt_year); 

     String dayAndMonth = calendar.getWeekDayName(today) + calendar.formatNumber(today.getDayOfMonth()) 
       + calendar.getMonthName(today); 
     txtDayMonth.setText(dayAndMonth); 
     txtYear.setText(calendar.formatNumber(today.getYear())); 

     calendar.setColorBackground(getResources().getColor(android.R.color.holo_blue_dark)); 
     persianCalendarView.update(); 

Es ist eine bewährte Methode, alle Werke nicht anders als das Layout innerhalb onCreateView() Aufblasen

+0

Ähnlich wie 'onCreateView' gibt es' onActivityCreated' aus 'Fragment'. Sie sollten es überschreiben. – Bob

+0

Ich habe, wie folgt, funktioniert aber immer noch nicht: @Override public void onActivityCreated (Bundle savedInstanceState) { super.onActivityCreated (savedInstanceState); .. –

+0

Haben Sie den obigen Code von 'onCreateView' entfernt und in' onActitivityCreated' gesetzt? – Bob

0

die persianCalendarView.update() Linie Bewegen Sie einfach in Ihrem FragmentTwo 's onAttach und entfernt sie aus onCreate():

@Override 
public void onAttachFragment(Fragment childFragment) { 
    super.onAttachFragment(childFragment); 
    persianCalendarView.update(); 
} 

Auch die update() von der Innenseite der persianCalendarView entfernen' s OnDayClickedListener. Ich habe diese Zeile beim Testen hinzugefügt und vergessen, sie aus der Beispiel-App zu entfernen. Sie müssen persianCalendarViewnicht aktualisieren, es sei denn, Sie müssen das Thema oder beim Hinzufügen von Ereignissen in Runtime ändern.

+0

Ja endlich diese Änderungen behoben mein 'RotationBug', Tnx. –

Verwandte Themen