如何使用 TabLayout 将数据从 Activity 传递到 Fragment

Posted

技术标签:

【中文标题】如何使用 TabLayout 将数据从 Activity 传递到 Fragment【英文标题】:How to pass data from Activity to Fragment with TabLayout 【发布时间】:2020-12-23 02:15:49 【问题描述】:

我一直在尝试使用 bundle 将数据从 Main Activity 传递到 Fragments。我使用 TabLayout 和 ViewPager 以 Tab 格式在我的活动中添加片段。我没有收到任何错误,但我得到了一个空对象作为回报,它在我的第一个片段上显示“错误”,因为我为空对象添加了一个 If 条件。 这是我的代码

主要活动代码

package com.example.activitytofragmenttest;

import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager.widget.ViewPager;

import android.os.Bundle;
import android.widget.TextView;

import com.google.android.material.tabs.TabLayout;

public class MainActivity extends AppCompatActivity 

    TextView textView;
    private ViewPager viewPager;
    private ViewPagerAdapter viewPagerAdapter;
    private TabLayout tabLayout;

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

        //Text View
        textView = findViewById(R.id.mainTextView);

        //TabLayout and ViewPager
        tabLayout = findViewById(R.id.tabLayout);
        viewPager = findViewById(R.id.viewPager);
        viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
        tabViewPager();

        Bundle bundle = new Bundle();
        String message = textView.getText().toString();
        bundle.putString("key",message);
        Fragment_1 fragment_1 = new Fragment_1();
        fragment_1.setArguments(bundle);

        viewPager.setAdapter(viewPagerAdapter);
        tabLayout.setupWithViewPager(viewPager);
    

    private void tabViewPager() 
        viewPagerAdapter.AddFragment(new Fragment_1(),"Frag1");
        viewPagerAdapter.AddFragment(new Fragment_2(),"Frag2");
        viewPagerAdapter.AddFragment(new Fragment_3(),"Frag3");
    

查看页面代码

package com.example.activitytofragmenttest;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;

import java.util.ArrayList;
import java.util.List;

public class ViewPagerAdapter extends FragmentPagerAdapter 
    private final List<Fragment> listFragment = new ArrayList<>();
    private final List<String> listTitle = new ArrayList<>();


    public ViewPagerAdapter(@NonNull FragmentManager fm) 
        super(fm);
    

    @NonNull
    @Override
    public Fragment getItem(int position) 
        return listFragment.get(position);
    

    @Override
    public int getCount() 
        return listTitle.size();
    

    @Nullable
    @Override
    public CharSequence getPageTitle(int position) 
        return listTitle.get(position);
    


    public void AddFragment (Fragment fragment, String title)
        listFragment.add(fragment);
        listTitle.add(title);
    

片段 1 代码

package com.example.activitytofragmenttest;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

public class Fragment_1 extends Fragment

    TextView fragment_1TextView;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) 
        View v = inflater.inflate(R.layout.fragment_1,container,false);

        fragment_1TextView = v.findViewById(R.id.fragment1TextView);
        Bundle message = getArguments();
        if (message != null)
            fragment_1TextView.setText(message.getString("key"));
        else 
            fragment_1TextView.setText("Error");
        
        return v;
    

片段 2 代码

package com.example.activitytofragmenttest;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

public class Fragment_2 extends Fragment 
    TextView fragment_2TextView;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) 
        View v = inflater.inflate(R.layout.fragment_2, container, false);

        fragment_2TextView = v.findViewById(R.id.fragment2TextView);
//        Bundle bundle = getArguments();
//        if (bundle != null) 
//            fragment_2TextView.setText(bundle.getString("key"));
//        
        return v;
    

片段 3 代码

package com.example.activitytofragmenttest;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

public class Fragment_3 extends Fragment 
    TextView fragment_3TextView;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) 
        View v = inflater.inflate(R.layout.fragment_3, container, false);

        fragment_3TextView = v.findViewById(R.id.fragment3TextView);
//        Bundle bundle = getArguments();
//        if (bundle != null) 
//            fragment_2TextView.setText(bundle.getString("key"));
//        
        return v;
    

谁能建议我为什么从主 Activity 获取一个空对象到片段,以及如何将多个数据从主 Activity 传输到其他片段以及第二个和第三个片段。

【问题讨论】:

【参考方案1】:

启动 Fragment 时,您可以通过 bundle 传递参数

/*ACTIVITY CODE*/
Bundle args = new Bundle();
args.putStringArrayList("argument_name", myListInString);
MyFragment fragment = new MyFragment();
fragment.setArguments(args);
fragment.show(fragmentTransaction, "fragment_tag")

并在您的新 sn-p 中使用它们,如下所示

/* FRAGMENT CODE */
ArrayList<String> myList = getArguments.getStringArrayList("argument_name");
// ... FILL TABLE

【讨论】:

非常感谢,很抱歉这么晚才回复您,这确实对我的情况有所帮助 没问题,只要问题已经解决了,如果对你有帮助,最好标记为解决方案,以便其他人可以将答案作为参考【参考方案2】:

这是一个代码排序和范围问题。

你在

中创建一个新的Fragment_1

viewPagerAdapter.AddFragment(new Fragment_1(),"Frag1");

并将其存储在 ViewPagerAdapter 中,它没有附加捆绑包。

然后您稍后在 oncreate 的本地范围内创建一个新的 Fragment_1 实例,并将 Bundle 附加到它,然后丢弃此实例。

更好的代码排序。

        //....
        viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());

        Bundle bundle = new Bundle();
        String message = textView.getText().toString();
        bundle.putString("key",message);
        Fragment_1 fragment_1 = new Fragment_1();
        fragment_1.setArguments(bundle);

        // Add the existing instance of the Fragment_1 to the viewpager instead of creating another new instance.
        viewPagerAdapter.AddFragment(fragment_1,"Frag1");
        viewPagerAdapter.AddFragment(new Fragment_2(),"Frag2");
        viewPagerAdapter.AddFragment(new Fragment_3(),"Frag3");

        viewPager.setAdapter(viewPagerAdapter);
        //....

【讨论】:

以上是关于如何使用 TabLayout 将数据从 Activity 传递到 Fragment的主要内容,如果未能解决你的问题,请参考以下文章

如何将tablayout的指示器从底部更改为顶部?

如何从片段更改 Tablayout 的背景颜色?

如何在 Android 上的 TabLayout 中以编程方式添加选项卡

如何从(和替换)TabLayout 和 ViewPager 移动到新片段?

如何使用 Tablayout 清除 Viewpager 的缓存内存

如何在 CollapsingToolbarLayout 中使用带有 Toolbar 的 TabLayout?