在一个活动中切换2个片段 - Android

时间:2014-07-19 23:58:09

标签: android android-fragments nullpointerexception onclicklistener

我尝试在按下按钮(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

1 个答案:

答案 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();
}