我正在尝试用2个片段做一个简单的android应用程序。第一个片段是输入消息,第二个片段是显示消息。
我需要在纵向模式下一次显示一个片段,两个片段都以横向模式显示。为此,我有2个主要活动的布局文件,一个用于纵向(普通)模式,空的FrameLayout,第二个用于横向模式,两个片段都嵌入在xml布局本身。
当我将屏幕旋转到横向模式时,我看到“onCreateView()”方法为第一个片段调用了两次。
我无法弄清楚如何解决这个问题。任何想法对我都有帮助!!
我已经在stackoverflow中遇到了相同的问题,但它没有帮助,因为这些问题与viewPager,tabs,adapter有关。
进一步详情:
MainActivity.java
public class MainActivity extends Activity implements MyFragment1.MyFragment1Interface{
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState){
Log.d(TAG,"On create called");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(findViewById(R.id.my_fragment_container) != null){
if(savedInstanceState != null)
return;
Log.d(TAG,"creating fragment1 and adding");
MyFragment1 myFragment1 = new MyFragment1();
getFragmentManager().beginTransaction().add(R.id.my_fragment_container,myFragment1).commit();
}
}
@Override
public void showMessage(String message) {
MyFragment2 myFragment2 = (MyFragment2) getFragmentManager().findFragmentById(R.id.fragment2);
if(myFragment2 != null)
myFragment2.displayMessage(message);
else{
myFragment2 = new MyFragment2();
Bundle args = new Bundle();
args.putString(MyFragment1.ARG_MESSAGE,message);
myFragment2.setArguments(args);
getFragmentManager().beginTransaction().replace(R.id.my_fragment_container,myFragment2).addToBackStack(null).commit();
}
}
}
RES /布局/ activity_main.xml中
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/my_fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
RES /布局脊/ activity_main.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="match_parent"
android:orientation="horizontal">
<fragment android:name="com.example.emanickam.sampleapp.MyFragment1"
android:id="@+id/fragment1"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"/>
<fragment android:name="com.example.emanickam.sampleapp.MyFragment2"
android:id="@+id/fragment2"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"/>
</LinearLayout>
MyFragment1.java
public class MyFragment1 extends Fragment {
MyFragment1Interface mMyFragment1Interface;
public static final String ARG_MESSAGE = "arg.message";
private static final String TAG = "MyFragment1";
public interface MyFragment1Interface
{
public void showMessage(String message);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_my_fragment1, container, false);
Button button = (Button) view.findViewById(R.id.send_message);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
sendMessage(v);
}
});
Log.d(TAG,"oncreatview is called");
return view;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
mMyFragment1Interface = (MyFragment1Interface) context;
}
public void sendMessage(View view)
{
EditText message = (EditText) getActivity().findViewById(R.id.message);
mMyFragment1Interface.showMessage(message.getText().toString());
}
}
MyFragment2.java
public class MyFragment2 extends Fragment {
public static final String ARG_MESSAGE = "arg.message";
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_my_fragment2, container, false);
if(getArguments() != null) {
TextView displayMessage = (TextView) view.findViewById(R.id.display_message);
displayMessage.setText(getArguments().getString(ARG_MESSAGE));
}
return view;
}
public void displayMessage(String message)
{
TextView displayMessage = (TextView) getActivity().findViewById(R.id.display_message);
displayMessage.setText(message);
}
}
RES /布局/ fragment_my_fragment1.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="Enter a message" />
<Button
android:id="@+id/send_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Send Message"/>
</LinearLayout>
RES /布局/ fragment_my_fragment2.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/display_message"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
日志:
> D/MainActivity: On create called
> D/MainActivity: creating fragment1 and adding
> D/MyFragment1: oncreatview is called
--screen rotated to landscape here
> D/MainActivity: On create called
> D/MyFragment1: oncreatview is called
> D/MyFragment1: oncreatview is called
更新
我找到了很少的建议答案链接,可以查看同类问题。例如,以下stackoverflow问题的答案,
Android Orientation changes calls onCreate
建议我们需要在清单文件中的活动中添加configChanges属性。
<activity android:name=".MainActivity" android:configChanges="keyboardHidden|orientation|screenSize">
这意味着android系统不会处理方向更改,活动将自行处理。当我使用它时,我为横向模式定义的布局文件(res / layout-land / activity_main.xml)被完全忽略,并且在横向模式下也使用了纵向布局文件,这与我正在尝试的完全不同实现。当然,我理解为什么。这是因为android:configChanges属性。但这不是我的意图。
我不想为我的活动禁用android的屏幕旋转处理。我可以使用销毁活动的默认行为,并在轮换发生时重新创建它,因为我可以存储和检索必要的数据来处理销毁。我只想知道如何修复片段onCreateView()调用两次的问题,而不会根据用户Answer的hackbod禁用旋转处理