【问题标题】:How do I get my buttons to work in the fragment?如何让我的按钮在片段中工作?
【发布时间】:2013-04-29 01:04:24
【问题描述】:

我仍然无法在屏幕上添加一个按钮并让它执行我的代码。现在,我会很高兴选择按钮并获得“log,d (msg);”去工作。问题可能是由于我在片段中的所有代码和/或按钮组合以及我在同一屏幕上滚动的列表。这可能是一个非常基本的问题。

我的应用程序首先从一个由 SQLite 表中的游标创建的滚动列表开始。所以这是一个开放式列表。选择一个项目,我会看到一个允许添加、更新或删除的详细信息屏幕。一切正常。

现在我在列表上方添加 3 个按钮。

我是一个新手,我开始的书说要创建一个片段,所以带有列表的屏幕就是这样编码的。 (详细屏幕被重写为仅活动。)

我尝试了很多方法,但大致有以下三种方法:

在我的 onCreate 方法中:

"btn_Add.setOnClickListener(new View.OnClickListener()"

正如最近的回复中所建议的那样 - 这将执行片段 onCreate ,然后因以下消息而崩溃:

java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.dummies.android.taskreminder/com.dummies.android.
taskreminder. EventListActivity}:Binary XML file line #34: Error inflating class fragment

作为 onCreate 之后的单独方法:

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

这会导致循环 - 多次重复 onCreate 然后崩溃:

java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.dummies.android.taskreminder/com.dummies.android.
taskreminder.EventListActivity}: android.view.InflateException: 
Binary XML file line #8: Error inflating class <unknown>

3 我在按钮定义的 XML 文件中添加了这个:

android:onClick="MyButton"

public void MyButton(View v)
    {
     Log.d(". . . " + v);
    }

这允许应用程序加载,但是当我选择按钮时,当我选择带有以下消息的按钮时它崩溃了:

java.lang.IllegalStateException: Could not find a method MyButton(View) in the activity

这是片段中的片段:eventListFragment.java

public class EventListFragment extends ListFragment
                                  implements LoaderCallbacks<Cursor>
  {
   . . . .
    List strRecord = new ArrayList(3);

    @Override
    public void onCreate(Bundle savedInstanceState)
       {
        super.onCreate(savedInstanceState);
        . . . .
        setListAdapter(mAdapter);
        getLoaderManager().initLoader(0, null, this);
       )
//------------------------------------
// THIS IS EXAMPLE # 1
//     java.lang.RuntimeException: Unable to start activity
//     ComponentInfo{com.dummies.android.taskreminder/com.dummies.android.taskreminder.EventListActivity}:
//     android.view.InflateException: Binary XML file line #34: Error inflating class fragment

    btn_Add.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
        // you may want to perform your clicks here.
        Log.d("EventLst","S create view btnAddEvent:" + v);
        }
    });   
//-------------------------------------


  }   //----> END: public void onCreate  

//-------------------------------------
//     THIS IS EXAMPLE #2:
//  it give me this error on initial load:
//  java.lang.RuntimeException: Unable to start activity
//  ComponentInfo{com.dummies.android.taskreminder/com.dummies.android.taskreminder.EventListActivity}:
//  android.view.InflateException: Binary XML file line #8: Error inflating class <unknown>

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
       {
        View view = inflater.inflate(R.layout.event_list, container, false);
        Button button = (Button) view.findViewById(R.id.btn_Add);
        button.setOnClickListener(new OnClickListener()
           {
            @Override
            public void onClick(View v)
               {
                Activity activity = getActivity();
                if (activity != null)
                   {
                    Log.d("EventLst","S create view btnAddEvent:" + v);
                    Toast.makeText(activity, "GOT button", Toast.LENGTH_LONG).show();
                   }
               }
             }   );
        return view;
       }
