使用FAB按钮,应用程序在两个片段之间交替显示。我正在尝试使当前片段在旋转屏幕时保持不变,但每次屏幕旋转时应用程序崩溃。我尝试了很多解决方案,但都没有。为什么会崩溃?我正在使用NetBeans,所以我不确定谁发布logcat。
public class agendaFalante extends AppCompatActivity
{
/** Called when the activity is first created. */
private Toolbar toolbar;
private FloatingActionButton fab ;
private listViewFrag lvfrag;
private newEventFrag nef;
private FragmentManager fragmentManager;
private FragmentTransaction fragmentTransaction;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
toolbar = (Toolbar) findViewById (R.id.toolbar);
setSupportActionBar(toolbar);
fragmentManager = getSupportFragmentManager();
fragmentTransaction = fragmentManager.beginTransaction();
if (savedInstanceState == null) {
lvfrag = new listViewFrag();
fragmentTransaction.replace(R.id.ll, lvfrag, "lvfrag");
fragmentTransaction.commit();
}else{
if(lvfrag!=null && lvfrag.isVisible()){
fragmentTransaction.replace(R.id.ll, lvfrag);
fragmentTransaction.commit();
}else if(nef!=null && nef.isVisible()){
fragmentTransaction.replace(R.id.ll, nef);
fragmentTransaction.commit();
}
}
fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
fragmentTransaction = fragmentManager.beginTransaction();
if(nef!=null && nef.isVisible()){
lvfrag = (listViewFrag) getSupportFragmentManager().findFragmentByTag("lvfrag");
fragmentTransaction.replace(R.id.ll,lvfrag);
}else{
if(lvfrag.isVisible()){
nef = (newEventFrag) getSupportFragmentManager().findFragmentByTag("nef");
if(nef==null){
nef = new newEventFrag();
fragmentTransaction.replace(R.id.ll,nef,"nef");
}else{
fragmentTransaction.replace(R.id.ll,nef);
}
}
}
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
});
}
public boolean OnCreateOptionsMenu(Menu menu){
getMenuInflater().inflate(R.menu.menu_layout,menu);
return true;
}
}
main xml
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/root"
tools:context=".agendaFalante">
<LinearLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/ll"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="?attr/colorPrimary"
android:elevation="6dp"
android:minHeight="?attr/actionBarSize"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
/>
</LinearLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:clickable="true"
android:src="@drawable/ic_done"
app:layout_anchor="@id/ll"
app:backgroundTint="#CE93D8"
app:layout_anchorGravity="bottom|right|end"/>
</android.support.design.widget.CoordinatorLayout>
片段1 xml
public class listViewFrag extends Fragment{
private ListView atividadesView;
private ArrayList<String> alist;
private ArrayAdapter<String> aDapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.listviewfrag, container, false);
atividadesView = (ListView) view.findViewById(R.id.listView);
alist = new ArrayList<String>();
alist.add("oi");
aDapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1,alist);
atividadesView.setAdapter(aDapter);
return view;
}
public void addText(String text){
alist.add(text);
aDapter.notifyDataSetChanged();
}
}
片段xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
片段2:
public class newEventFrag extends Fragment{
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.neweventfrag, container, false);
return view;
}
}
片段xml
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
>
<TableRow
android:layout_height="0dp"
android:layout_weight="1">
<EditText
android:text="Insira o título"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
>
</EditText>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.2"
android:id="@+id/record"
android:src="@drawable/ic_mic"
>
</Button>
</TableRow>
<TableRow
android:layout_height="0dp"
android:layout_weight="1">
<DatePicker
android:id="@+id/dpResult"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:datePickerMode="spinner"
android:calendarViewShown="false"
/>
</TableRow>
</TableLayout>
答案 0 :(得分:2)
在屏幕旋转时,碎片不会被破坏。但是,字段lvfrag将不是您在旋转之前创建的片段,直到找到片段并将其分配给字段。所以你应该首先找到&#34; savedInstanceState时的片段不为null。 ---
if (savedInstanceState == null) {
lvfrag = new listViewFrag();
fragmentTransaction.replace(R.id.ll, lvfrag, "lvfrag");
fragmentTransaction.commit();
}else{
lvfrag = (listViewFrag)this.getSupportFragmentManager().findFragmentByTag("lvfrag");
if(lvfrag!=null)
....你需要重置任何片段的字段,然后在这里替换并提交 }
我在这里仅显示lvfrag,但您也可以将代码包含在nef中。您的mainActivity需要知道活动被销毁时哪个片段可见。您应该覆盖onSaveInstanceState方法,以便在旋转时销毁活动时发回包中可见的碎片,然后在替换碎片时捕获该碎片。
答案 1 :(得分:1)
当屏幕旋转时,savedInstanceState
中的onCreate()
参数将包含Bundle
,您可以将Activity
恢复为其所处的状态。但您仍然需要将其视为一个全新的Activity
并再次加载所有控件:
if (savedInstanceState == null) {
lvfrag = new listViewFrag();
fragmentTransaction.replace(R.id.ll, lvfrag, "lvfrag");
fragmentTransaction.commit();
} else {
// even though savedInstanceState is not null
// lvfrag still needs to be created
if(lvfrag.isVisible()){
我已经展示了上面代码的一部分 - 在其中,如果lvfrag
不为空,则假设已经创建了savedInstanceState
- 这是错误的。
每次旋转屏幕时,Android都会从new重新创建您的Activity - 您必须重新创建任何片段(以及任何其他控件)并重新初始化Activity中的所有字段。您的应用崩溃的最可能原因是,当lvfrag.isVisible()
尚未初始化时,您尝试拨打lvfrag
(因此,为空)。
答案 2 :(得分:1)
在以下行中添加以下行:android:configChanges="orientation|screenSize|keyboardHidden"
AndroidManifest.xml
。
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main"
android:configChanges="orientation|screenSize|keyboardHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>