ViewPager中的片段没有与之关联的活动

时间:2020-01-01 13:55:45

标签: android android-fragments android-intent android-viewpager

我有一个用例,其中我将ViewPager与TabLayout一起使用。我已经使用了Android教程linked here

我的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
     <androidx.viewpager.widget.ViewPager
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/notification_view_pager">
        <com.google.android.material.tabs.TabLayout
            android:id="@+id/notification_tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </androidx.viewpager.widget.ViewPager>
</LinearLayout>

我的活动

public class MyActivity extends AppCompatActivity 
{

    int currentFocussedTab = -1;

    private TabLayout notificationsTabLayout;

    private ViewPager notificationsViewPager;

    private FragmentStatePagerAdapter notificationsStatePagerAdapter;

    private Fragment fragmentOne;

    private Fragment fragmentTwo;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_activity);
        // Setting up tabbed layouts.
        notificationsTabLayout = findViewById(R.id.notification_tabs);

        notificationsTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab)
            {
                int position = tab.getPosition();
                currentFocussedTab = position;
                // Custom function to log click.
                if (position == 0) {
                  fragmentOne.logClick();
                } else {
                  fragmentTwo.logClick();
                }
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab)
            {
                int position = tab.getPosition();

                if (position == 0) {
                   fragmentOne.logUnselect();
                } else
                   fragmentTwo.logUnselect();
                }
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {}
        });

        // Set up view pager.
        notificationsViewPager = findViewById(R.id.notification_view_pager);
        notificationsViewPager.setCurrentItem(0);
        notificationsTabLayout.setupWithViewPager(notificationsViewPager);
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentOne = new FragmentOne();
        fragmentTwo = new FragmentTwo();
        notificationsStatePagerAdapter = new FragmentStatePagerAdapter(fragmentManager,
            FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
            @NonNull
            @Override
            public Fragment getItem(int position)
            {
                return position == 0 ? fragmentOne : fragmentTwo;
            }

            @Override
            public int getCount()
            {
                // Two fixed tabs.
                return 2;
            }

            @Nullable
            @Override
            public CharSequence getPageTitle(int position)
            {
                return position == 0 ? getText(R.string.act_now_tab) : getText(R.string.others_tab);
            }


        };
        notificationsViewPager.setAdapter(notificationsStatePagerAdapter);
    }
}

FragmentOne和Fragment 2的设置都类似。所以我以FragmentOne为例

class FragmentOne extends Fragment {


. . . . Define all UI elements . . . .

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState)
   {
       final View view = inflater.inflate(R.layout.fragment_layout, container, false);
        ... Initialize all the layout UI elements . . . 

       return view;
   }
}

更新

我在片段布局中定义了一个按钮。该按钮以onCreateView方法初始化。单击该按钮后,我想启动一个新活动。

问题

我必须从片段内部加载另一个活动。这就是我的做法

Intent intent = new Intent(getActivity(), MyNewActivity.class);
getActivity().startActivity(intent);

但是,由于getActivity()始终返回null,因此应用程序终止。如果视图分页器中没有该片段,则该函数不会返回null。

期望的行为

我想从视图分页器内部已加载的片段中加载新的应用程序活动。我该如何实现?

2 个答案:

答案 0 :(得分:1)

尝试这种操作,假设您要通过单击按钮启动新的意图。

在您的片段类中

public class MyFragment extends Fragment implements View.OnclickListener {
    private Activity activity;

    @Override
    public void onAttach(Context context) {
        activity = (Activity) context;
    }

    @Override
    public void onDetach(){
        activity = null;
    }

    @Override
    public void onClick(View v) {
        startIntent();
    }

    private void startIntent(){
        if (activity == null) return;
        Intent intent = new Intent(activity, MyNewActivity.class);
        activity.startActivity(intent);
    }
}

如果这不起作用,即活动为空,那么当片段未附加到活动且未通过按钮的onclicklistener出现时,您可能在错误的生命周期阶段开始了意图。

答案 1 :(得分:0)

我会将有问题的方法放在您的Activity中,然后从您的Fragment进行调用。我在类的底部添加了一个方法。

活动:

public class MyActivity extends AppCompatActivity 
{

    int currentFocussedTab = -1;

    private TabLayout notificationsTabLayout;

    private ViewPager notificationsViewPager;

    private FragmentStatePagerAdapter notificationsStatePagerAdapter;

    private Fragment fragmentOne;

    private Fragment fragmentTwo;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_activity);
        // Setting up tabbed layouts.
        notificationsTabLayout = findViewById(R.id.notification_tabs);

        notificationsTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab)
            {
                int position = tab.getPosition();
                currentFocussedTab = position;
                // Custom function to log click.
                if (position == 0) {
                  fragmentOne.logClick();
                } else {
                  fragmentTwo.logClick();
                }
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab)
            {
                int position = tab.getPosition();

                if (position == 0) {
                   fragmentOne.logUnselect();
                } else
                   fragmentTwo.logUnselect();
                }
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {}
        });

        // Set up view pager.
        notificationsViewPager = findViewById(R.id.notification_view_pager);
        notificationsViewPager.setCurrentItem(0);
        notificationsTabLayout.setupWithViewPager(notificationsViewPager);
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentOne = new FragmentOne();
        fragmentTwo = new FragmentTwo();
        notificationsStatePagerAdapter = new FragmentStatePagerAdapter(fragmentManager,
            FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
            @NonNull
            @Override
            public Fragment getItem(int position)
            {
                return position == 0 ? fragmentOne : fragmentTwo;
            }

            @Override
            public int getCount()
            {
                // Two fixed tabs.
                return 2;
            }

            @Nullable
            @Override
            public CharSequence getPageTitle(int position)
            {
                return position == 0 ? getText(R.string.act_now_tab) : getText(R.string.others_tab);
            }


        };
        notificationsViewPager.setAdapter(notificationsStatePagerAdapter);
    }

    public void startNewActivity() {
        Intent intent = new Intent(this, MyNewActivity.class);
        startActivity(intent);
    }
}

内部片段:

将其放入片段的点击功能中

...
MyActivity myActivity = getActivity()
if (myActivity != null)
  myActivity.startNewActivity()
...
相关问题