检测来自主要活动的片段的点击

时间:2014-01-12 08:21:24

标签: java android android-fragments

我试图在点击事件中检测来自我的参考活动

的片段中的按钮

背景 ::由于我有2个片段,其中一个片段上有一个按钮,点击按钮我想将片段替换为新片段.....我是尝试以编程方式实现此目的,例如使用findviewbyid

MainActivity.java

public class MainActivity extends  FragmentActivity implements MyInterface{

    //Fragment fragment;
    Fragment fragment;
    Button btnFragment1, btnFragment2, btnFragment3;

    FragmentManager fragmentManager=getSupportFragmentManager();
    FragmentTransaction fragmentTransaction;


    /** Called when the activity is first c1reated. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btnFragment1 = (Button)findViewById(R.id.displayfragment1);
        btnFragment2 = (Button)findViewById(R.id.displayfragment2);
        btnFragment3=(Button)findViewById(R.id.button1);
        fragmentTransaction=fragmentManager.beginTransaction();

        //add a fragment 
        MyFragment myFragment = new MyFragment();

        fragmentTransaction.add(R.id.myfragment, myFragment);
        fragmentTransaction.commit();

        btnFragment1.setOnClickListener(btnFragmentOnClickListener);
        btnFragment2.setOnClickListener(btnFragmentOnClickListener);
        btnFragment3.setOnClickListener(btnFragmentOnClickListener);
    }

    /*

    public void ReplaceFragment(View V){

        MyFragment2 breakfast_fragment1=new MyFragment2();
        fragmentTransaction=fragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.myfragment, breakfast_fragment1, "Tag1");
        fragmentTransaction.commit();

    }
    */


    Button.OnClickListener btnFragmentOnClickListener
    = new Button.OnClickListener(){

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            Fragment newFragment;

            // Create new fragment
            if(v == btnFragment1){
                newFragment = new MyFragment();
            }

            else{
                newFragment = new MyFragment2();
            }

            FragmentTransaction transaction=fragmentManager.beginTransaction();


            transaction.replace(R.id.myfragment, newFragment);
            transaction.addToBackStack(null);

            // Commit the transaction
            transaction.commit();
        }};


    @Override
    public void buttonClicked() {
        // TODO Auto-generated method stub

        Toast.makeText(this, "Hey", Toast.LENGTH_SHORT).show();
    }

}

MyFragment.java

public class MyFragment extends Fragment {

    MyInterface interface1;

     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
       Bundle savedInstanceState) {
      // TODO Auto-generated method stub
      View myFragmentView = inflater.inflate(R.layout.fragmentlayout, container, false);

      return myFragmentView;
     }


     public void setInterface(MyInterface interface2) {
          this.interface1 = interface2;
       }

       public void onClick(View v) {
           interface1.buttonClicked();
       }

}

main.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="horizontal" >

    <LinearLayout 
        android:layout_width="0px"
        android:layout_weight="1"
        android:layout_height="match_parent" 
        android:orientation="vertical" >
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content" 
        android:text="Select Fragment:" />
    <Button
        android:id="@+id/displayfragment1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" 
        android:text="Fragment 1" />
    <Button
        android:id="@+id/displayfragment2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" 
        android:text="Fragment 2" />
    </LinearLayout>
    <LinearLayout
        android:id="@+id/myfragment"
        android:layout_width="0px"
        android:layout_weight="3"
        android:layout_height="match_parent" 
        android:orientation="vertical"/>

</LinearLayout>

MyInterface.java

public interface MyInterface {
    public void buttonClicked();
}

日志::

01-12 13:37:31.679: E/AndroidRuntime(14297): FATAL EXCEPTION: main
01-12 13:37:31.679: E/AndroidRuntime(14297): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.fragmenttest/com.example.fragmenttest.MainActivity}: java.lang.NullPointerException
01-12 13:37:31.679: E/AndroidRuntime(14297):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
01-12 13:37:31.679: E/AndroidRuntime(14297):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
01-12 13:37:31.679: E/AndroidRuntime(14297):    at android.app.ActivityThread.access$2300(ActivityThread.java:125)
01-12 13:37:31.679: E/AndroidRuntime(14297):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
01-12 13:37:31.679: E/AndroidRuntime(14297):    at android.os.Handler.dispatchMessage(Handler.java:99)
01-12 13:37:31.679: E/AndroidRuntime(14297):    at android.os.Looper.loop(Looper.java:123)
01-12 13:37:31.679: E/AndroidRuntime(14297):    at android.app.ActivityThread.main(ActivityThread.java:4627)
01-12 13:37:31.679: E/AndroidRuntime(14297):    at java.lang.reflect.Method.invokeNative(Native Method)
01-12 13:37:31.679: E/AndroidRuntime(14297):    at java.lang.reflect.Method.invoke(Method.java:521)
01-12 13:37:31.679: E/AndroidRuntime(14297):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
01-12 13:37:31.679: E/AndroidRuntime(14297):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
01-12 13:37:31.679: E/AndroidRuntime(14297):    at dalvik.system.NativeStart.main(Native Method)
01-12 13:37:31.679: E/AndroidRuntime(14297): Caused by: java.lang.NullPointerException
01-12 13:37:31.679: E/AndroidRuntime(14297):    at com.example.fragmenttest.MainActivity.onCreate(MainActivity.java:45)
01-12 13:37:31.679: E/AndroidRuntime(14297):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
01-12 13:37:31.679: E/AndroidRuntime(14297):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
01-12 13:37:31.679: E/AndroidRuntime(14297):    ... 11 more
01-12 13:42:31.743: I/Process(14297): Sending signal. PID: 14297 SIG: 9

{编辑}

MyFragment.java

public class MyFragment extends Fragment {

    MyInterface interface1;
    Button btnChange;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        View myFragmentView = inflater.inflate(R.layout.fragmentlayout, container, false);
        btnChange=(Button) myFragmentView.findViewById(R.id.displayfragment1);
        return myFragmentView;
    }

    public void setOnClickListener(OnClickListener listener)
    {    
        btnChange.setOnClickListener(listener);

        Log.d("HI", "HI");
    }

    public void setInterface(MyInterface interface2) {
        this.interface1 = interface2;
    }



}

MyInterface.java

public interface MyInterface {
    public void buttonClicked();
}

MainActivity.java

public class MainActivity extends  FragmentActivity {

    //Fragment fragment;
    Fragment fragment;
    Button btnFragment1, btnFragment2, btnFragment3;

    FragmentManager fragmentManager=getSupportFragmentManager();
    FragmentTransaction fragmentTransaction;


    /** Called when the activity is first c1reated. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btnFragment1 = (Button)findViewById(R.id.displayfragment1);
        btnFragment2 = (Button)findViewById(R.id.displayfragment2);
        btnFragment3=(Button)findViewById(R.id.button1);
        fragmentTransaction=fragmentManager.beginTransaction();

        //add a fragment 
        MyFragment myFragment = new MyFragment();

        fragmentTransaction.add(R.id.myfragment, myFragment);
        fragmentTransaction.commit();

        //btnFragment1.setOnClickListener(btnFragmentOnClickListener);
        //btnFragment2.setOnClickListener(btnFragmentOnClickListener);
        myFragment.setOnClickListener(btnFragmentOnClickListener);
        //btnFragment3.setOnClickListener(btnFragmentOnClickListener);
    }

    /*

    public void ReplaceFragment(View V){

        MyFragment2 breakfast_fragment1=new MyFragment2();
        fragmentTransaction=fragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.myfragment, breakfast_fragment1, "Tag1");
        fragmentTransaction.commit();

    }
    */


    Button.OnClickListener btnFragmentOnClickListener
    = new Button.OnClickListener(){

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            Fragment newFragment;

            // Create new fragment
            if(v == btnFragment1){
                newFragment = new MyFragment();
            }

            else{
                newFragment = new MyFragment2();
            }

            FragmentTransaction transaction=fragmentManager.beginTransaction();


            transaction.replace(R.id.myfragment, newFragment);
            transaction.addToBackStack(null);

            // Commit the transaction
            transaction.commit();
        }};

/*
    @Override
    public void buttonClicked() {
        // TODO Auto-generated method stub

        Toast.makeText(this, "Hey", Toast.LENGTH_SHORT).show();
    }

    */

}

日志:

