片段中的片段未在第二次调用时设置 class 变量
Fragment within fragment not setting class variable on second call
我有一个包含 TripMemberFragment 和 TripPhotosFragment 的 TripDetailFragment。在 TripMemberFragment 中,我有一个私有实例变量 Trip trip。此变量在第一次调用 TripDetailFragment 时正确设置。但是,在第二次打开 TripDetailFragment 时,此变量为空。
public class TripDetailFragment extends Fragment {
Trip trip;
Context context;
MainActivity.BottomNavAdapter adapter;
private final List<Fragment> fragments = new ArrayList<>();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//inflate view
setUpFragments();
//return inflate view
}
private void setUpFragments(){
fragments.add(new TripMemberFragment(trip));
((TripMemberFragment)fragments.get(0)).setTrip(trip);
fragments.add(new TripPhotosFragment());
adapter = new MainActivity.BottomNavAdapter(getChildFragmentManager(), fragments);
vpTrip.setAdapter(adapter);
vpTrip.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int i, float v, int i1) {
}
@Override
public void onPageSelected(int i) {
switch (i) {
case 0:
tripNavigation.setSelectedItemId(R.id.action_members);
break;
case 1:
tripNavigation.setSelectedItemId(R.id.action_photos);
break;
}
}
@Override
public void onPageScrollStateChanged(int i) {
}
});
tripNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch(item.getItemId()){
case R.id.action_members:
vpTrip.setCurrentItem(0);
return true;
case R.id.action_photos:
vpTrip.setCurrentItem(1);
return true;
default:
return false;
}
}
});
}
}
public class TripMemberFragment extends Fragment {
private Trip trip;
public TripMemberFragment(Trip trp) {
trip = trp;
}
public TripMemberFragment(){}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
members = new ArrayList<>();
memberAdapter = new TripMemberAdapter(members, callbackMember);
rvMembers.setLayoutManager(new LinearLayoutManager(context));
rvMembers.setAdapter(memberAdapter);
loadMembers();
//return inflated view
}
public void loadMembers(){
try{
ParseRelation relation = trip.getRelation("user");
ParseQuery query = relation.getQuery();
query.findInBackground(new FindCallback<ParseUser>() {
@Override
public void done(List<ParseUser> objects, ParseException e) {
Log.d("relation", objects.toString());
members.clear();
members.addAll(objects);
memberAdapter.notifyDataSetChanged();
}
});
}catch (Exception e){
e.printStackTrace();
}
}
}
运行 时没有记录错误或异常,但在第二次 运行 上调用 loadMembers() 时 TripDetailFragment 中的 trip 变量为空,但似乎在构造函数时正确设置因为片段被调用。我认为将 setUpFragments() 放在 onCreateView() 中可能存在问题,但不知道它还能去哪里。
首先,您应该使用静态工厂方法来创建一个新的 Fragment 实例,如下所示:
public static TripMemberFragment newInstance(Trip trip) {
TripMemberFragment fragment = new TripMemberFragment();
Bundle extras = new Bundle();
extras.putParcelable(“EXTRA_TRIP, trip); // or use here putSerializable method if you working with Serializable objects
fragment.setArguments(extras);
return fragment;
}
你现在应该在每次需要 Fragment 的实例时使用这个 newInstance 方法。因此,您需要从片段中删除所有构造函数,以防止使用构造函数创建片段实例。
可以从 Fragment 参数中获取 Trip 对象,如下所示:
getArguments().getParcelable(“EXTRA_TRIP”) // or use here getSerializable method if you working with Serializable objects
在 setUpFragments 方法中 TripDetailFragment 您可以替换这些行:
fragments.add(new TripMemberFragment(trip));
((TripMemberFragment)fragments.get(0)).setTrip(trip);
fragments.add(new TripPhotosFragment());
与:
fragments.add(TripMemberFragment.newInstance(trip));
fragments.add(pTripPhotosFragment.newInstance());
我有一种感觉,传递的对象不知何故丢失了。如果您传递带有参数的对象,则该对象应该在 getArguments() 方法内的片段实例上保留。
我有一个包含 TripMemberFragment 和 TripPhotosFragment 的 TripDetailFragment。在 TripMemberFragment 中,我有一个私有实例变量 Trip trip。此变量在第一次调用 TripDetailFragment 时正确设置。但是,在第二次打开 TripDetailFragment 时,此变量为空。
public class TripDetailFragment extends Fragment {
Trip trip;
Context context;
MainActivity.BottomNavAdapter adapter;
private final List<Fragment> fragments = new ArrayList<>();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//inflate view
setUpFragments();
//return inflate view
}
private void setUpFragments(){
fragments.add(new TripMemberFragment(trip));
((TripMemberFragment)fragments.get(0)).setTrip(trip);
fragments.add(new TripPhotosFragment());
adapter = new MainActivity.BottomNavAdapter(getChildFragmentManager(), fragments);
vpTrip.setAdapter(adapter);
vpTrip.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int i, float v, int i1) {
}
@Override
public void onPageSelected(int i) {
switch (i) {
case 0:
tripNavigation.setSelectedItemId(R.id.action_members);
break;
case 1:
tripNavigation.setSelectedItemId(R.id.action_photos);
break;
}
}
@Override
public void onPageScrollStateChanged(int i) {
}
});
tripNavigation.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch(item.getItemId()){
case R.id.action_members:
vpTrip.setCurrentItem(0);
return true;
case R.id.action_photos:
vpTrip.setCurrentItem(1);
return true;
default:
return false;
}
}
});
}
}
public class TripMemberFragment extends Fragment {
private Trip trip;
public TripMemberFragment(Trip trp) {
trip = trp;
}
public TripMemberFragment(){}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
members = new ArrayList<>();
memberAdapter = new TripMemberAdapter(members, callbackMember);
rvMembers.setLayoutManager(new LinearLayoutManager(context));
rvMembers.setAdapter(memberAdapter);
loadMembers();
//return inflated view
}
public void loadMembers(){
try{
ParseRelation relation = trip.getRelation("user");
ParseQuery query = relation.getQuery();
query.findInBackground(new FindCallback<ParseUser>() {
@Override
public void done(List<ParseUser> objects, ParseException e) {
Log.d("relation", objects.toString());
members.clear();
members.addAll(objects);
memberAdapter.notifyDataSetChanged();
}
});
}catch (Exception e){
e.printStackTrace();
}
}
}
运行 时没有记录错误或异常,但在第二次 运行 上调用 loadMembers() 时 TripDetailFragment 中的 trip 变量为空,但似乎在构造函数时正确设置因为片段被调用。我认为将 setUpFragments() 放在 onCreateView() 中可能存在问题,但不知道它还能去哪里。
首先,您应该使用静态工厂方法来创建一个新的 Fragment 实例,如下所示:
public static TripMemberFragment newInstance(Trip trip) {
TripMemberFragment fragment = new TripMemberFragment();
Bundle extras = new Bundle();
extras.putParcelable(“EXTRA_TRIP, trip); // or use here putSerializable method if you working with Serializable objects
fragment.setArguments(extras);
return fragment;
}
你现在应该在每次需要 Fragment 的实例时使用这个 newInstance 方法。因此,您需要从片段中删除所有构造函数,以防止使用构造函数创建片段实例。
可以从 Fragment 参数中获取 Trip 对象,如下所示:
getArguments().getParcelable(“EXTRA_TRIP”) // or use here getSerializable method if you working with Serializable objects
在 setUpFragments 方法中 TripDetailFragment 您可以替换这些行:
fragments.add(new TripMemberFragment(trip));
((TripMemberFragment)fragments.get(0)).setTrip(trip);
fragments.add(new TripPhotosFragment());
与:
fragments.add(TripMemberFragment.newInstance(trip));
fragments.add(pTripPhotosFragment.newInstance());
我有一种感觉,传递的对象不知何故丢失了。如果您传递带有参数的对象,则该对象应该在 getArguments() 方法内的片段实例上保留。