简体   繁体   中英

Android - setOnClickListener crashing in fragment

I am working on an activity which uses two fragments, one for displaying images on a canvas and the second which features buttons to affect elements on the canvas. I have just set up onClickListeners for the two buttons, and now the program is crashing where it didn't crash before. This happens immediately when it runs, so I don't know what exactly is the problem except that logcat says it's entirely an issue with this fragment. I can only assume that I'm implementing setOnClickListener incorrectly. Could anyone help me to see what I am doing incorrectly?

ToolbarFragment

package com.example.chris.drawingtest;

import android.app.Activity;
import android.app.Fragment;
import android.content.DialogInterface;
import android.nfc.Tag;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageButton;

import com.example.chris.drawingtest.R;

/**
 * Created by Chris on 11/28/2014.
 */
public class ToolbarFragment extends Fragment {

    ToolSelectionListener mCallback;

    ImageButton pencilButton, eraserButton;

    public interface ToolSelectionListener {
        public void sendNewValue(int newValue);
    }

    public void clicked(ImageButton imageButton) {
        Log.d("we're listening...", "to the buttons!");
        if (imageButton.getId() == eraserButton.getId())
            mCallback.sendNewValue(1);
        else
            mCallback.sendNewValue(0);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        pencilButton = (ImageButton) getActivity().findViewById(R.id.pencil);
        eraserButton = (ImageButton) getActivity().findViewById(R.id.eraser);

        pencilButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                clicked(pencilButton);
            }
        });

        eraserButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                clicked(eraserButton);
            }
        });

        Log.d("Toolbar Inflation", "Inflating ToolbarFragment...");
        return inflater.inflate(R.layout.fragment_toolbar, container, false);

    }
}

**EDIT: ** Here is the matching XML file as well.

fragment_toolbar:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="40dp"
    android:layout_gravity="bottom|left"
    android:orientation="horizontal"
    >

    <ImageButton
        android:id="@+id/pencil"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_gravity="left"
        android:background="@drawable/pencil"
        />

    <ImageButton
        android:id="@+id/eraser"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_gravity="center"
        android:background="@drawable/eraser"
        />

</LinearLayout>

Thanks for any help you can give!

The problem of your part of code is that in Fragment you have to inflate the view. You are inflating it only when you return it. Try to change your onCreateView in this way:

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        final View view = inflater.inflate(R.layout.fragment_toolbar, container, false);
        pencilButton = (ImageButton) view.findViewById(R.id.pencil);
        eraserButton = (ImageButton) view.findViewById(R.id.eraser);

        pencilButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                clicked(pencilButton);
            }
        });

        eraserButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                clicked(eraserButton);
            }
        });

        Log.d("Toolbar Inflation", "Inflating ToolbarFragment...");
        return view;

    }

You're getting an exception because you're trying to call functionality on ImageButtons before they're inflated. See how your inflater inflates after your setOnCallListener?

In your onCreateView , you're referencing Buttons, pencilButton and eraserButton improperly by calling your findViewById() off of getActivity.

Instead, transplant that logic to onViewCreated and call your findViewById(R.id.xxx) on the View parameter.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_toolbar, container, false);

    pencilButton = (ImageButton) view.findViewById(R.id.pencil);
    eraserButton = (ImageButton) view.findViewById(R.id.eraser);

    pencilButton.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            clicked(pencilButton);
        }
    });

    eraserButton.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            clicked(eraserButton);
        }
    });

    Log.d("Toolbar Inflation", "Inflating ToolbarFragment...");
    return view;

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM