从父片段到选项卡片段的接口侦听器不起作用

Posted

技术标签:

【中文标题】从父片段到选项卡片段的接口侦听器不起作用【英文标题】:Interface Listener From Parent Fragment to Tabs Fragment Not Working 【发布时间】:2018-05-17 01:35:56 【问题描述】:

我正在尝试为标签片段的父片段实现接口侦听器。它给出 Null 值错误。 这是我的代码。 在下面给出的代码中,我创建了名为 OnFeedItemClickListener 的接口,并尝试将该方法覆盖到选项卡片段中。

parent_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    android:id="@+id/drawer_layout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    app:layout_scrollFlags="scroll|enterAlways"
    android:layout_
    android:layout_>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_
    android:layout_
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical">

    <!-- TODO: Update blank fragment layout -->
    <android.support.design.widget.AppBarLayout
        android:layout_
        android:layout_
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_
            android:layout_
            android:background="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/AppTheme.PopupOverlay" />
        <LinearLayout
            android:layout_
            android:layout_
            android:gravity="bottom|end"
            app:layout_collapseMode="parallax"
            app:layout_scrollFlags="scroll|enterAlways"
            android:orientation="horizontal">


            <Button
                android:id="@+id/ButtonId"
                style="@style/Widget.AppCompat.Button.Borderless"
                android:layout_
                android:layout_
                android:layout_weight="1"
                android:text="Switch"
                android:textAllCaps="false"
                android:textColor="#FFFFFF" />

        </LinearLayout>
        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_
            android:layout_
            android:background="@color/colorPrimary"
            app:tabGravity="fill"
            app:tabMode="fixed"/>


        </android.support.design.widget.AppBarLayout>
    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_
        android:layout_
        app:layout_scrollFlags="scroll|enterAlways"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />


</android.support.design.widget.CoordinatorLayout>
    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_
        android:layout_
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" >
    </android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>

fragment_one.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    android:background="#FFFFFF">


    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_
        android:layout_
        android:layout_above="@+id/navigation" />

</RelativeLayout>

ParentFragment.java

public class ParentFragment extends Fragment implements NavigationView.OnNavigationItemSelectedListener 

    private List<Fragment> fragmentList = new ArrayList<>();
    private List<String> titleList = new ArrayList<>();
    private View rootView;
    private ViewPager viewPager;
   private TextTabsAdapter adapter;
    private TabLayout tabLayout;
    private Button BtnId;


    private OnFeedItemClickListener onFeedItemClickListener;

    public ParentFragment() 
        // Required empty public constructor
    




    private void initialise() 
        Toolbar toolbar = (Toolbar) rootView.findViewById(R.id.toolbar);
        toolbar.setTitle("Dashboard");
        DrawerLayout drawer = (DrawerLayout) rootView.findViewById(R.id.drawer_layout);

        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                getActivity(), drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.setDrawerListener(toggle);
        drawer.setBackgroundColor(getResources().getColor(R.color.whiteColor));
        toggle.syncState();

        NavigationView navigationView = (NavigationView) rootView.findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);

        viewPager = (ViewPager) rootView.findViewById(R.id.viewPager);
        tabLayout = (TabLayout) rootView.findViewById(R.id.tabs);
    
    private void prepareDataResource() 

            addData(new FragmentOne(), "ONE");
            addData(new FragmentTwo(), "TWO");

    


    private void addData(Fragment fragment, String title) 
        fragmentList.add(fragment);
        titleList.add(title);
    



    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) 
        // Inflate the layout for this fragment
        rootView = inflater.inflate(R.layout.parent_fragment, container, false);

        initialise();
        prepareDataResource();

        adapter = new TextTabsAdapter(getChildFragmentManager(), fragmentList, titleList);

        // Bind Adapter to ViewPager.
        viewPager.setAdapter(adapter);

        // Link ViewPager and TabLayout
        tabLayout.setupWithViewPager(viewPager);
        BtnId = (Button) rootView.findViewById(R.id.CountryId);

        BtnId.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v) 

                onFeedItemClickListener.onButtonClick();
            
        );
        return rootView;
    


    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) 
        return false;
    




    public void setOnFeedItemClickListener(OnFeedItemClickListener onFeedItemClickListener) 
        this.onFeedItemClickListener = onFeedItemClickListener;
    


    public interface OnFeedItemClickListener 
        void onButtonClick();


    

FragmentOne.java

public class FragmentOne extends Fragment implements FeedsAdapter.OnFeedItemClickListener,ParentFragment.OnFeedItemClickListener


    private RecyclerView mrecyclerview;
    private FeedsAdapter feedadapter;
    View rootView;


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

        rootView =  inflater.inflate(R.layout.fragment_one, container, false);
        mrecyclerview = (RecyclerView) rootView.findViewById(R.id.recyclerView);
        mrecyclerview.setLayoutManager(new LinearLayoutManager(getContext()));


        populateFeedsData();
        ParentFragment parentFragment = new ParentFragment();
        parentFragment.setOnFeedItemClickListener(this);

        return rootView;
    


    @Override
    public void onButtonClick() 
        Toast.makeText(getContext(), "ButtonClicked", Toast.LENGTH_SHORT).show();
    

请帮我解决这个问题,非常感谢:)

【问题讨论】:

【参考方案1】:

在您的 FragmentOne 类中,您正在创建 ParentFragment 的新实例。

ParentFragment parentFragment = new ParentFragment();

您实际需要做的是获取创建 FragmentOne 子片段的 ParentFragment 实例。

要做到这一点,你可以试试这个:

ParentFragment parentFrag = ((ParentFragment)FragmentOne.this.getParentFragment());

现在你可以通过parentFrag调用setOnFeedItemClickListener()函数了。

希望对你有帮助!

【讨论】:

ChildFragment 是从哪里来的?是 ChildFragment 是 FragmentOne 吗?当我添加您的代码 ChildFragment 以错误(红色警报)格式显示时 当我在两个不同的片段标签一和标签二中覆盖该方法时,它仅适用于一个片段标签而不适用于另一个片段 ParentFragment 中的 setOnFeedItemClickListener() 一次只设置一个侦听器实例,因此它只适用于一个子片段。您可以做的是使用两个侦听器或在每次更改片段时调用 setOnFeedItemClickListener(),即当您切换标签时! 将您的应用程序置于调试模式并检查当您切换选项卡时,是否会调用各个片段的 onCreateView?

以上是关于从父片段到选项卡片段的接口侦听器不起作用的主要内容,如果未能解决你的问题,请参考以下文章

listview OnItemClick 侦听器在片段中不起作用

中继片段传播不起作用

FragmentTransaction 隐藏/显示有时不起作用

数据从父片段传递到选项卡片段(子) - Android

Android - 一个选项卡中的多个片段

Recyclerview 滚动在嵌套滚动视图中的片段中不起作用