//---------------------------------------


    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor)
       {
        . . . 
         while  (cursor.isAfterLast() == false)
            {
             strRecord.add(iRecNo, strDate + ": "  + strC[2]);
            }
         lstAdapter = new ArrayAdapter<String>(getActivity(),
                  R.layout.event_row, R.id.text1, strRecord);
          setListAdapter(lstAdapter);

这是主要布局:event_list.XML 注意: android:onClick="MyButton" 仅在上述尝试#3 中

<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:name="com.dummies.android.taskreminder.EventListFragment" >

 <Button  android:id="@+id/btn_Add"
    android:onClick="MyButton"
    android:layout_width="50dp"
    android:layout_height="30dp"   
    android:textSize="12dp"
    android:padding="1dip"
    android:text="@string/add" />

  <Button  android:id="@+id/btn_Exit"
    android:onClick="onClick"
    android:layout_width="50dp"
    android:layout_height="30dp"
    android:textSize="12dp"
    android:padding="1dip"
    android:layout_marginLeft="5dp"
    android:layout_toRightOf="@+id/btn_Add" 
    android:text="@string/exit" />

  <Button  android:id="@+id/btn_Other"
    android:layout_width="50dp"
    android:layout_height="30dp"
    android:textSize="12dp"
    android:padding="1dip"
    android:layout_marginLeft="5dp"
    android:layout_toRightOf="@+id/btn_Exit" 
    android:text="@string/other" />

 <fragment
    android:name="com.dummies.android.taskreminder.EventListFragment"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/btn_Add"  />
 </RelativeLayout>   

这是创建 scrow 列表的行:event_row.XML

  <TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/text1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" 
    android:textSize="12dp"
    android:padding="2dip" />

Luksprog 在回复中要求提供此信息,请张贴或至少提供给他/她。

首先我创建了这个 XML 文件 event_list_activity.xml,对文件名进行了一些猜测:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container" 
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>

也添加到字符串中:

<string name="container">EventContainer</string>

运行我的测试,这是完整的日志:(我的代码中的前三个记录):

04-28 16:09:24.504: D/EventLst(258): X onCrt: x01strI:eventname
04-28 16:09:24.544: D/EventLst(258): X onCrt: x02 START
04-28 16:09:24.584: D/EventLst(258): X onCrt: x03 START
04-28 16:09:24.624: D/AndroidRuntime(258): Shutting down VM
04-28 16:09:24.646: W/dalvikvm(258): threadid=3: thread exiting with uncaught exception (group=0x4001b1d8)
04-28 16:09:24.646: E/AndroidRuntime(258): Uncaught handler: thread main exiting due to uncaught exception
04-28 16:09:24.646: W/dalvikvm(258): threadid=3: thread exiting with uncaught exception (group=0x4001b1d8)
04-28 16:09:24.646: E/AndroidRuntime(258): Uncaught handler: thread main exiting due to uncaught exception
04-28 16:09:25.065: E/AndroidRuntime(258): java.lang.RuntimeException: Unable to start activity
         ComponentInfo{com.dummies.android.taskreminder/com.dummies.android.taskreminder.EventListActivity}:
         android.view.InflateException: Binary XML file line #33: Error inflating class fragment
04-28 16:09:25.065: E/AndroidRuntime(258):  at
         android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496)
04-28 16:09:25.065: E/AndroidRuntime(258):  at
         android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
04-28 16:09:25.065: E/AndroidRuntime(258):  at android.app.ActivityThread.access$2200(ActivityThread.java:119)
04-28 16:09:25.065: E/AndroidRuntime(258):  at
         android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
04-28 16:09:25.065: E/AndroidRuntime(258):  at android.os.Handler.dispatchMessage(Handler.java:99)
04-28 16:09:25.065: E/AndroidRuntime(258):  at android.os.Looper.loop(Looper.java:123)
04-28 16:09:25.065: E/AndroidRuntime(258):  at android.app.ActivityThread.main(ActivityThread.java:4363)
04-28 16:09:25.065: E/AndroidRuntime(258):  at java.lang.reflect.Method.invokeNative(Native Method)
04-28 16:09:25.065: E/AndroidRuntime(258):  at java.lang.reflect.Method.invoke(Method.java:521)
04-28 16:09:25.065: E/AndroidRuntime(258):  at
         com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
04-28 16:09:25.065: E/AndroidRuntime(258):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
04-28 16:09:25.065: E/AndroidRuntime(258):  at dalvik.system.NativeStart.main(Native Method)
04-28 16:09:25.065: E/AndroidRuntime(258): Caused by: android.view.InflateException: Binary XML file line #33:
         Error inflating class fragment
04-28 16:09:25.065: E/AndroidRuntime(258):  at
         android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:582)
04-28 16:09:25.065: E/AndroidRuntime(258):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:618)
04-28 16:09:25.065: E/AndroidRuntime(258):  at android.view.LayoutInflater.inflate(LayoutInflater.java:407)
04-28 16:09:25.065: E/AndroidRuntime(258):  at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
04-28 16:09:25.065: E/AndroidRuntime(258):  at android.view.LayoutInflater.inflate(LayoutInflater.java:276)
04-28 16:09:25.065: E/AndroidRuntime(258):  at
         com.android.internal.policy.impl.WimmWindow.setContentView(WimmWindow.java:181)
