38

我是 Android 新手,正在尝试自学。但是我在使用 Fragments 时遇到了困难。我正在创建一个简单的应用程序来学习片段。我认为这可能看起来很愚蠢,但我真的无法让它发挥作用。

我想要做的就是点击 Fragment_One 中的一个按钮(buttonSayHi),Fragment_One 应该被 Fragment_Two 替换。

我不确定何时调用片段代码以及我应该在哪里编写代码来调用第二个片段。我收到错误:无法启动 Activity 组件。

但是,如果我放弃按钮的侦听器并且片段显示在活动中,则代码可以正常工作。

我进行了大量研究,阅读了 developer.android.com 上的片段教程以及 Lars Vogella 的教程。我认为我的概念不清楚。

任何帮助将不胜感激。

以下是代码:

activity_main.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/frameLayoutFragmentContainer"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

</FrameLayout>

fragment_one.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" >

    <EditText
        android:id="@+id/editTextPersonName"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textPersonName" >

        <requestFocus />
    </EditText>

    <Button
        android:id="@+id/buttonSayHi"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Say Hi" 
        android:onClick="onButtonClicked"/>

</LinearLayout>

fragment_two.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" >

    <TextView
        android:id="@+id/textViewResult"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="I will say Hi!" />

</LinearLayout>

MainActivity.java

package com.example.fragmenttutorial;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;

public class MainActivity extends Activity{

    View view;
    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);     

        Fragment fragmentOne = new FragmentOne();

        fragmentTransaction.add(R.id.frameLayoutFragmentContainer, fragmentOne);
        fragmentTransaction.addToBackStack(null);

        fragmentTransaction.commit();
    }

    protected void onButtonClicked()
    {
        if(view.getId() == R.id.buttonSayHi){
            Fragment fragmentTwo = new FragmentTwo();

            fragmentTransaction.replace(R.id.frameLayoutFragmentContainer, fragmentTwo);
            fragmentTransaction.addToBackStack(null);

            fragmentTransaction.commit();   

        }

    }
}

FragmentOne.java

package com.example.fragmenttutorial;

import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class FragmentOne extends Fragment{

    View view;
    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_one, container, false);
        return view;
    }

//  protected void onButtonClicked()
//  {
//      if(view.getId() == R.id.buttonSayHi){
//          Fragment fragmentTwo = new FragmentTwo();
//
//          fragmentTransaction.replace(R.id.frameLayoutFragmentContainer, fragmentTwo);
//          fragmentTransaction.addToBackStack(null);
//
//          fragmentTransaction.commit();   
//
//      }
//
//  }
}

我已经注释掉了片段中的点击代码。我也尝试在片段中实现 onClickListener。

片段二.java

package com.example.fragmenttutorial;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class FragmentTwo extends Fragment{

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_two, container, false);
        return view;    
    }
}

编辑:我已经从我的 XML 代码中删除了 android:onClick="onButtonClicked" 行。并编辑了以下文件,但它仍然不起作用。你们能给我提供一个没有 android:onClick="onButtonClicked" 行的工作示例吗?

MainActivity.java

package com.example.fragmenttutorial;

import android.os.Bundle;
import android.view.View;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;

public class MainActivity extends Activity{

    View view;
    Fragment fragmentOne;
    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);     

        fragmentOne = new FragmentOne();

        fragmentTransaction.add(R.id.frameLayoutFragmentContainer, fragmentOne);
        fragmentTransaction.addToBackStack(null);

        fragmentTransaction.commit();       
    }
}

FragmentOne.java

package com.example.fragmenttutorial;

import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;

public class FragmentOne extends Fragment implements OnClickListener{

    View view;
    Fragment fragmentTwo;
    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_one, container, false);
        Button buttonSayHi = (Button) view.findViewById(R.id.buttonSayHi);
        buttonSayHi.setOnClickListener(this);
        return view;
    }

    @Override
    public void onClick(View v) {

        fragmentTwo = new FragmentTwo();

        fragmentTransaction.replace(R.id.frameLayoutFragmentContainer, fragmentTwo);
        fragmentTransaction.addToBackStack(null);

        fragmentTransaction.commit();   

    }
}

感谢您提出宝贵的建议。

4

9 回答 9

68

您的片段类应该实现 OnClickListener

public class SmartTvControllerFragment extends Fragment implements View.OnClickListener

然后获取视图、链接按钮并设置 onClickListener,如下例所示

 View view;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    view = inflater.inflate(R.layout.smart_tv_controller_fragment, container, false);
    upButton = (Button) view.findViewById(R.id.smart_tv_controller_framgment_up_button);
    upButton.setOnClickListener(this);
    return view;
 }

然后添加 onClickListener 方法并做你想做的事。

@Override
public void onClick(View v) {
 //do what you want to do when button is clicked
    switch (v.getId()) {
        case R.id.textView_help:
            switchFragment(HelpFragment.TAG);
            break;
        case R.id.textView_settings:
            switchFragment(SettingsFragment.TAG);
            break;
    }
}

这是我的代码示例,但我希望你能理解

于 2013-09-10T05:56:26.293 回答
9

使用您的代码

public class FragmentOne extends Fragment implements OnClickListener{

    View view;
    Fragment fragmentTwo;
    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_one, container, false);
        Button buttonSayHi = (Button) view.findViewById(R.id.buttonSayHi);
        buttonSayHi.setOnClickListener(this);
        return view;
    }

但我认为以这种方式处理按钮更好:

@Override
    public void onClick(View v) {
        switch(v.getId()){
            case R.id.buttonSayHi:
            /** Do things you need to..
               fragmentTwo = new FragmentTwo();

               fragmentTransaction.replace(R.id.frameLayoutFragmentContainer, fragmentTwo);
               fragmentTransaction.addToBackStack(null);

               fragmentTransaction.commit();  
            */
            break;
        }   
    }
