我尝试在按下按钮(onClick)事件后将一个片段替换为另一个片段。我是碎片的新手,所以如果我以错误的方式解决这个问题,请告诉我。
在运行时加载帧布局(容器)。然后动态地将片段添加到其中。这很好用。如果我添加setOnClickListener,我会得到一个NullPointerException。这是Java:
public class WelcomeActivity extends ActionBarActivity {
FrameLayout container;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
//setContentView(R.layout.welcome_fragment);
container = (FrameLayout)findViewById(R.id.mainContainer);
// Check that the activity is using the layout version with
// the fragment_container FrameLayout
if (findViewById(R.id.mainContainer) != null) {
// However, if we're being restored from a previous state,
// then we don't need to do anything and should return or else
// we could end up with overlapping fragments.
if (savedInstanceState != null) {
return;
}
addWelcomeFragment();
}
//NPE at the below line
Button submitUser = (Button) findViewById(R.id.submitUser);
submitUser.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View view){
addExpedFragment();
}
});
}
通过研究片段,我在WelcomeActivity类中使用静态类来加载片段。他们在这里:
public static class WelcomeFragment extends Fragment {
public static Fragment newInstance(){
Fragment wFrag = new WelcomeFragment();
return wFrag;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.welcome_fragment, null);
return v;
}
}
//-----------------------------------------------------------------------------------------------------//
public static class ExpedFragment extends Fragment {
public static Fragment secondInstance(){
Fragment eFrag = new ExpedFragment();
return eFrag;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.exped_fragment, null);
return v;
}
}
调用它们的方法也在这里使用WelcomeActivity:
private void addWelcomeFragment(){
Fragment welcome = WelcomeFragment.newInstance();
FragmentTransaction fTrans = getSupportFragmentManager().beginTransaction();
fTrans.add(R.id.mainContainer, welcome);
fTrans.addToBackStack(null);
fTrans.commit();
}
private void addExpedFragment(){
Fragment exped = ExpedFragment.secondInstance();
getSupportFragmentManager().beginTransaction().replace(R.id.mainContainer, exped).commit();
}
我感觉问题与尝试找到按钮视图ID" submitUser"从第一个片段。我的xmls看起来像这样。
第一个空的FrameLayout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<FrameLayout
android:id="@+id/mainContainer"
android:layout_width="wrap_content"
android:layout_height="match_parent" >
</FrameLayout>
</RelativeLayout>
在运行时加载的第一个片段:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/welcome_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
tools:context=".WelcomeActivity" >
<TextView
android:id="@+id/welcome"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/welcome1"
android:textAppearance="?android:attr/textAppearanceLarge" />
<EditText
android:id="@+id/userName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/welcome"
android:layout_alignRight="@+id/welcome"
android:layout_below="@+id/welcome"
android:layout_marginTop="32dp"
android:ems="10"
android:hint="@string/userHint"
android:inputType="textPersonName" >
<requestFocus />
</EditText>
<Button
android:id="@+id/submitUser"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/userName"
android:layout_alignRight="@+id/userName"
android:layout_below="@+id/userName"
android:layout_marginTop="16dp"
android:text="@string/Done" />
<FrameLayout
android:id="@+id/mainContainer"
android:layout_width="wrap_content"
android:layout_height="match_parent" >
</FrameLayout>
</RelativeLayout>
用onClick事件替换第一个片段的第二个片段:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/exped_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
tools:context=".WelcomeActivity" >
<TextView
android:id="@+id/expedText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/exped"
android:textAppearance="?android:attr/textAppearanceLarge">
</TextView>
<FrameLayout
android:id="@+id/mainContainer"
android:layout_width="wrap_content"
android:layout_height="match_parent" >
</FrameLayout>
</RelativeLayout>
如果我忘记在运行时加载第一个片段并且setContentView(第一个片段)没有NullPointerException,但是当按下按钮而不是替换时,这两个片段会相互叠加。
所以我的问题是,如何引用活动片段来正确设置OnClickListener并避免NullPointerException?
Button submitUser = (Button) findViewById(R.id.submitUser);
给出了NPE
答案 0 :(得分:1)
<强>问题:强>
Button submitUser = (Button) findViewById(R.id.submitUser);
submitUser
位于WelcomeFragment's layout
而不是Activity's layout
,这就是为什么它为空。
<强>溶液强>
您需要在activity class
视图中对其进行初始化,而不是在Welcome fragment
中对其进行初始化。
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View v = inflater.inflate(R.layout.welcome_fragment, null);
Button submitUser = (Button) v.findViewById(R.id.submitUser);
submitUser.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View view){
addExpedFragment();
}
});
return v;
}
修改强>
private void addExpedFragment(){
Fragment exped = ExpedFragment.secondInstance();
getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.mainContainer, exped).commit();
}