04-28 16:09:25.065: E/AndroidRuntime(258):  at android.app.Activity.setContentView(Activity.java:1622)
04-28 16:09:25.065: E/AndroidRuntime(258):  at
         com.dummies.android.taskreminder.EventListActivity.onCreate(EventListActivity.java:22)
04-28 16:09:25.065: E/AndroidRuntime(258):  at
         android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
04-28 16:09:25.065: E/AndroidRuntime(258):  at
         android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
04-28 16:09:25.065: E/AndroidRuntime(258):  ... 11 more
04-28 16:09:25.065: E/AndroidRuntime(258): Caused by: java.lang.NullPointerException
04-28 16:09:25.065: E/AndroidRuntime(258):  at
         com.dummies.android.taskreminder.EventListFragment.onCreate(EventListFragment.java:98)
04-28 16:09:25.065: E/AndroidRuntime(258):  at
         android.support.v4.app.Fragment.performCreate(Fragment.java:1437)
04-28 16:09:25.065: E/AndroidRuntime(258):  at
         android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:877)
04-28 16:09:25.065: E/AndroidRuntime(258):  at
         android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1066)
04-28 16:09:25.065: E/AndroidRuntime(258):  at
         android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1168)
04-28 16:09:25.065: E/AndroidRuntime(258):  at
         android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:280)
04-28 16:09:25.065: E/AndroidRuntime(258):  at
         android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:558)

接下来我在下面添加了您的语句,并得到以下错误是从片段开始到创建结束注意:我还必须添加:import android.support.v4.app.FragmentTransaction;

package com.dummies.android.taskreminder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;  
import java.util.Date;
import java.util.List;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.view.LayoutInflater;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.content.DialogInterface;
import android.os.Bundle; 
import android.support.v4.app.FragmentTransaction;
//* below insures that you are using the ...v4 for version android 1.6
import android.support.v4.app.ListFragment; 
import android.support.v4.app.LoaderManager.LoaderCallbacks; 
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.SimpleCursorAdapter;
import android.view.MenuItem;
import android.content.ContentValues;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Button;
import android.widget.Toast;
import android.util.Log;

