【问题标题】:Android: handle user input from within a FragmentAndroid:处理来自片段内的用户输入
【发布时间】:2014-01-25 22:36:59
【问题描述】:

我的测试项目有一个主要活动如下:

public class MainActivity extends Activity {

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.display_message, menu);
        return true;
    }

    public void sendMessage(View view){
        FragmentManager frManager = getFragmentManager();
        FragmentTransaction transaction = frManager.beginTransaction();
        Frag fr= new Frag();
        transaction.add(R.id.stuuf, fr);
        transaction.addToBackStack(null);
        transaction.commit();
    }
}

以及以下主要布局:

<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/stuuf"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:paddingTop="?android:attr/actionBarSize" >

    <Button android:id="@+id/submit_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/button_send"
        android:onClick="sendMessage"/>

    </TableLayout>

当用户单击按钮时,会显示以下片段,其中包含第二个按钮:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".Frag" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="180dp"
        android:onClick="buttonClicked"
        android:text="Button" />
    </RelativeLayout>

以及应该控制它的类:

public class Frag extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        return inflater.inflate(R.layout.frag_test, null);
    }

    public void buttonClicked(){
        System.out.println("Hello!");
    }

}

现在,当我单击第二个按钮时,系统会在 MainActivity 中而不是在 Frag 中查找 buttonClicked() 方法,从而给我以下错误:

java.lang.IllegalStateExcetion: Could not find method buttonClicked(View) in the activity class com.spacitron.mytestproject.MainActivity for onClick handler on view class android.widget.Button with id 'button1'

显然我应该能够从片段类本身处理片段中发生的事情,所以我一定是在做完全错误的事情,我只是无法确定是什么。

【问题讨论】:

    标签: java android android-fragments


    【解决方案1】:

    问题是您在片段布局中使用onClick 方法,而Android 期望在活动中找到该方法。有两种方法可以解决这个问题:

    1. 最健康的方法:从 XML 中删除 onClick 属性并依赖 OnClickListener 实现。
    2. 将活动的调用委托给片段 - 在活动中声明方法并将其委托给片段。如下所示:

    在activity类中有这个:

    public void buttonClicked(View view){
        Fragment current = getFragmentManager().findFragmentById(R.id.stuuf);
        if(current != null) {
            ((Frag)current).buttonClicked();
        }
    }
    

    从长远来看,我强烈建议不要使用onClick XML 属性。原因在this SO answer中解释。

    【讨论】:

      【解决方案2】:

      您似乎缺少一些步骤,请将其放在您的第二个片段中(并从 xml 中删除 onClick)

      public void onViewCreated(View view, ...) {
      
          View btn = view.findViewById(R.id.button1);
          btn.setOnClickListener(new View.OnClickLisener() {
      
              public void onClick(View view) {
                  Log.d("My App", "The button was clicked");
              }
      
          }
      
      }
      

      【讨论】:

        【解决方案3】:

        Fragment 建立在 Activity 之上,onClick 属性与 Activity 相连。

        我建议您对两个按钮都使用 ClickListeners :-

        @Override
        public void onViewCreated((View view, Bundle savedInstanceState) {
        Button fragmentButton = (Button)view.findViewById(R.id.button1);
        fragmentButton.setOnClickListener(new View.OnClickLisener() {
        
            public void onClick(View view) {
                //Do Something here
            }
        
        });
        
        }
        

        【讨论】:

          猜你喜欢
          • 2014-09-01
          • 2015-06-03
          • 1970-01-01
          • 1970-01-01
          • 2012-03-05
          • 2019-07-27
          • 1970-01-01
          • 2021-11-27
          • 1970-01-01
          相关资源
          最近更新 更多