gpt4 book ai didi

java - Android fragment - 按下 fragment 中的文本后出现 "Activity has been destroyed"

转载 作者:行者123 更新时间:2023-12-02 01:36:16 25 4
gpt4 key购买 nike

因此,我一直在尝试在我的应用程序中实现一项功能,当我从 searchBoxResultsFragment(显示搜索框用户结果的 fragment )中单击用户名时,它将转到用户的轮廓。

用户的个人资料将被放置在名为 UserFragment 的新 fragment 中。因此基本上 searchBoxResultsFragment 将被 UserFragment 替换。因此,我在调用函数中使用了 ft.replace() 来为 UserFragment 创建一个新实例,该实例位于 userFragment() 内部MainNavigation Activity 类的函数。

但是,我遇到了错误Activity has been destroy,导致我的应用程序崩溃。

我是 Android 开发新手,正在自学如何开发应用程序。

这些是我的代码:

MainNavigation.java

public class MainNavigation extends AppCompatActivity {

private BottomNavigationView mBottomNav;

// fix main layout of navigation
ImageButton uProfileBtn, searchBox;

GetSearchBoxResults getSearcResults;

EditText searchBoxText;

Fragment frag = null;


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

// hide action bar
if(this.getSupportActionBar()!=null) {
this.getSupportActionBar().hide();
}

uProfileBtn = (ImageButton) findViewById(R.id.profileBtn);
searchBox = (ImageButton) findViewById(R.id.searchFriendBtn);

mBottomNav = (BottomNavigationView) findViewById(R.id.navigation);
mBottomNav.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
selectFragment(item);
return true;
}
});

uProfileBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// goes to the Profile Fragment
profileFragment();
}
});

searchBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// goes to the Search Box Fragment
searchBoxResultsFragment();
}
});
}

private void profileFragment() {
frag = ProfileFragment.newInstance("test1", "test2");
if (frag != null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.fragmentContainer, frag, frag.getTag());
ft.commit();
}
}

private void searchBoxResultsFragment() {
frag = SearchBoxFragment.newInstance("test1", "test2");
if (frag != null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.fragmentContainer, frag, frag.getTag());
ft.commit();
}
}

// so it can be called from the adapter
public void userFragment() {
frag = UserFragment.newInstance("test1", "test2");
if (frag != null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.fragmentContainer, frag, frag.getTag());
ft.commit();
}
}

private void selectFragment(MenuItem item) {
// init corresponding fragment
switch (item.getItemId()) {
case R.id.nav_home_btn:
frag = HomeFragment.newInstance("test1", "test2");
break;
case R.id.nav_message_btn:
frag = MessagesFragment.newInstance("test1", "test2");
break;
case R.id.nav_notif_btn:
frag = NotificationsFragment.newInstance("test1", "test2");
break;
case R.id.nav_settings_btn:
frag = SettingsFragment.newInstance("test1", "test2");
break;
}

// uncheck the other items
for (int i = 0; i< mBottomNav.getMenu().size(); i++) {
MenuItem menuItem = mBottomNav.getMenu().getItem(i);
menuItem.setChecked(menuItem.getItemId() == item.getItemId());
}

// sets the fragment to show
if (frag != null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.fragmentContainer, frag, frag.getTag());
ft.commit();
}
}
}

SearchBoxFragment.java

public class SearchBoxFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";

// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;

GetSearchBoxResults getSearcResults;

Fragment frag;

EditText searchBox;
TextView uUsername;

private OnFragmentInteractionListener mListener;

public SearchBoxFragment() {
// Required empty public constructor
}

/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment SearchBoxFragment.
*/
// TODO: Rename and change types and number of parameters
public static SearchBoxFragment newInstance(String param1, String param2) {
SearchBoxFragment fragment = new SearchBoxFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_search_box, container, false);
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState){
searchBox = (EditText) getActivity().findViewById(R.id.searchTopBar);
//uUsername = (TextView) getActivity().findViewById(R.id.userUsername);
getSearcResults = new GetSearchBoxResults(getContext(), getActivity());
// combines the searched input with the API REST call
getSearcResults.execute("http://192.168.1.4:8000/api/search/?search=" + searchBox.getText().toString());
}

// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}

@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
}
}

@Override
public void onDetach() {
super.onDetach();

try {
Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");
childFragmentManager.setAccessible(true);
childFragmentManager.set(this, null);

} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
mListener = null;
}

