这是一个由两个部分组成的问题。我的问题是一个3片段布局,其中第三个片段(FragmentC)在用户点击另一个片段中的按钮时动态添加。然后,在添加第三个片段后,第三个片段有一个按钮可以最大化/最小化它。
更新:请滚动到结尾查看解决方案
问题1:
我试图改变FrameLayout的可见性属性,该属性作为第三个片段(R.id.fragment_C)的容器。
代码的目的是生成另一个片段,最初具有包含android:visibility =“gone”的XML。然后,在点击按钮并添加片段后,可见性应该更改为VISIBLE。
我知道这已经被讨论过了,但是经过4个小时的尝试使其工作后,我决定问一下我做错了什么。
问题2:
在生成第三个片段之后,我有一个最小化/最大化按钮,该按钮应该隐藏前两个片段,并允许第三个片段填充屏幕。
问题在于使用.setVisibility(View.GONE)时,前两个Fragment的Views未被移除。这个问题以前也提到过,但我无法弄清楚为什么在我的代码中不起作用。
到目前为止的代码(如果太冗长,对不起,但我认为为了您们更好地理解,最好包含所有细节):
现在是第一个Fragment的XML和.java文件。
现在,包含按钮的Fragment的XML和.java文件被添加到了R.id.fragment_C中。
XML和.java文件是用于添加片段的。
更新:请滚动到结尾查看解决方案
问题1:
我试图改变FrameLayout的可见性属性,该属性作为第三个片段(R.id.fragment_C)的容器。
代码的目的是生成另一个片段,最初具有包含android:visibility =“gone”的XML。然后,在点击按钮并添加片段后,可见性应该更改为VISIBLE。
我知道这已经被讨论过了,但是经过4个小时的尝试使其工作后,我决定问一下我做错了什么。
问题2:
在生成第三个片段之后,我有一个最小化/最大化按钮,该按钮应该隐藏前两个片段,并允许第三个片段填充屏幕。
问题在于使用.setVisibility(View.GONE)时,前两个Fragment的Views未被移除。这个问题以前也提到过,但我无法弄清楚为什么在我的代码中不起作用。
到目前为止的代码(如果太冗长,对不起,但我认为为了您们更好地理解,最好包含所有细节):
main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:orientation="vertical"
>
<FrameLayout
android:id="@+id/fragment_A"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:background="#CCCCCC"
>
</FrameLayout>
<FrameLayout
android:id="@+id/fragment_B"
android:layout_width="fill_parent"
android:layout_height="300dp"
android:layout_below="@id/fragment_A"
android:layout_centerHorizontal="true"
android:layout_marginTop="15dp"
android:background="#B4B4B4"
>
</FrameLayout>
<FrameLayout
android:id="@+id/fragment_C"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="@id/fragment_B"
android:layout_centerHorizontal="true"
android:layout_marginTop="0dp"
android:background="#A3A3A3"
android:visibility="gone"
>
</FrameLayout>
</RelativeLayout>
land/main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:paddingLeft="0dp"
android:paddingRight="0dp" >
<LinearLayout
android:id="@+id/fragments_container"
android:layout_width="fill_parent"
android:layout_height="200dp"
android:baselineAligned="false" >
<FrameLayout
android:id="@+id/fragment_A"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="0.5"
android:background="#CCCCCC" >
</FrameLayout>
<FrameLayout
android:id="@id/fragment_B"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="0.5"
android:background="#B4B4B4"
>
</FrameLayout>
</LinearLayout>
<FrameLayout
android:id="@+id/fragment_C"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_below="@id/fragment_container"
android:layout_centerHorizontal="true"
android:layout_marginTop="0dp"
android:background="#A3A3A3"
android:visibility="gone" >
</FrameLayout>
</RelativeLayout>
MainActivity.java
package com.example.android.fragments_proto.activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import com.example.android.fragments_proto.R;
import com.example.android.fragments_proto.fragment.GMC_DateSelectionFragment;
import com.example.android.fragments_proto.fragment.GMC_ProdUnitSelectionFragment;
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
FragmentManager fm = getSupportFragmentManager();
Fragment fragmentA = fm.findFragmentById(R.id.fragment_A);
Fragment fragmentB = fm.findFragmentById(R.id.fragment_B);
if (fragmentA == null) {
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.fragment_A, new FragmentA());
ft.commit();
}
if (fragmentB == null) {
FragmentTransaction ft = fm.beginTransaction();
ft.add(R.id.fragment_B, new FragmentB());
ft.commit();
}
}
}
现在是第一个Fragment的XML和.java文件。
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="match_parent"
android:gravity="center_horizontal"
>
<DatePicker
android:id="@+id/datePicker1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
FragmentA.java
package com.example.android.fragments_proto.fragment;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.DatePicker;
import android.widget.Toast;
import com.example.android.fragments_proto.R;
public class FragmentA extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_A, container, false);
DatePicker datePicker = (DatePicker) view.findViewById(R.id.datePicker1);
datePicker.setCalendarViewShown(true);
datePicker.setSpinnersShown(false);
datePicker.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Activity activity = getActivity();
if (activity != null) {
Toast.makeText(activity, "You Touched ME!", Toast.LENGTH_SHORT).show();
}
return false;
}
});
return view;
}
}
现在,包含按钮的Fragment的XML和.java文件被添加到了R.id.fragment_C中。
fragment_B.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="0.1"
>
<ListView
android:id="@+id/listView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
</ListView>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:orientation="horizontal"
android:gravity="center"
android:layout_height="wrap_content">
<Button
android:id="@+id/button"
android:text="@string/btn_fragment"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
</LinearLayout>
FragmentB.java
package com.example.android.fragments_proto.fragment;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import com.example.android.fragments_proto.R;
public class FragmentB extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragmentB, container, false);
ListView listView = (ListView) view.findViewById(R.id.listView1);
Button button = (Button) view.findViewById(R.id.button);
String[] machines = new String[] { "MachineId-001", "MachineId-002", "MachineId-003", "MachineId-004", "MachineId-005", "MachineId-006", "MachineId-007", "MachineId-008"};
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
listView.setAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.select_dialog_multichoice, machines));
final FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.fragment_C);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Activity activity = getActivity();
if (activity != null) {
getFragmentManager().beginTransaction().replace(R.id.fragment_C, new FragmentC()).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE).addToBackStack(null).commit();
frameLayout.setVisibility(View.VISIBLE);
}
}
});
return view;
}
}
XML和.java文件是用于添加片段的。
fragment_C.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:orientation="horizontal"
android:gravity="center"
android:layout_height="wrap_content">
<Button
android:id="@+id/maximize_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Maximize Me!" />
</LinearLayout>
<TextView
android:id="@+id/text_view"
android:textIsSelectable="true"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FF33FF"
/>
</LinearLayout>
FragmentC.java
package com.example.android.fragments_proto.fragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import com.example.android.fragments_proto.R;
public class FragmentC extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_C, container, false);
TextView textView = (TextView) view.findViewById(R.id.text_view);
final Fragment fragmentA = getFragmentManager().findFragmentById(R.id.fragment_A);
final Fragment fragmentB = getFragmentManager().findFragmentById(R.id.fragment_B);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
FragmentTransaction ft = getFragmentManager().beginTransaction();
if (fragmentA.isVisible() && fragmentB.isVisible()) {
ft.hide(fragmentA);
ft.hide(fragmentB);
fragmentA.getView().setVisibility(View.GONE);
fragmentB.getView().setVisibility(View.GONE);
button.setText("Minimize Me!");
ft.addToBackStack(null);
} else {
ft.show(fragmentA);
ft.show(fragmentB);
fragmentA.getView().setVisibility(View.VISIBLE);
fragmentB.getView().setVisibility(View.VISIBLE);
button.setText("Maximize Me!");
ft.addToBackStack(null);
}
ft.commit();
}
});
return view;
}
}
由Moesio发现问题并提供解决方案
问题:
我的错误在于我试图通过以下代码在 FragmentB.java 中寻找视图:
final FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.fragment_C);
这一行返回了 null,因此当代码到达应该进行 .setVisibility() 的点时,应用程序将返回 nullPointerException。
FragmentC.java 发生了同样的情况(所以我的两个问题是相关的)。视图没有被删除,因为我的 findViewById 是 null!
解决方案:
只需使用 getActivity.findViewById(R.id.your_view) 寻找您的 View 即可。