【问题标题】:Android imagebutton in custom listview is null自定义列表视图中的 Android imagebutton 为空
【发布时间】:2025-12-16 05:00:02
【问题描述】:

我正在开发一个显示列表视图的 android 应用程序。当我单击列表视图的某些项目时,它应该打开一个对话框,其中包括另一个(自定义)列表视图。对话框中的列表视图有两个文本视图和一个(图像)按钮(我都试过了)。但我总是得到一个 nullpointerException 我不知道,我做错了什么。

这是我的代码

    public class Schuldet_mir extends Fragment {

    private ListView mainList;
    private ListView subList;
    .....

    MainActivity mainActivity = (MainActivity) getActivity();
    .....


    public Schuldet_mir(int position) {                                                                         
    }

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

        View v = inflater.inflate(R.layout.fragment_schuldet_mir, container, false);

        mainList        = (ListView)v.findViewById(R.id.listView1);
        imageButton     = (ImageButton)v.findViewById(R.id.imageBtn1);


        imageButton.setOnClickListener(new OnClickListener() {                                      
            @Override
            public void onClick(View v) {

                openDialog();
            }
        });

        mainList.setOnItemClickListener(new OnItemClickListener() {                                             //Hauptliste klick

            @Override
            public void onItemClick(AdapterView<?> parent, View v, int position, long idInDB) {

                mainListViewClick(parent, v, position, idInDB);
            }           
        });

        return v;
    }

    @Override                                                                                                   //onResume
    public void onResume() {
        super.onResume();

        populateListViewFromDB();   
    }


    private void openDialog() {                                                                                 

        final Dialog dialog1 = new Dialog(getActivity());                   
        dialog1.setContentView(R.layout.dialog1);
        dialog1.setTitle("Schuldner hinzufügen");
        dialog1.setCancelable(false);

        eintrag_name   = (EditText)dialog1.findViewById(R.id.editText_name);
        eintrag_betrag = (EditText)dialog1.findViewById(R.id.editText_betrag);
        eintrag_grund  = (EditText)dialog1.findViewById(R.id.editText1);

        ImageButton hinzufügen = (ImageButton)dialog1.findViewById(R.id.imageButton_add);
        ImageButton abbrechen = (ImageButton)dialog1.findViewById(R.id.imageButton_cancel);

        hinzufügen.setOnClickListener(new OnClickListener() {                                                   //Buttonklick Hinzufügen 

            @Override
            public void onClick(View v) {
                                                                //do s.th.

                }
            }
        });


        abbrechen.setOnClickListener(new OnClickListener() {                                                    

            @Override
            public void onClick(View v) {
                dialog1.dismiss();                      
            }
        });

        dialog1.show();                 
    }


    private void mainListViewClick(AdapterView<?> parent, View v, int position, long idInDB) {                  

        final Dialog dialog3 = new Dialog(getActivity());                                                       
        dialog3.setContentView(R.layout.dialog3);
        dialog3.setTitle("Schuldner");
        dialog3.setCancelable(false);

        subList                 = (ListView)dialog3.findViewById(R.id.dialog3_listView);
        Button deleteBtn        = (Button)dialog3.findViewById(R.id.dialog3_deleteBtn);
        Button allesErhalten    = (Button)dialog3.findViewById(R.id.dialog3_btn1);
        Button zurück           = (Button)dialog3.findViewById(R.id.dialog3_btn2);

        populateSubListViewFromDB(idInDB);

        subList.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View v, int position, long idInDB) {

                subListViewClick(parent, v, position, idInDB);              
            }
        });

        deleteBtn.setOnClickListener(new OnClickListener() {  **// line:193**                                                       /

            @Override
            public void onClick(View v) {
                Log.e("++++++++", "TEST OK");                       
            }
        });

        allesErhalten.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

            }
        });

        zurück.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog3.dismiss();
            }
        });

        dialog3.show(); 
    }

