我有两门课。第一个是活动,第二个是片段,其中有一些EditText。在活动中,我有一个带有async-task的子类,在方法doInBackground中,我得到了一些结果,我保存到变量中。我怎么能把这个变量从子类“我的活动”到这个片段?


当前回答

我想为初学者补充一点,这里被点赞最多的两个答案之间的差异是由不同的片段使用所给出的。

如果你在java类中使用片段,你有想要传递的数据,你可以应用第一个答案来传递数据:

Bundle bundle = new Bundle();
bundle.putString("edttext", "From Activity");
Fragmentclass fragobj = new Fragmentclass();
fragobj.setArguments(bundle);

但是,如果您使用Android Studio为标签片段提供的默认代码,则此代码将无法工作。

即使你用你的FragmentClasses替换默认的PlaceholderFragment,即使你纠正FragmentPagerAdapter到新情况添加一个开关getItem()和另一个开关getPageTitle()(如图所示),它也不会工作。

警告:上面提到的剪辑有代码错误,我稍后会在这里解释,但它有助于了解如何从默认代码转换为选项卡片段的可编辑代码)!如果您考虑该剪辑中的java类和xml文件(代表初学者首次使用选项卡片段的场景),那么我的回答的其余部分就更有意义了。

本页投票最多的答案将不起作用的主要原因是,在选项卡片段的默认代码中,片段被用于另一个java类:FragmentPagerAdapter!

因此,为了发送数据,您可能会在MotherActivity中创建一个包,并使用答案2在FragmentPagerAdapter中传递它。

只是这又错了。(也许你可以这样做,但这只是一个复杂的,不是真正需要的)。

The correct/easier way to do it, I think, is to pass the data directly to the fragment in question, using answer no.2. Yes, there will be tight coupling between the Activity and the Fragment, BUT, for tabbed fragments, that is kind of expected. I would even advice you to create the tabbed fragments inside the MotherActivity java class (as subclasses, as they will never be used outside the MotherActivity) - it is easy, just add inside the MotherActivity java class as many Fragments as you need like this:

 public static class Tab1 extends Fragment {

    public Tab1() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.your_layout_name_for_fragment_1, container, false);
        return rootView;
    }
}.

因此,要将数据从MotherActivity传递到这样一个Fragment,你需要在你的Mother activity的onCreate上面创建私有的Strings/Bundles -你可以填充你想传递给Fragment的数据,并通过onCreate之后创建的方法传递它们(这里称为getMyData())。

public class MotherActivity extends Activity {

    private String out;
    private Bundle results;

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

       // for example get a value from the previous activity
        Intent intent = getIntent();
        out = intent.getExtras().getString("Key");

    }

    public Bundle getMyData() {
        Bundle hm = new Bundle();
        hm.putString("val1",out);
        return hm;
    }
}

然后在fragment类中,你使用getMyData:

public static class Tab1 extends Fragment {
        /**
         * The fragment argument representing the section number for this
         * fragment.
         */
        public Tab1() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.your_layout_name_for_fragment_1, container, false);
            TextView output = (TextView)rootView.findViewById(R.id.your_id_for_a_text_view_within_the_layout);

            MotherActivity activity = (MotherActivity)getActivity();

            Bundle results = activity.getMyData();
            String value1 = results.getString("val1");

            output.setText(value1);
            return rootView;
        }
    }

如果你有数据库查询,我建议你在MotherActivity中执行它们(并将它们的结果作为字符串/整数传递给一个捆绑包中的键,如上所示),因为在选项卡片段中,你的语法将变得更加复杂(例如,这变成了getActivity(),而getIntent变成了getActivity().getIntent),但你也可以选择做你想做的事情。

我对初学者的建议是专注于小步骤。首先,让你的意图打开一个非常简单的选项卡活动,不传递任何数据。这有用吗?它能打开你想要的标签吗?如果不是,为什么?

从这一点开始,通过应用这段视频中介绍的解决方案,看看缺少了什么。对于那个特定的剪辑,mainactivity.xml永远不会显示。这肯定会把你弄糊涂。但是如果你注意的话,你会发现xml片段文件中的context (tools:context)是错误的。每个片段XML都需要指向正确的片段类(或使用分隔符$的子类)。

你还会看到,在主活动java类中,你需要添加TabLayout . setupwithviewpager (mViewPager) -在一行TabLayout TabLayout = (TabLayout) findViewById(R.id.tabs)之后;如果没有这一行,您的视图实际上没有链接到片段的XML文件,但它只显示主活动的XML文件。

除了主活动java类中的行,在主活动XML文件中,您需要更改选项卡以适应您的情况(例如添加或删除TabItems)。如果在主活动XML中没有制表符,那么可能在最初创建活动时没有选择正确的活动类型(新活动-选项卡活动)。

请注意,我在最后3段中谈到了视频!我说的主活动XML,就是视频中的主活动XML,也就是MotherActivity XML文件。

其他回答

使用以下接口在活动和片段之间进行通信

public interface BundleListener {
    void update(Bundle bundle);
    Bundle getBundle();
}

或者使用下面这个通用监听器进行双向通信使用接口

 /**
 * Created by Qamar4P on 10/11/2017.
 */
public interface GenericConnector<T,E> {
    T getData();
    void updateData(E data);
    void connect(GenericConnector<T,E> connector);
}

片段显示法

public static void show(AppCompatActivity activity) {
        CustomValueDialogFragment dialog = new CustomValueDialogFragment();
        dialog.connector = (GenericConnector) activity;
        dialog.show(activity.getSupportFragmentManager(),"CustomValueDialogFragment");
    }

你也可以在onAttach(context)中将你的上下文转换为GenericConnector

在你的活动中

CustomValueDialogFragment.show(this);

在你的片段中

...
@Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        connector.connect(new GenericConnector() {
            @Override
            public Object getData() {
                return null;
            }

            @Override
            public void updateData(Object data) {

            }

            @Override
            public void connect(GenericConnector connector) {

            }
        });
    }
...
    public static void show(AppCompatActivity activity, GenericConnector connector) {
            CustomValueDialogFragment dialog = new CustomValueDialogFragment();
            dialog.connector = connector;
            dialog.show(activity.getSupportFragmentManager(),"CustomValueDialogFragment");
        }

注意:千万不要像"".toString().toString().toString();道路

如果你将片段(具体子类)的引用传递给异步任务,你就可以直接访问片段。

将片段引用传递给异步任务的一些方法:

如果你的异步任务是一个完全成熟的类(类FooTask扩展AsyncTask),那么将你的片段传递到构造函数中。 如果您的异步任务是一个内部类,只需在异步任务定义的范围内声明一个最终的Fragment变量,或者作为外部类的字段。您将能够从内部类访问它。

将数据从活动类发送到片段的更好方法是通过setter方法传递。就像

FragmentClass fragmentClass = new FragmentClass();
fragmentClass.setMyList(mylist);
fragmentClass.setMyString(myString);
fragmentClass.setMyMap(myMap);

并且很容易从类中获得这些数据。

在你的活动中声明静态变量

public static HashMap<String,ContactsModal> contactItems=new HashMap<String, ContactsModal>();

然后在你的片段中像这样做

ActivityName.contactItems.put(Number,contactsModal);

从Activity中发送数据,意图如下:

Bundle bundle = new Bundle();
bundle.putString("edttext", "From Activity");
// set Fragmentclass Arguments
Fragmentclass fragobj = new Fragmentclass();
fragobj.setArguments(bundle);

在Fragment的onCreateView方法中:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    String strtext = getArguments().getString("edttext");    
    return inflater.inflate(R.layout.fragment, container, false);
}