于 2013-12-09T01:20:42.477 回答
4

片段监听器

如果 afragment需要与 通信events,则应将 a 定义activity为内部类型并要求必须this :fragmentinterfaceactivityimplementinterface

import android.support.v4.app.Fragment;

public class MyListFragment extends Fragment {
  // ...
  // Define the listener of the interface type
  // listener is the activity itself
  private OnItemSelectedListener listener;

  // Define the events that the fragment will use to communicate
  public interface OnItemSelectedListener {
    public void onRssItemSelected(String link);
  }

  // Store the listener (activity) that will have events fired once the fragment is attached
  @Override
  public void onAttach(Activity activity) {
    super.onAttach(activity);
      if (activity instanceof OnItemSelectedListener) {
        listener = (OnItemSelectedListener) activity;
      } else {
        throw new ClassCastException(activity.toString()
            + " must implement MyListFragment.OnItemSelectedListener");
      }
  }

  // Now we can fire the event when the user selects something in the fragment
  public void onSomeClick(View v) {
     listener.onRssItemSelected("some link");
  }
}

然后在activity

import android.support.v4.app.FragmentActivity;

public class RssfeedActivity extends FragmentActivity implements
  MyListFragment.OnItemSelectedListener {
    DetailFragment fragment;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_rssfeed);
      fragment = (DetailFragment) getSupportFragmentManager()
            .findFragmentById(R.id.detailFragment);
  }

  // Now we can define the action to take in the activity when the fragment event fires
  @Override
  public void onRssItemSelected(String link) {
      if (fragment != null && fragment.isInLayout()) {
          fragment.setText(link);
      }
  }
}
于 2015-07-23T13:13:55.807 回答
4

您只需要获取携带此片段的活动的视图,并且只有在您的片段已经创建时才会发生这种情况

覆盖onViewCreated()片段中的方法并享受它的魔力:) ..

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    Button button = (Button) view.findViewById(R.id.YOURBUTTONID);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
         //place your action here
         }
    });

希望这可以帮助你;

于 2016-12-28T08:27:43.070 回答
0

当您在 XML 中声明 onclick 时,您必须声明方法并将 View v 作为参数传递并公开该方法...

Ex:
//in xml
android:onClick="onButtonClicked"


// in java file
public void onButtonClicked(View v)
{
//your code here
}
于 2013-11-14T09:26:45.923 回答
0

这对我有用。

private OnClickListener mDisconnectListener;
mDisconnectListener = new OnClickListener() {

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

        }
    };

...

... onCreateView(...){

mButtonDisconnect = (Button) rootView.findViewById(R.id.button_disconnect);
mButtonDisconnect.setOnClickListener(mDisconnectListener);
...
}
于 2015-03-27T01:02:31.070 回答
0
    //sure run it i will also test it
//we make a class that extends with the fragment
    public class Example_3_1 extends Fragment  implements OnClickListener
    {
       View vi;
        EditText t;
        EditText t1;
        Button bu;
 // that are by defult function of fragment extend class
     @Override
       public View onCreateView(LayoutInflater inflater,ViewGroup container,BundlesavedInstanceState) 
       {        
           vi=inflater.inflate(R.layout.example_3_1, container, false);// load the xml file 
           bu=(Button) vi.findViewById(R.id.button1);// get button id from example_3_1 xml file
           bu.setOnClickListener(this); //on button appay click listner
           t=(EditText) vi.findViewById(R.id.editText1);// id get from example_3_1 xml file
           t1=(EditText) vi.findViewById(R.id.editText2);
          return vi; // return the view object,that set the xml file  example_3_1 xml file
       }
       @Override
       public void onClick(View v)//on button click that called
       {

          switch(v.getId())// on run time get id what button os click and get id
          {
          case R.id.button1:        // it mean if button1 click then this work
           t.setText("UMTien");     //set text 
           t1.setText("programming");
           break;
          }
    }     }
于 2014-12-26T00:05:52.110 回答
0

尝试这个 :

FragmentOne.java

import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

public class FragmentOne extends Fragment{

    View rootView;        

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

        rootView = inflater.inflate(R.layout.fragment_one, container, false);


        Button button = (Button) rootView.findViewById(R.id.buttonSayHi);
        button.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                onButtonClicked(v);
            }
        });
        return rootView;
    }

  public void onButtonClicked(View view)
  {
          //do your stuff here..           
    final FragmentTransaction ft = getFragmentManager().beginTransaction(); 
    ft.replace(R.id.frameLayoutFragmentContainer, new FragmentTwo(), "NewFragmentTag"); 
    ft.commit(); 

    ft.addToBackStack(null);    
  }
}

检查这个:点击这里

于 2015-03-31T09:55:00.537 回答
0

只需将视图对象传递给 onButtonClicked 函数。getView() 在片段中似乎没有按预期工作。为您的 FragmentOne 片段尝试此代码

PS。您已经在原始 FragmentOne 代码中重新定义了对象视图。

package com.example.fragmenttutorial;

import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class FragmentOne extends Fragment{

    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_one, container, false);
        onButtonClicked(view);
        return view;
    }

  protected void onButtonClicked(View view)
  {
      if(view.getId() == R.id.buttonSayHi){
          Fragment fragmentTwo = new FragmentTwo();

          fragmentTransaction.replace(R.id.frameLayoutFragmentContainer, fragmentTwo);
          fragmentTransaction.addToBackStack(null);

          fragmentTransaction.commit();   

     }
于 2017-01-27T17:14:25.537 回答