//  --------------------------------------------------------------------
    private void subListViewClick(AdapterView<?> parent, View v, int position, long idInDB) {                   // SubList Item Click

        cursor = mainActivity.myDBHandler.getRowinTable1(idInDB);       

        if(cursor.moveToFirst()) {                                                                              //informationen der zeile
            idDB = cursor.getLong(DataBaseHandler.COL_ROWID);
            dialog2_name = cursor.getString(DataBaseHandler.COL_NAME);
            dialog2_betrag = cursor.getFloat(DataBaseHandler.COL_BETRAG);
            dialog2_grund = cursor.getString(DataBaseHandler.COL_GRUND);
            dialog2_datum = cursor.getString(DataBaseHandler.COL_DATUM);            
        }

        final Dialog dialog2 = new Dialog(getActivity());                                                       //open dialog
        dialog2.setContentView(R.layout.dialog2);
        dialog2.setTitle("Schuldner");
        dialog2.setCancelable(false);

        TextView dial2_TxtDatum  = (TextView)dialog2.findViewById(R.id.dialog2_TxtDatum);
        TextView dial2_TxtName   = (TextView)dialog2.findViewById(R.id.dialog2_TxtName);
        TextView dial2_TxtGrund  = (TextView)dialog2.findViewById(R.id.dialog2_TxtGrund);
        TextView dial2_TxtBetrag = (TextView)dialog2.findViewById(R.id.dialog2_TxtBetrag);

        Button erhalten = (Button)dialog2.findViewById(R.id.dialog2_btnBezahlt);
        Button ok = (Button)dialog2.findViewById(R.id.dialog2_btnOk);

        NumberFormat currencyFormatter = NumberFormat.getCurrencyInstance(Locale.getDefault());
        String currencyOut = currencyFormatter.format(dialog2_betrag);

        dial2_TxtDatum.setText("Vom " + dialog2_datum + " Uhr");
        dial2_TxtName.setText(dialog2_name);
        dial2_TxtGrund.setText(dialog2_grund);
        dial2_TxtBetrag.setText(currencyOut);


        erhalten.setOnClickListener(new OnClickListener() {                                                     //Buttonklick für erhalten
            @Override
            public void onClick(View v) {

                mainActivity.myDBHandler.deleteRowInTable1(idDB);
                populateListViewFromDB();
                dialog2.dismiss();
            }
        });

        ok.setOnClickListener(new OnClickListener() {                                                           //Buttonklick für ok
            @Override
            public void onClick(View v) {

                dialog2.dismiss();
            }
        });

        dialog2.show();
    }

//  --------------------------------------------------------------------
    @SuppressWarnings("deprecation")
    public void populateListViewFromDB() {              ...
    }   

//  --------------------------------------------------------------------
    @SuppressWarnings("deprecation")
    public void populateSubListViewFromDB(long idInDB) {        

    getActivity().startManagingCursor(cursor = mainActivity.myDBHandler.getAllEntriesFromAPerson1(idInDB));

    String[] dbSpaltenNamen = new String[] {"d", "b"};

    int[] zuListViewIDs = new int[] {R.id.dialog3_datum, R.id.dialog3_lz_betrag};

    SimpleCursorAdapter myCursorAdapter 
            = new SimpleCursorAdapter
                        (getActivity(), R.layout.dialog3_listzeile, cursor, dbSpaltenNamen, zuListViewIDs);

    subList.setAdapter(myCursorAdapter);
    }

//  --------------------------------------------------------------------
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mainActivity = (MainActivity) activity;
        } 
        catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() +  " Fehler: Keine MainActivity-Instanz!");
        }
    }
}

logcat 消息:

01-10 18:10:19.392: E/AndroidRuntime(14649): FATAL EXCEPTION: main
01-10 18:10:19.392: E/AndroidRuntime(14649): java.lang.NullPointerException
01-10 18:10:19.392: E/AndroidRuntime(14649):    at fragments.Schuldet_mir.mainListViewClick(Schuldet_mir.java:193)
01-10 18:10:19.392: E/AndroidRuntime(14649):    at fragments.Schuldet_mir.access$1(Schuldet_mir.java:171)
01-10 18:10:19.392: E/AndroidRuntime(14649):    at fragments.Schuldet_mir$2.onItemClick(Schuldet_mir.java:90)
01-10 18:10:19.392: E/AndroidRuntime(14649):    at android.widget.AdapterView.performItemClick(AdapterView.java:298)
01-10 18:10:19.392: E/AndroidRuntime(14649):    at android.widget.AbsListView.performItemClick(AbsListView.java:1111)
01-10 18:10:19.392: E/AndroidRuntime(14649):    at android.widget.AbsListView$PerformClick.run(AbsListView.java:2900)
01-10 18:10:19.392: E/AndroidRuntime(14649):    at android.widget.AbsListView$1.run(AbsListView.java:3728)
01-10 18:10:19.392: E/AndroidRuntime(14649):    at android.os.Handler.handleCallback(Handler.java:615)
01-10 18:10:19.392: E/AndroidRuntime(14649):    at android.os.Handler.dispatchMessage(Handler.java:92)
01-10 18:10:19.392: E/AndroidRuntime(14649):    at android.os.Looper.loop(Looper.java:137)
01-10 18:10:19.392: E/AndroidRuntime(14649):    at android.app.ActivityThread.main(ActivityThread.java:4872)
01-10 18:10:19.392: E/AndroidRuntime(14649):    at java.lang.reflect.Method.invokeNative(Native Method)
01-10 18:10:19.392: E/AndroidRuntime(14649):    at java.lang.reflect.Method.invoke(Method.java:511)
01-10 18:10:19.392: E/AndroidRuntime(14649):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
01-10 18:10:19.392: E/AndroidRuntime(14649):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
01-10 18:10:19.392: E/AndroidRuntime(14649):    at dalvik.system.NativeStart.main(Native Method)

