0

我有一个Activity02tabLayout

First Fragment在我的第一个选项卡中添加,一切都很好,因为我Second Fragment在第二个选项卡中添加了我的

我的Second Fragment作品,但是当我旋转设备时它会崩溃,这是我的代码和 logCat ..

我试图以不同的方式将我的附加FragmentTwo到我MainActivity的..有人可以告诉我出了什么问题&&我该如何正确地做到这一点?

提前致谢。

主要活动:

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;
        }
    }

}

片段二:

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;
    }

}

这是我的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>

这是fragment_two_layout.xml

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorPrimaryDark"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v7.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="24dp">

    <ir.mirrajabi.persiancalendar.PersianCalendarView
        android:id="@+id/persian_calendar"
        android:layout_width="match_parent"
        android:layout_height="290sp"
        app:pcv_colorBackground="#292929"
        app:pcv_colorDayName="#bab6b6"
        app:pcv_colorHoliday="#ffd506"
        app:pcv_colorHolidaySelected="#f1f2f3"
        app:pcv_colorNormalDaySelected="#d9d9d9"
        app:pcv_colorNormalDay="#f3f4f5"
        app:pcv_eventUnderlineColor="#02f0f0"
        app:pcv_fontSize="20sp"
        app:pcv_headersFontSize="14sp"/>
        </android.support.v7.widget.CardView>
        </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_marginBottom="8dp">

        <TextView
            android:id="@+id/txt_day_month"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@color/colorAccent"
            android:layout_gravity="center_horizontal"
            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="@color/colorAccent"
            android:textSize="20sp"/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal">

        <Button
            android:id="@+id/change_to_ad"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Change to Gregorian Calendar"
            android:textSize="14dp"/>
    </LinearLayout>
</LinearLayout>

日志猫:

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)
4

3 回答 3

1

将以下所有代码移至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();

最好的做法是不要做任何工作,而不是膨胀里面的布局onCreateView()

于 2017-08-17T18:49:34.577 回答
1

只需将persianCalendarView.update()行移到您FragmentTwo的 'sonAttach中并将其从 中删除onCreate()

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

还要从'supdate()的内部删除。我在测试时添加了该行,却忘记从示例应用程序中删除它。除非您需要更改主题在运行时添加事件,否则您不必更新persianCalendarViewOnDayClickedListenerpersianCalendarView

于 2017-08-18T09:26:20.770 回答
0

问题不在您的应用程序中,问题在 PersianCalendar Lib 中,

如果您检查 PersianCalendarView.java 中的实现,则您正在 Fragment 类的布局中膨胀PersianCalendarView,1. 他们正在膨胀一个布局,并且他们试图在该 FragmentManager 中的该布局中添加一个 Fragment 并且它工作正常。2.但不仅在那个片段中,他们试图使用getChildFragmentManager()问题添加 ViewPager 仅来自她。

你可以问为什么?在已经有一个 FragmentManager 添加了这个 Fragment 时它工作正常,但现在它崩溃了,为此,您可以在这个 S0 Answer中检查 2 FragmnetManger 之间的区别

对于这个问题,您可以做 3 件事,1. 您可以为他们创建票证并等待结果 2. 您可以修复该问题 3. 而不是在布局中添加,只需在 Fragment 中创建一个 ViewGroup 并且当调用 onActivtyCreated 时您可以添加该布局运行时。

已编辑

我尝试了该示例,并尝试将其添加到 Fragment 中,我面临的问题是,实际上即使我们的 Fragment 附加到 Activity,CalendarView 片段也没有附加,所以正如我在解决方案 3 中提到的那样,我们可以将其添加onActivtyCreated到错误的。

那我们怎么能暂时解决呢?

我通过添加视图来解决onStart(我知道这是错误的地方,这将在 Fragment 的生命周期中多次调用),但是我们可以添加一些逻辑,我们可以只添加这个日历视图一次,让它现在工作直到在他们的库中进行开发修复。

我的样本:

我的片段布局:

<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>

片段代码

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);
    }
}

笔记:

如果您采用上述方法,请添加一些逻辑并确保在 Fragment 中调用 onStart 时不会添加多次。

于 2017-08-17T20:42:43.677 回答