FragmentActivity setOnClickListener ist fehlgeschlagen
-
21-12-2019 - |
Frage
In meiner Android-App mit ViewPager
, Ich habe FragmentActivity
zum Erstellen von ViewPager
.
In onCreate
methode, die ich versuche einzustellen OnClickListener
für Button
.Aber nach dem Kompilieren stürzte meine App ab.Wenn ich alle entferne setOnClickListener
s alles funktioniert.
Könntest du mir helfen?
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);
}
}
Mein 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
Hauptlayout-Datei:
<?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>
Fragmentdatei:
<?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>
Vollständiger Aktivitätscode
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();
}
}
}
Lösung
Aber nach dem Kompilieren stürzte meine App ab.
Dass NullPointerException
geschieht, weil Sie versuchen, auf die Ansicht eines zuzugreifen Fragment
zu einem unangemessenen Zeitpunkt, wenn es sich nicht in einem gültigen Zustand befindet.Diese Schaltflächen sind Teil des Fragmentlayouts, das Fragment wird nur in der instanziiert onCreate()
rückruf, seine Ansicht wird erstellt nach Methode onCreate()
wenn Sie also versuchen, diese Schaltflächen in der nicht vorhandenen Fragmentansicht zu finden, werden die Referenzen null.
Was Sie tun, ist auch falsch, weil es keine sehr gute Möglichkeit ist, mit dieser Interaktion umzugehen.Fragmente sollen als eigenständige Elemente gestaltet sein, die bei Bedarf eingesteckt werden können und nach den Ansichten eines Fragments aus dem suchen Activity
bricht dies und bindet das Fragment an die Activity
(ganz zu schweigen von der hohen Fehlerwahrscheinlichkeit).Um dies zu vermeiden (zusammen mit dem obigen Problem), verwenden Sie eine Schnittstelle, um die Klickereignisse vom Fragment an die Aktivität zu übertragen, wenn Sie dies möchten:
/**
* An interface that will transmit the click events to the Activity
*/
public interface ClickDispatch {
void onClickReceived(View btn);
}
Die Aktivität implementiert diese Schnittstelle
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
}
Entfernen Sie dann das Auffinden der Schaltflächen und setzen Sie den Listener in der Aktivität darauf onCreate()
methode und tun Sie es in dem Fragment, in dem Sie die Schaltflächen haben:
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);
Andere Tipps
Ihre Schaltflächen und andere Ansichten werden in Ihr Fragment aufgeblasen, nicht in Ihre Aktivität, also findViewById()
kehrt zurück null
für diese Ausweise.Wenn du für die Knöpfe meinst usw.verschieben Sie diese Elemente von FragmentFile nach, um an der Aktivität teilzunehmen activity_main.xml
.Andernfalls verschieben Sie die Ansichtsinitialisierungen und -methoden in Ihre Fragmentklassen.