// so it can be called from the adapter
/*public void UserFragment() {
frag = UserFragment.newInstance("test1", "test2");
if (frag != null) {
FragmentTransaction ft = frag.getFragmentManager().beginTransaction();
ft.replace(R.id.fragmentContainer, frag, frag.getTag());
ft.commit();
}
}*/

/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}

SearchResultsAdapter.java

public class SearchResultsAdapter extends  RecyclerView.Adapter<SearchResultsAdapter.CustomViewHolder>{
private List<User> users;

MainNavigation mainNavHelper;

public class CustomViewHolder extends RecyclerView.ViewHolder {
public TextView userFN, userUN;

public CustomViewHolder(View view) {
super(view);
userFN = (TextView) view.findViewById(R.id.userFullName);
userUN = (TextView) view.findViewById(R.id.userUsername);

// when userUN is clicked, then go to their profile
userUN.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
userUN.setText("this text was clicked");

mainNavHelper = new MainNavigation();
mainNavHelper.userFragment();
}
});
}
}

public SearchResultsAdapter(List<User> users){
this.users = users;
}

@Override
public SearchResultsAdapter.CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.users_list, parent, false);

return new SearchResultsAdapter.CustomViewHolder(itemView);
}

@Override
public void onBindViewHolder(SearchResultsAdapter.CustomViewHolder holder, int position) {
User user = users.get(position);
String uFN = user.getFirstName() + " " + user.getLastName();
holder.userFN.setText(uFN);
holder.userUN.setText(user.getUsername());
}

@Override
public int getItemCount() {
return users.size();
}
}

UserFragment.java

public class UserFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";

// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;

private OnFragmentInteractionListener mListener;

public UserFragment() {
// Required empty public constructor
}

/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment UserFragment.
*/
// TODO: Rename and change types and number of parameters
public static UserFragment newInstance(String param1, String param2) {
UserFragment fragment = new UserFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_user, container, false);
}

// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}

@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
}
}

@Override
public void onDetach() {
super.onDetach();

try {
Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");
childFragmentManager.setAccessible(true);
childFragmentManager.set(this, null);

} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
mListener = null;
}

/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}

这是我针对该问题的 logcat。

03-17 20:51:57.409 8879-8879/com.example.darkestmidnight.lykeyfoods E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.darkestmidnight.lykeyfoods, PID: 8879
java.lang.IllegalStateException: Activity has been destroyed
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:2114)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:683)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:637)
at com.example.darkestmidnight.lykeyfoods.activities.main_navigation.MainNavigation.UserFragment(MainNavigation.java:101)
at com.example.darkestmidnight.lykeyfoods.activities.main_navigation.adapters.SearchResultsAdapter$CustomViewHolder$1.onClick(SearchResultsAdapter.java:35)
at android.view.View.performClick(View.java:6294)
at android.view.View$PerformClick.run(View.java:24770)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

我将非常感谢任何帮助!

最佳答案

您做错的是您在这一行以编程方式创建 Activity 的新实例

mainNavHelper = new MainNavigation();

解决此问题的方法是将 MainNavigation 实例传递给适配器并使用它

public class SearchResultsAdapter extends  RecyclerView.Adapter<SearchResultsAdapter.CustomViewHolder>{
private List<User> users;

Context context;

public class CustomViewHolder extends RecyclerView.ViewHolder {
public TextView userFN, userUN;

public CustomViewHolder(View view) {
super(view);
userFN = (TextView) view.findViewById(R.id.userFullName);
userUN = (TextView) view.findViewById(R.id.userUsername);

// when userUN is clicked, then go to their profile
userUN.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
userUN.setText("this text was clicked");
if (context instanceOf MainNavigation) {
((MainNavigation) context).userFragment();
}
}
});
}
}

public SearchResultsAdapter(Context context, List<User> users){
this.context = context;
this.users = users;
}

@Override
public SearchResultsAdapter.CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.users_list, parent, false);

return new SearchResultsAdapter.CustomViewHolder(itemView);
}

@Override
public void onBindViewHolder(SearchResultsAdapter.CustomViewHolder holder, int position) {
User user = users.get(position);
String uFN = user.getFirstName() + " " + user.getLastName();
holder.userFN.setText(uFN);
holder.userUN.setText(user.getUsername());
}

@Override
public int getItemCount() {
return users.size();
}
}

关于java - Android fragment - 按下 fragment 中的文本后出现 "Activity has been destroyed",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55214154/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com