public class EventListFragment extends ListFragment
                                  implements 
                                  LoaderCallbacks<Cursor>
  {
    private SimpleCursorAdapter mAdapter;
    List strRecId = new ArrayList();

    private ListAdapter lstAdapter;
    private Button btn_Add;
    private Button myButton;

    List strRecord = new ArrayList(3);
    List strFields = new ArrayList();

    @Override
    public void onCreate(Bundle savedInstanceState)
       {
        super.onCreate(savedInstanceState);

//---------------------------------------------------------------        
     // assuming you use FragmentActivity
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.add(R.id.container, new EvetListFragment());
        ft.commit();        

// errors above:   
// For: getSupportFragmentManager()
//  "The method getSupportFragmentManager() is undefined for the type EventListFragment" 
// For: EvetListFragment());
//   "EvetListFragment cannot be resolved to a type"
//----------------------------------------------------------------

//  BELOW READS FROM DATABASE AND DISPLAYS EVENTNAME
//  THEN ALLOWS UPDATE OF THEM ABD INSERT FROM EXISTING        
//        Log.d("EventLst","X onCrt: x01 START" ); 

        String[]  strItems =  new String[]  
           { 
            EventProvider.COLUMN_EVENTNAME
           };
        Log.d("EventLst","X onCrt: x01strI:" + strItems[0]);          
        int[] iCnt = new int[]
            {  
             R.id.text1
            };

        mAdapter =  new SimpleCursorAdapter(getActivity(),R.layout.event_row,
                    null, strItems, iCnt,  0);
        Log.d("EventLst","X onCrt: x02 START" );

        setListAdapter(mAdapter);
        getLoaderManager().initLoader(0, null, this);

        Log.d("EventLst","X onCrt: x03 START" );
//---------------------------------------------------------------------------------
// I thought this set my OnClickListener.  Without this code, the application runs 
//   but the buttons don't do anything  
        btn_Add.setOnClickListener(new OnClickListener()
         {
      @Override
          public void onClick(View v)
             {
              Log.d("EventLst","S onclkBtn2" + v);
             }
         }  );
//-------------------------------------------------------------------------------

      }   //----> END: public void onCreate    

非常感谢您的帮助。

【问题讨论】:

    标签: android button android-fragments


    【解决方案1】:

    你的代码有很多问题:

    请发布完整的堆栈跟踪,InflateException 告诉您片段无法膨胀的原因。最可能的原因是您扩展了ListFragment 并覆盖了onCreateView() 以扩充您自己的布局,该布局不包含ID 为android.R.id.listListView(xml 文件中的@android:id/list)。即使没有抛出该异常,您的代码仍然会失败,因为您会陷入 stackoverflow 错误,您的片段布局是一个包含相同片段的布局文件(将再次加载等等......)。

    删除:

    android:name="com.dummies.android.taskreminder.EventListFragment"
    

    从布局。布局应该是这样的:

    <RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    >
    
     <Button  android:id="@+id/btn_Add"    
        android:layout_width="50dp" <!-- you should avoid fixed sizes -->
        android:layout_height="30dp"   
        android:textSize="12sp" <!-- use sp units for text size! -->
        android:padding="1dip"
        android:text="@string/add" />
    
      <Button  android:id="@+id/btn_Exit"
        android:layout_width="50dp"
        android:layout_height="30dp"
        android:textSize="12sp"
        android:padding="1dip"
        android:layout_marginLeft="5dp"
        android:layout_toRightOf="@id/btn_Add" 
        android:text="@string/exit" />
    
      <Button  android:id="@+id/btn_Other"
        android:layout_width="50dp"
        android:layout_height="30dp"
        android:textSize="12sp"
        android:padding="1dip"
        android:layout_marginLeft="5dp"
        android:layout_toRightOf="@id/btn_Exit" 
        android:text="@string/other" />
    
     <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/btn_Add"  />
     </RelativeLayout>   
    

    这将是片段的布局。 Activity 的布局为:

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

    添加片段(在onCreate()方法中):

    // assuming you use FragmentActivity
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.add(R.id.container, new EvetListFragment());
    ft.commit();
    

    然后您可以使用R.id.container 替换EventListFragment

    在您的EventListFragment 中,在您的按钮上设置OnClickListener,并在onActivityCreated() 回调中设置您的适配器。 onClick 属性将在 Activity 级别查找该方法,因此只需手动设置 OnClickListener

    【讨论】:

    • 欣赏答案。我会发布更多,但我去了谷歌网站,说去属性/java编译器并从1.6更改合规性。结果:“Android 要求编译器合规级别为 5.0 或 6.0。找到的是 '1.7'。......” W/ 属性变灰,无法返回,没有任何运行......幸运的是最近有备份,并且不会花很长时间才能回到我原来的位置。但是,您可能已经提供了帮助。我没有 activity.xml 只有 event_row 和 event_List 。由于列表,从列表中选择有效,只是按钮失败,我以为我有我需要的东西。所以我也会试试。
    • PS:我是 android 的新手, - 我的第一个应用程序,所以我的代码很糟糕也就不足为奇了。我注意到夏洛特的显示器,也许我可以买一个辅导课。它适用于我的 WIMMOne 手表,因此方向改变、位置固定和一个应用程序覆盖整个小屏幕。这就是为什么我有特定的职位。再次感谢,如果您还没有解决它,将实现您所拥有的并发布更多日志。克拉克
    • 我昨晚发布了你要求的日志和其他结果,显然他们没有把它放在网站上。由于日志不仅仅是评论中的内容,我编辑并将新信息发布到最后。感谢您的回复,并希望他们尽快提供。谢谢,克拉克
    • @ClarkG 如果您想添加额外的详细信息,请编辑您的问题并添加它们。你不明白片段是如何工作的。在Activity 中,您只需添加EventListFragment(我发布的代码)。在EventListFragment(因为这些视图在片段布局中而不是在活动中),在onCreateView()onActivityCreated() 回调中搜索视图并设置监听器。
    • 首先非常感谢您的帮助和耐心等待! - 我确实编辑了我的问题以添加更多信息,它说“只有在同行审查之前我才能看到”。显然那个审稿人不喜欢它,所以我又试了一次,并要求至少让你看到它。如果您需要更多,请告诉我,我认为没有什么是专有的,所以发布或共享整个项目没有问题。
    猜你喜欢
    • 2014-11-07
    • 1970-01-01
    • 2015-06-14
    • 2017-05-05
    • 1970-01-01
    • 2021-02-25
    • 2014-06-12
    • 2020-06-14
    • 1970-01-01
    相关资源
    最近更新 更多