我有一个具有两个片段的android应用程序,这些片段将数据从fragmentA传递到fragmentB。我可以正确加载所有数据,但是当我改变屏幕方向时,它们都会重新加载。我已经在要保留状态的片段中设置了onSaveInstanceState和onViewStateRestored方法,但是当屏幕方向改变时,什么也不会停留。
The main problem that needs to be fixed is when text is loaded into the TextView in FragmentB - it needs to stay there when the screen orientation is changed.
MainActivity.Java
package com.example.tourguide;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentTransaction;
public class MainActivity extends AppCompatActivity implements FragmentA.FragmentAListener, FragmentB.FragmentBListener {
private FragmentA fragmentA;
private FragmentB fragmentB;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentA = new FragmentA();
fragmentB = new FragmentB();
if(savedInstanceState == null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.container_a, new FragmentA());
ft.replace(R.id.container_b, new FragmentB());
ft.commitNow();
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
@Override
public void onInputASent(CharSequence input) {
fragmentB.updateEditText(input);
}
@Override
public void onInputBSent(CharSequence input) {
fragmentA.updateEditText(input);
}
}```
片段Java
package com.example.tourguide;
import android.content.Context; import android.os.Bundle;
import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.ListFragment;
public class FragmentA extends ListFragment implements AdapterView.OnItemClickListener { private FragmentAListener listener;
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String[] locationList = getActivity().getResources().getStringArray(R.array.location_list);
updateEditText(locationList[position]);
listener.onInputASent(locationList[position]);
}
public interface FragmentAListener {
void onInputASent(CharSequence input);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_a, container, false);
return v;
}
@Override
public void onListItemClick(@NonNull ListView l, @NonNull View v, int position, long id) {
super.onListItemClick(l, v, position, id);
}
public void updateEditText(CharSequence newText) {
//editText.setText(newText);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof FragmentAListener) {
listener = (FragmentAListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement FragmentAListener");
}
}
@Override
public void onDetach() {
super.onDetach();
listener = null;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ArrayAdapter arrayAdapter = ArrayAdapter.createFromResource(getActivity(), R.array.location_list, android.R.layout.simple_list_item_1);
setListAdapter(arrayAdapter);
getListView().setOnItemClickListener(this);
}
}``` FragmentB.Java-这是片段,当旋转屏幕时,需要将该字符串保留在TextView中
package com.example.tourguide;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
public class FragmentB extends Fragment {
private FragmentBListener listener;
private TextView resultsFrag;
private static final String KEY_TITLE = "title_key";
private String stateObject;
public interface FragmentBListener {
void onInputBSent(CharSequence input);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_b, container, false);
resultsFrag = v.findViewById(R.id.tvFragmentB);
//I used the same if block in three different locations and none of them worked
if (savedInstanceState != null) {
String itemTo = savedInstanceState.getString(KEY_TITLE);
resultsFrag.setText(itemTo);
} else {
Toast.makeText(getActivity(), "Error 1", Toast.LENGTH_SHORT).show();
}
return v;
}
public void updateEditText(CharSequence newText) {
String newOption = newText.toString();
stateObject = newText.toString();
Resources res = getResources();
String[] locationDesc = res.getStringArray(R.array.location_description);
if (newOption.equals("Calgary")) {
resultsFrag.setText(locationDesc[0]);
} else if (newOption.equals("Victoria")) {
resultsFrag.setText(locationDesc[1]);
} else if (newOption.equals("Vancouver")) {
resultsFrag.setText(locationDesc[2]);
} else if (newOption.equals("Toronto")) {
resultsFrag.setText(locationDesc[3]);
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof FragmentBListener) {
listener = (FragmentBListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement FragmentBListener");
}
}
@Override
public void onDetach() {
super.onDetach();
listener = null;
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(KEY_TITLE, resultsFrag.getText().toString());
}
@Override
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
//I used the same if block in three different locations and none of them worked
if (savedInstanceState != null) {
String itemTo = savedInstanceState.getString(KEY_TITLE);
resultsFrag.setText(itemTo);
} else {
Toast.makeText(getActivity(), "Error 2", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//I used the same if block in three different locations and none of them worked
if (savedInstanceState != null) {
String itemTo = savedInstanceState.getString(KEY_TITLE);
resultsFrag.setText(itemTo);
} else {
Toast.makeText(getActivity(), "Error 3", Toast.LENGTH_SHORT).show();
}
}
}```
fragment_b.xml
``` 弦乐
<resources>
<string name="app_name">Tour Guide</string>
<string-array name="location_list">
<item>Calgary</item>
<item>Victoria</item>
<item>Vancouver</item>
<item>Toronto</item>
</string-array>
<!-- Descriptions for the locations -->
<string-array name="location_description">
<item>This is a big description for CALGARY - THIS needs to load in for more information regarding CALGARY</item>
<item>This is a big description for VICTORIA - THIS needs to load in for more information regarding VICTORIA</item>
<item>This is a big description for VANCOUVER - THIS needs to load in for more information regarding VANCOUVER</item>
<item>This is a big description for TORONTO - THIS needs to load in for more information regarding TORONTO</item>
</string-array>
</resources>
fragment_a.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/holo_green_light"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="16dp">
<ListView
android:id="@android:id/list"
android:layout_width="wrap_content"
android:layout_height="206dp" />
</LinearLayout>```
activity_main.xml
```
问题来源:Stack Overflow
它们已保存,但是您正在替换它们。用这个
if(savedInstanceState == null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.container_a, new FragmentA());
ft.replace(R.id.container_b, new FragmentB());
ft.commit();
}```
请注意,片段实例化几乎是唯一可以通过这种检查产生正确和预期结果的方案。
除非通过findFragmentByTag+实例化获得,否则不要保留对Fragment的引用。commitNow在这种情况下,您可能需要使用以获得可靠的结果。
编辑:使用更完整的代码更新:
public class MainActivity extends AppCompatActivity implements FragmentA.FragmentAListener, FragmentB.FragmentBListener { private FragmentA fragmentA; private FragmentB fragmentB;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState == null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.container_a, new FragmentA(), "fragmentA");
ft.replace(R.id.container_b, new FragmentB(), "fragmentB");
ft.commitNow();
}
fragmentA = getSupportFragmentManager().findFragmentByTag("fragmentA");
fragmentB = getSupportFragmentManager().findFragmentByTag("fragmentB");
}```
回答来源:Stack Overflow
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。