FragmentActivity SetOnClickListenerが失敗しました
-
21-12-2019 - |
質問
ViewPager
を使用して、FragmentActivity
を作成するためのViewPager
を作成しました。
onCreate
メソッドでは、OnClickListener
用のButton
を設定しようとします。しかし、私のアプリをコンパイルした後にクラッシュしました。すべてのsetOnClickListener
sをすべて削除した場合はすべて働きます。
あなたは私を助けることができますか?
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);
}
}
.
私の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
.
メインレイアウトファイル:
<?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>
.
フラグメントファイル:
<?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>
.
完全アクティビティコード
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();
}
}
}
. 解決
しかし、私のアプリをコンパイルした後、クラッシュしました。
NullPointerException
が起こっているのは、有効な状態にない場合は、不適切な時点でFragment
のビューにアクセスしようとしているためです。これらのボタンはFragment Layoutの一部です。このフラグメントはonCreate()
コールバックでのみインスタンス化されているため、の後にの後に作成されます。 NULLを参照してください。
あなたがやっていることも間違っていますので、その相互作用を扱うための非常に良い方法ではありません。フラグメントは、必要に応じてプラグメントのビューを検索することができる自己含有項目として設計されることになっています。これを回避するために(上記の問題と共に)これが必要なものである場合、断片からアクティビティへのクリックイベントを送信するためのインターフェースを使用します。
/**
* An interface that will transmit the click events to the Activity
*/
public interface ClickDispatch {
void onClickReceived(View btn);
}
.
アクティビティはこのインタフェース
を実装します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
}
.
ボタンの検索を取り除き、アクティビティのonCreate()
メソッドでそれらの上のリスナーを設定し、ボタンを持っているフラグメントで実行します。
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);
. 他のヒント
あなたのボタンやその他のビューはあなたの活動ではなくあなたの断片に膨張しているので、findViewById()
はそれらのIDのためにnull
を返します。ボタンなどがアクティビティにあることを意味する場合は、それらの要素をFragmentFileからactivity_main.xml
に移動します。それ以外の場合は、ビューの初期化とメソッドをフラグメントクラスに移動します。