01-12 14:52:31.909: E/AndroidRuntime(14548): FATAL EXCEPTION: main
01-12 14:52:31.909: E/AndroidRuntime(14548): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.fragmenttest/com.example.fragmenttest.MainActivity}: java.lang.NullPointerException
01-12 14:52:31.909: E/AndroidRuntime(14548):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
01-12 14:52:31.909: E/AndroidRuntime(14548):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
01-12 14:52:31.909: E/AndroidRuntime(14548):    at android.app.ActivityThread.access$2300(ActivityThread.java:125)
01-12 14:52:31.909: E/AndroidRuntime(14548):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
01-12 14:52:31.909: E/AndroidRuntime(14548):    at android.os.Handler.dispatchMessage(Handler.java:99)
01-12 14:52:31.909: E/AndroidRuntime(14548):    at android.os.Looper.loop(Looper.java:123)
01-12 14:52:31.909: E/AndroidRuntime(14548):    at android.app.ActivityThread.main(ActivityThread.java:4627)
01-12 14:52:31.909: E/AndroidRuntime(14548):    at java.lang.reflect.Method.invokeNative(Native Method)
01-12 14:52:31.909: E/AndroidRuntime(14548):    at java.lang.reflect.Method.invoke(Method.java:521)
01-12 14:52:31.909: E/AndroidRuntime(14548):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
01-12 14:52:31.909: E/AndroidRuntime(14548):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
01-12 14:52:31.909: E/AndroidRuntime(14548):    at dalvik.system.NativeStart.main(Native Method)
01-12 14:52:31.909: E/AndroidRuntime(14548): Caused by: java.lang.NullPointerException
01-12 14:52:31.909: E/AndroidRuntime(14548):    at com.example.fragmenttest.MyFragment.setOnClickListener(MyFragment.java:31)
01-12 14:52:31.909: E/AndroidRuntime(14548):    at com.example.fragmenttest.MainActivity.onCreate(MainActivity.java:43)
01-12 14:52:31.909: E/AndroidRuntime(14548):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
01-12 14:52:31.909: E/AndroidRuntime(14548):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
01-12 14:52:31.909: E/AndroidRuntime(14548):    ... 11 more

1 个答案:

答案 0 :(得分:9)

您无法在活动中为片段中的按钮执行findViewById。

而是在片段内创建一个函数setOnClickListener,并调用它,例如:

public class MyFragment extends Fragment {

    MyInterface interface1;
    Button btnChange;

     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
       Bundle savedInstanceState) {
      // TODO Auto-generated method stub
      View myFragmentView = inflater.inflate(R.layout.fragmentlayout, container, false);
      btnChange=(Button)findViewById(R.id.displayfragment1);
      return myFragmentView;
     }


     public void setOnClickListener(OnClickListener listener){    
         btnChange.setOnClickListener(listener);
     }



}

活动中:

myFragment.setOnClickListener(btnFragmentOnClickListener);

此调用会将相同的单击侦听器设置为片段

内的按钮

修改

尝试使用您的界面。

上面代码的问题是在onCreateView之前调用了setOnClickListener。

执行以下操作:

  public class MyFragment extends Fragment {

    MyInterface interface1;
    Button btnChange;

     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
       Bundle savedInstanceState) {
      // TODO Auto-generated method stub
      View myFragmentView = inflater.inflate(R.layout.fragmentlayout, container, false);
      btnChange=(Button)findViewById(R.id.displayfragment1);
      btnChange.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            interface1.buttonClicked(v);
        }
    });
      return myFragmentView;
     }



  public void setInterface(MyInterface interface2) {
    this.interface1 = interface2;
   }


}

接口:

 public interface MyInterface {
    public void buttonClicked(View v);
}

活动onCreate:

    MyFragment myFragment = new MyFragment();

    fragmentTransaction.add(R.id.myfragment, myFragment);
    fragmentTransaction.commit();
    myFragment.setInterface(this);

使用MyInterface实现您的活动:

public class MainActivity extends  FragmentActivity implements MyInterface

在Activity中创建一个函数:

    @Override
    public void buttonClicked(View v) {
        // TODO Auto-generated method stub
        Fragment newFragment;

        // Create new fragment
        if(v.getId()==R.id.displayfragment1){
            newFragment = new MyFragment();
        }

        else{
            newFragment = new MyFragment2();
        }

        FragmentTransaction transaction=fragmentManager.beginTransaction();


        transaction.replace(R.id.myfragment, newFragment);
        transaction.addToBackStack(null);

        // Commit the transaction
        transaction.commit();
    }};

编辑2

你没有问题btnFragment1和btnFragment2为R.id.displayfragment1而'R.id.displayfragment2'在main.xml中

问题在于

btnFragment3.setOnClickListener(btnFragmentOnClickListener);

因为R.id.button1不在main.xml中,所以它必须处于片段布局中,所以只做以上所有内容并保持onlick侦听器与前面的前2个按钮相同,第三个更改代码{{ 1}}。

buttonClicked