Domanda

Nella mia app Android, con ViewPager, Ho FragmentActivity per creare ViewPager.

In onCreate metodo che cerco di impostare OnClickListener per Button.Ma dopo aver compilato la mia app si è schiantata.Se rimuovo tutto setOnClickListeners tutto funziona.

Puoi aiutarmi?

public class MainActivity extends FragmentActivity {

    AdvicePageAdapter pageAdapter;

    Spinner categoriesSpinner;

    Button blueButton, greenButton, pinkButton, greyButton, yellowButton;

    private OnClickListener oclBtn;

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

        setContentView(R.layout.activity_main);

        List<Fragment> fragments = getFragments();

        pageAdapter = new AdvicePageAdapter(getSupportFragmentManager(), fragments);

        ViewPager pager = (ViewPager)findViewById(R.id.viewpager);
        pager.setAdapter(pageAdapter);

        blueButton = (Button) findViewById(R.id.blueButton);
        greenButton = (Button) findViewById(R.id.greenButton);
        pinkButton = (Button) findViewById(R.id.pinkButton);
        greyButton = (Button) findViewById(R.id.greyButton);
        yellowButton = (Button) findViewById(R.id.yellowButton);

        oclBtn = new OnClickListener (){
            @Override
            public void onClick(View v){
            }
        };

        blueButton.setOnClickListener(oclBtn);
        greenButton.setOnClickListener(oclBtn);
        pinkButton.setOnClickListener(oclBtn);
        greyButton.setOnClickListener(oclBtn);
        yellowButton.setOnClickListener(oclBtn);

    }
}

Il mio logcat

04-12 11:31:33.567: E/AndroidRuntime(2748): FATAL EXCEPTION: main
04-12 11:31:33.567: E/AndroidRuntime(2748): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.eugene.greatadvice/com.eugene.greatadvice.MainActivity}: java.lang.NullPointerException
04-12 11:31:33.567: E/AndroidRuntime(2748):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
04-12 11:31:33.567: E/AndroidRuntime(2748):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
04-12 11:31:33.567: E/AndroidRuntime(2748):     at android.app.ActivityThread.access$600(ActivityThread.java:141)
04-12 11:31:33.567: E/AndroidRuntime(2748):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
04-12 11:31:33.567: E/AndroidRuntime(2748):     at android.os.Handler.dispatchMessage(Handler.java:99)
04-12 11:31:33.567: E/AndroidRuntime(2748):     at android.os.Looper.loop(Looper.java:137)
04-12 11:31:33.567: E/AndroidRuntime(2748):     at android.app.ActivityThread.main(ActivityThread.java:5103)
04-12 11:31:33.567: E/AndroidRuntime(2748):     at java.lang.reflect.Method.invokeNative(Native Method)
04-12 11:31:33.567: E/AndroidRuntime(2748):     at java.lang.reflect.Method.invoke(Method.java:525)
04-12 11:31:33.567: E/AndroidRuntime(2748):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
04-12 11:31:33.567: E/AndroidRuntime(2748):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
04-12 11:31:33.567: E/AndroidRuntime(2748):     at dalvik.system.NativeStart.main(Native Method)
04-12 11:31:33.567: E/AndroidRuntime(2748): Caused by: java.lang.NullPointerException
04-12 11:31:33.567: E/AndroidRuntime(2748):     at com.eugene.greatadvice.MainActivity.onCreate(MainActivity.java:83)
04-12 11:31:33.567: E/AndroidRuntime(2748):     at android.app.Activity.performCreate(Activity.java:5133)
04-12 11:31:33.567: E/AndroidRuntime(2748):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
04-12 11:31:33.567: E/AndroidRuntime(2748):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
04-12 11:31:33.567: E/AndroidRuntime(2748):     ... 11 more

File di layout principale:

<?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" 
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textViewAdvice"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:textAppearance="?android:attr/textAppearanceLarge" />


</RelativeLayout>

FragmentFile:

