我有两门课。第一个是活动,第二个是片段,其中有一些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文件。
其他回答
将数据从活动类发送到片段的更好方法是通过setter方法传递。就像
FragmentClass fragmentClass = new FragmentClass();
fragmentClass.setMyList(mylist);
fragmentClass.setMyString(myString);
fragmentClass.setMyMap(myMap);
并且很容易从类中获得这些数据。
如果一个活动需要一个片段在初始化后执行一个动作,最简单的方法是让这个活动调用片段实例上的一个方法。在这个片段中,添加一个方法:
public class DemoFragment extends Fragment {
public void doSomething(String param) {
// do something in fragment
}
}
然后在活动中,使用片段管理器访问片段并调用方法:
public class MainActivity extends FragmentActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DemoFragment fragmentDemo = (DemoFragment)
getSupportFragmentManager().findFragmentById(R.id.fragmentDemo);
fragmentDemo.doSomething("some param");
}
}
然后活动可以通过调用此方法直接与片段通信。
在你的活动中声明静态变量
public static HashMap<String,ContactsModal> contactItems=new HashMap<String, ContactsModal>();
然后在你的片段中像这样做
ActivityName.contactItems.put(Number,contactsModal);
我在使用最新的导航体系结构组件时遇到了类似的问题。通过从我的调用活动传递一个包到Fragment,尝试了上述所有代码。
紧跟Android最新发展趋势的最佳解决方案是使用View Model (Android Jetpack的一部分)。
在父Activity中创建并初始化一个ViewModel类,请注意这个ViewModel必须在Activity和fragment之间共享。
现在,在片段的onViewCreated()中,初始化相同的ViewModel并设置观察者来监听ViewModel字段。
如果你需要,这里有一个有用的,深入的教程。
https://medium.com/mindorks/how-to-communicate-between-fragments-and-activity-using-viewmodel-ca733233a51c
使用以下接口在活动和片段之间进行通信
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();道路
推荐文章
- 如何隐藏动作栏之前的活动被创建,然后再显示它?
- 是否有一种方法以编程方式滚动滚动视图到特定的编辑文本?
- 在Android中将字符串转换为Uri
- 如何在NestedScrollView内使用RecyclerView ?
- 移动到另一个EditText时,软键盘下一步点击Android
- Android应用中的GridView VS GridLayout
- Activity和FragmentActivity的区别
- 右对齐文本在android TextView
- 权限拒绝:start前台需要android.permission.FOREGROUND_SERVICE
- 如何更改android操作栏的标题和图标
- Android Split字符串
- 让一个链接在安卓浏览器启动我的应用程序?
- 如何在Android工作室的外部库中添加一个jar ?
- GridLayout(不是GridView)如何均匀地拉伸所有子元素
- 如何让一个片段删除自己,即它的等效完成()?