第 193 行是 deleteBtn.setOnClickListener 方法。我做错了什么!?提前感谢您的建议

编辑: 对话框3.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<ListView
    android:id="@+id/dialog3_listView"
    android:layout_width="match_parent"
    android:layout_height="0dip"
    android:layout_weight="0.98" >
</ListView>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="46dp" >

    <Button
        android:id="@+id/dialog3_btn1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:layout_weight="1"
        android:text="Alles erhalten" />

    <Button
        android:id="@+id/dialog3_btn2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:layout_weight="1"
        android:text="Zurück" />
</LinearLayout>

dialog3_listzeile:这是列表视图的自定义行

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<TextView
    android:id="@+id/dialog3_datum"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:text="Medium Text"
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:textStyle="italic" />

<Button
    android:id="@+id/dialog3_deleteBtn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_alignParentTop="true"
    android:focusable="false"
    android:text="Delete" />

<TextView
    android:id="@+id/dialog3_lz_betrag"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignBottom="@+id/dialog3_deleteBtn"
    android:layout_centerHorizontal="true"
    android:text="Large Text"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:textStyle="bold" />

【问题讨论】:

  • 即使这不能解决您的问题,您也不应该使用 'ä'、'ü' 或 'ö' 作为变量名。
  • 你能发帖dialog3.xml。看起来引用了错误的 ID
  • @Raghunandan id 引用正确。我发布了 xmls
  • 那么该行不能为空。如果它为空,那么它引用了错误的 id

标签: android android-listview android-fragments android-dialog android-dialogfragment


【解决方案1】:

您尝试在活动的layout 中找到dialog3_deleteBtn。这不起作用,因为它是ListViewrow 的一部分。 您必须编写一个自定义适配器来处理每行内的按钮点击。

此外,正如我在 cmets 部分已经说过的,您不应在代码中使用 'ä'、'ü'、'ö' 或类似字母。 对于“ü”,您可以改用“ue”。

Zudem solltest du dir angewöhnen möglichst auch auf Englisch zu 'coden', damit möglichst viele deinen Code besser verstehen。

【讨论】:

  • 感谢您的建议。正如 raghunandan 所说,它毕竟没有用。相同的错误信息。 (丹克)
  • @user1953173 我认为您必须编写一个自定义适配器来处理行内的按钮点击,否则您将无法获取它们。
  • @user1953173 您的代码绝对令人困惑且难以调试。请改变你编码的方式。也发布适配器代码
  • 适配器在方法 populateSubListViewFromDB() 中。我贴出来了
  • @user1953173 不,您还没有创建自定义适配器。您只需使用 SimpleCursorAdapter。 SimpleCursorAdapter myCursorAdapter = new SimpleCursorAdapter (getActivity(), R.layout.dialog3_listzeile, cursor, dbSpaltenNamen, zuListViewIDs);您可以扩展 SimpleCursorAdapter 并在膨胀每一行时为按钮添加一个侦听器。
【解决方案2】:

dialog3.xml 没有 ID 为 R.id.dialog3_deleteBtn 的按钮

findViewById 在当前的膨胀布局中查找具有 id 的视图。所以它会给你NullPointerException

你有这个在dialog3_listzeile.xml

<Button
android:id="@+id/dialog3_deleteBtn"
android:layout_width="wrap_content"

应该是

Button deleteBtn = (Button)dv.findViewById(R.id.dialog3_deleteBtn);

除此之外。

MainActivity mainActivity = (MainActivity) getActivity();

也是错的

getActivity() 将返回 null。移至onCreateView

【讨论】:

  • 我知道。列表视图是自定义列表视图。该列表视图的单行有一个按钮。
  • @user1953173 然后使用Button deleteBtn = (Button)dv.findViewById(R.id.dialog3_deleteBtn); onItemClick 有一个View v 作为参数。所以用它来初始化你的按钮
  • @user1953173 我还建议您编辑您的帖子并向我们说明清楚。它非常混乱,我们没有看到适配器代码,我们不知道按钮在哪里
  • @user1953173 尝试我评论中的代码并告诉我它是否有效
  • @user1953173 1.您没有 ImageButton 2.您没有自定义适配器。 3.您应该只发布相关代码。 4. 让我们清楚地看到帖子,以便我们提供帮助。您的编码不仅令人困惑,而且令人困惑且难以对其他人进行调试。