<?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" 
    android:orientation="vertical"
    android:background="@color/grey" >

    <TextView
        android:id="@+id/categoriesTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_marginLeft = "15dip"
        android:layout_marginTop = "15dip"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="@string/categoriesTitle"
        android:textColor="@color/white"
        android:textSize="17sp" />

    <TextView
        android:id="@+id/setingsTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_marginLeft = "15dip"
        android:layout_marginBottom = "15dip"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="@string/settingsTitle"
        android:textColor="@color/white"
        android:textSize="35sp"/>

    <Spinner
        android:id="@+id/categorieSpinner"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft = "15dip"
        android:layout_marginRight = "15dip"
        android:layout_marginTop = "15dip"
        android:layout_below="@+id/categoriesTitle"
        android:entries="@array/categories_array"
        android:background="@color/white"
        android:paddingTop="5dip"
        android:paddingBottom="5dip"
        android:textSize="17sp" />

    <TextView
        android:id="@+id/colorsTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/categorieSpinner"
        android:layout_below="@+id/categorieSpinner"
        android:layout_marginTop="20dp"
        android:text="@string/colorsTitle"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textColor="@color/white"
        android:textSize="17sp" />

    <View
        android:id="@+id/colorsBG"
        android:layout_width="84dip"
        android:layout_height="84dip"
        android:layout_below="@+id/colorsTitle"
        android:layout_marginLeft = "13dip"
        android:layout_marginTop = "13dip"
        android:background="@color/white" />

    <Button
        android:id="@+id/blueButton"
        android:layout_width="80dip"
        android:layout_height="80dip"
        android:layout_marginLeft = "15dip"
        android:layout_marginTop = "15dip"
        android:layout_below="@+id/colorsTitle"
        android:background="@color/blue"
     />

    <Button
        android:id="@+id/greenButton"
        android:layout_width="80dip"
        android:layout_height="80dip"
        android:layout_marginLeft = "110dip"
        android:layout_marginTop = "15dip"
        android:layout_below="@+id/colorsTitle"
        android:background="@color/green"
     />

    <Button
        android:id="@+id/pinkButton"
        android:layout_width="80dip"
        android:layout_height="80dip"
        android:layout_marginLeft = "205dip"
        android:layout_marginTop = "15dip"
        android:layout_below="@+id/colorsTitle"
        android:background="@color/pink"
     />

    <Button
        android:id="@+id/greyButton"
        android:layout_width="80dip"
        android:layout_height="80dip"
        android:layout_marginLeft = "15dip"
        android:layout_marginTop = "110dip"
        android:layout_below="@+id/colorsTitle"
        android:background="@color/lightGrey"
     />

    <Button
        android:id="@+id/yellowButton"
        android:layout_width="80dip"
        android:layout_height="80dip"
        android:layout_marginLeft = "110dip"
        android:layout_marginTop = "110dip"
        android:layout_below="@+id/colorsTitle"
        android:background="@color/yellow"
     />

</RelativeLayout>

Codice attività completo

package com.eugene.greatadvice;

import java.util.ArrayList;
import java.util.List;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.Spinner;

public class MainActivity extends FragmentActivity {

    AdvicePageAdapter pageAdapter;

    Spinner categoriesSpinner;

    Button blueButton, greenButton, pinkButton, greyButton, yellowButton;

    View colorsBG;

    public OnClickListener oclBtn = new OnClickListener() 
    {
        @Override
        public void onClick(View v) 
        {
            if(v == blueButton)
            {
            }

            if(v == greenButton)
            {
            }

           if(v == pinkButton)
            {
            }

            if(v == greyButton)
            {
            }
           if(v == yellowButton)
            {
            }
        }
      };

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

        setContentView(R.layout.activity_main);

        List<Fragment> fragments = getFragments();

        pageAdapter = new AdvicePageAdapter(getSupportFragmentManager(), fragments);

        ViewPager pager = (ViewPager)findViewById(R.id.viewpager);
        pager.setAdapter(pageAdapter);

        colorsBG = findViewById(R.id.colorsBG);

        //init actions

        categoriesSpinner = (Spinner) findViewById(R.id.categorieSpinner);

        blueButton = (Button) findViewById(R.id.blueButton);
        greenButton = (Button) findViewById(R.id.greenButton);
        pinkButton = (Button) findViewById(R.id.pinkButton);
        greyButton = (Button) findViewById(R.id.greyButton);
        yellowButton = (Button) findViewById(R.id.yellowButton);

