Android在片段之间传递数据
时间:2020-02-23 14:29:08 来源:igfitidea点击:
在本教程中,我们将开发一个包含TabLayout,ViewPager和Fragments的应用程序。
我们将实现一项功能,将数据从一个片段传递到另一个片段。
Android在片段之间传递数据
意图仅可用于在活动级别上发送数据。
为了在片段之间传递数据,我们需要创建自己的接口。
下面显示了将String数据从一个Fragment发送到另一个Fragment的流程。
让我们开始执行上述流程。
Android在片段项目结构之间传递数据
MainActivity.java类的xml布局如下。
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="https://schemas.android.com/apk/res/android" xmlns:app="https://schemas.android.com/apk/res-auto" xmlns:tools="https://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:context="com.theitroad.passingdatabetweenfragments.MainActivity"> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay" <android.support.design.widget.TabLayout android:id="@+id/tabs" style="@style/MyStyle" android:layout_width="match_parent" android:layout_height="wrap_content" app:tabGravity="fill" app:tabMode="fixed" </android.support.design.widget.AppBarLayout> <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_behavior="@string/appbar_scrolling_view_behavior" </android.support.design.widget.CoordinatorLayout>
TabLayout和ToolBar的样式在styles.xml文件中定义,如下所示。
<resources> <!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> </style> <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" <style name="MyStyle" parent="Widget.Design.TabLayout"> <item name="tabIndicatorColor">#FFFF</item> <item name="tabIndicatorHeight">5dp</item> <item name="tabPaddingStart">8dp</item> <item name="tabPaddingEnd">8dp</item> </style> </resources>
ViewPagerAdapter.java是片段的初始化位置。
代码如下。
public class ViewPagerAdapter extends FragmentPagerAdapter { public ViewPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { Fragment fragment = null; if (position == 0) { fragment = new FragmentOne(); } else if (position == 1) { fragment = new FragmentTwo(); } return fragment; } @Override public int getCount() { return 2; } @Override public CharSequence getPageTitle(int position) { String title = null; if (position == 0) { title = "Tab-1"; } else if (position == 1) { title = "Tab-2"; } return title; } }
FragmentOne会将在EditText中输入的数据发送到FragmentTwo。
下面给出fragment_one.xml的xml布局。
<?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="https://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:fillViewport="true"> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/inMessage" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_above="@+id/btnPassData" android:layout_margin="16dp" android:hint="Enter here" <Button android:id="@+id/btnPassData" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="PASS DATA TO FRAGMENT TWO" </RelativeLayout> </ScrollView>
以下给出fragment_two.xml的xml布局。
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/txtData" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20sp" android:layout_centerInParent="true" android:text="No data received" </RelativeLayout>
FragmentOne.java类的代码如下。
package com.theitroad.passingdatabetweenfragments; import android.content.Context; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.EditText; public class FragmentOne extends Fragment { SendMessage SM; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View rootView = inflater.inflate( R.layout.fragment_one, container, false); return rootView; } @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); Button btnPassData = (Button) view.findViewById(R.id.btnPassData); final EditText inData = (EditText) view.findViewById(R.id.inMessage); btnPassData.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { SM.sendData(inData.getText().toString().trim()); } }); } interface SendMessage { void sendData(String message); } @Override public void onAttach(Context context) { super.onAttach(context); try { SM = (SendMessage) getActivity(); } catch (ClassCastException e) { throw new ClassCastException("Error in retrieving data. Please try again"); } } }
自定义接口SendMessage是在上面的onAttach方法中初始化的。
该接口将在我们即将看到的MainActivity.java中实现。
FragmentTwo.java类的代码如下。
package com.theitroad.passingdatabetweenfragments; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; public class FragmentTwo extends Fragment { TextView txtData; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View rootView = inflater.inflate( R.layout.fragment_two, container, false); return rootView; } @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); txtData = (TextView)view.findViewById(R.id.txtData); } protected void displayReceivedData(String message) { txtData.setText("Data received: "+message); } }
如下所示,将从MainActivity.java中自定义接口的方法内部的FragmentTwo.java实例上调用" displayReceivedData()"。
package com.theitroad.passingdatabetweenfragments; import android.support.design.widget.TabLayout; import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.Toolbar; public class MainActivity extends AppCompatActivity implements FragmentOne.SendMessage{ TabLayout tabLayout; ViewPager viewPager; ViewPagerAdapter viewPagerAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); viewPager = (ViewPager) findViewById(R.id.viewPager); viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager()); viewPager.setAdapter(viewPagerAdapter); tabLayout = (TabLayout) findViewById(R.id.tabs); tabLayout.setupWithViewPager(viewPager); } @Override public void sendData(String message) { String tag = "android:switcher:" + R.id.viewPager + ":" + 1; FragmentTwo f = (FragmentTwo) getSupportFragmentManager().findFragmentByTag(tag); f.displayReceivedData(message); } }
一旦按下FragmentOne中的Button,就会触发上述代码中的sendData()
方法。
我们使用findFragmentByTag方法获取在ViewPagerAdapter中已经初始化的FragmentTwo。