        blueButton.setOnClickListener(oclBtn);
        greenButton.setOnClickListener(oclBtn);
        pinkButton.setOnClickListener(oclBtn);
        greyButton.setOnClickListener(oclBtn);
        yellowButton.setOnClickListener(oclBtn);

    }


    private List<Fragment> getFragments(){
        List<Fragment> fList = new ArrayList<Fragment>();

        fList.add(SettingsFragment.newInstance(""));
        fList.add(AdviceFragment.newInstance(""));

        return fList;
    }

    private class AdvicePageAdapter extends FragmentPagerAdapter {
        private List<Fragment> fragments;

        public AdvicePageAdapter(FragmentManager fm, List<Fragment> fragments) {
            super(fm);
            this.fragments = fragments;
        }
        @Override
        public Fragment getItem(int position) {
            return this.fragments.get(position);
        }

        @Override
        public int getCount() {
            return this.fragments.size();
        }
    }

}
È stato utile?

Soluzione

Ma dopo aver compilato la mia app si è schiantata.

Quello NullPointerException sta accadendo perché stai cercando di accedere alla vista di un Fragment in un momento inappropriato quando non è in uno stato valido.Questi pulsanti fanno parte del layout del frammento, il cui frammento viene istanziato solo nel onCreate() callback, verrà creata la sua vista dopo metodo onCreate() quindi cercare di trovare quei pulsanti nella vista frammento inesistente renderà i riferimenti nulli.

Quello che stai facendo è anche sbagliato perché non è un ottimo modo per gestire quell'interazione.I frammenti dovrebbero essere progettati come elementi autonomi, che possono essere collegati dove necessario, cercando le viste di un frammento dal Activity rompe questo e lega il frammento al Activity(per non parlare delle alte probabilità di errori).Per evitare questo (insieme al problema sopra) usa un'interfaccia per trasmettere gli eventi di clic dal frammento all'attività se questo è ciò che vuoi:

/**
* An interface that will transmit the click events to the Activity
*/
public interface ClickDispatch {

    void onClickReceived(View btn);
}

L'attività implementerà questa interfaccia

public class MainActivity extends FragmentActivity implements ClickDispatch {

   // code...

   @Override
   public void onClickReceived(View btn) {
       // one of the fragment's buttons(btn) was clicked so do stuff
   }

Quindi rimuovere il ritrovamento dei pulsanti e impostare il listener su di essi nell'Attività onCreate() metodo e farlo nel frammento in cui si hanno i pulsanti:

   ClickDispatch mListener; 

   // in the fragment class
   @Override
   public void onAttach(Activity activity) {
       super.onAttach(activity);
       // this is where the activity is passed to the fragment, we use this to cast the 
       // activity to our listener to pass it the click events
       mListener = (ClickDispatch) activity;
   } 


   // in the onCreateView method of the fragment:
   View inflatedView = inflater.inflate(/*your layout*/);
   blueButton = (Button) inflatedView.findViewById(R.id.blueButton);
   greenButton = (Button) inflatedView.findViewById(R.id.greenButton);
   pinkButton = (Button) inflatedView.findViewById(R.id.pinkButton);
   greyButton = (Button) inflatedView.findViewById(R.id.greyButton);
   yellowButton = (Button) inflatedView.findViewById(R.id.yellowButton);
   OnClickListener oclBtn = new OnClickListener (){
            @Override
            public void onClick(View v){
                // dispatch the click event to the Activity
                if (mListener != null) {
                     mListener.onClickReceived(v);
                }
            }
        };
   blueButton.setOnClickListener(oclBtn);
   greenButton.setOnClickListener(oclBtn);
   pinkButton.setOnClickListener(oclBtn);
   greyButton.setOnClickListener(oclBtn);
   yellowButton.setOnClickListener(oclBtn);

Altri suggerimenti

I pulsanti e altre viste vengono gonfiati nel frammento, non sulla vostra attività, quindi findViewById() restituisce null per tali ID.Se si intende per i pulsanti, ecc. Per essere nell'attività, spostare quegli elementi da frammentfile a activity_main.xml.In caso contrario, sposta le inizializzazioni e i metodi di vista per le classi di frammenti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top