0

私は、スレッドを設定することなく、onUpdate(画面がタッチされたとき)のようなコールバックを起動する可能性のあるAndroid用のシンプルなタッチハンドラーを開発してきました。私の問題は、Javaの知識がかなり限られており、インターフェイスの使用方法をほとんど知らないため、それができないことです。私の問題は単純なタイプミスか何かである可能性が高いと確信していますが、メインアクティビティクラスで必要なことを実行できるように、タッチハンドラー(タッチ情報を処理した)からメソッドを実行するとNullPointerExceptionが発生します。

これはメインのクラスコードです(無関係なものから切り取ったものです):

//package and imports

public class Test extends Activity implements TouchHelper {

    StringBuilder builder = new StringBuilder();
    TextView textView;
    TouchReader touchReader;
    List<TouchTable> touchTablesArray;
    TouchTable touchTable;
    public static final String Tag = "TouchTest";

        @Override
        public void onCreate(Bundle savedInstanceState) 
        {
            super.onCreate(savedInstanceState);
            textView = new TextView(this);
            Log.d(Tag, "TextView initialized " + textView);
            textView.setText("Touch and drag (multiple fingers supported)!");
            touchReader = new TouchReader(textView);
            Log.d(Tag, "touchReader initialized");
            touchTablesArray = touchReader.getTouchTables();
            setContentView(textView);
        }

        @Override
        public void onTouchUpdate(int pointerId)
        {
            Log.d(Tag, "onTouchUpdate called");
            touchTable = touchTablesArray.get(pointerId);
            Log.d(Tag, "touchTable get successful");
            //writing on stringbuilder
        }
    }

これは、ハンドラー自体のコードです。

//package and imports

public class TouchReader implements OnTouchListener
{
    public final static String Tag = "TouchReader";
    List<TouchTable> touchTables;
    TouchHelper helper;
    TouchTable touchTable = new TouchTable();

    public TouchReader(View view)
    {
        view.setOnTouchListener(this);
        touchTables = new ArrayList<TouchTable>(10);
        Log.d(Tag, "TouchReader initialized");
    }

    public boolean onTouch(View v, MotionEvent event)
    {
        synchronized(this)
        {
            //all the common code handling the actual handling, with switches and such
            touchTables.add(pointerId, touchTable); //obviously the pointerId is defined earlier
            Log.d(Tag, "Values updated");
            helper.onTouchUpdate(pointerId); //the exception is here
            Log.d(Tag, "Update called");
        }
        return true;
    }
    public List<TouchTable> getTouchTables()
    {
        synchronized(this)
        {
            return touchTables;
        }
    }
}

ご覧のとおり、エラーはインターフェイスを正しく使用できないことが原因である可能性が高いですが、すべての公式ドキュメントでさらに混乱しています。

最後に、インターフェースの小さなコード:

//package

public interface TouchHelper 
{
    public void onTouchUpdate(int pointerId);
}

私はこの質問がここに投稿するのにあまりにも気難しいものではないことを願っています:)

編集:助けてくれたすべての人に感謝します、結局私はブギの解決策に従いました。

4

6 に答える 6

4

あなたTouchHelper helper;はnullです、それはそれでメソッドを呼び出すことができるようにインターフェースのインスタンスを必要とします-あなたの場合あなたのインターフェースを実装するメインアクティビティクラス-

リスナーのsetメソッドを作成します

public void setOnTouchListener(TouchHelper helper)
{
    this.helper = helper;
}

次に、作成時に呼び出します。

public class Test extends Activity implements TouchHelper {
    ...
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        ...
        touchReader = new TouchReader(textView);
        touchReader.setOnTouchListener(this);
        ...
    }
}

また、ontouchメソッドにnullチェックを追加します。

public boolean onTouch(View v, MotionEvent event)
{
    synchronized(this)
    {
        //all the common code handling the actual handling, with switches and such
        touchTables.add(pointerId, touchTable); //obviously the pointerId is defined earlier
        Log.d(Tag, "Values updated");
        if (helper != null)
            helper.onTouchUpdate(pointerId); //the exception is here
        Log.d(Tag, "Update called");
    }
    return true;
}
于 2012-07-21T17:46:14.870 に答える
2

NullPointerExceptionがここにある場合:

helper.onTouchUpdate(pointerId);

それでは単にhelpernullですが、どこで初期化しますか?

私はあなたがそれを定義しているのを見ます:

TouchHelper helper;

しかし、あなたは今までに持っていますか?

helper = ...
于 2012-07-21T17:35:39.113 に答える
1

私はこれが古いことを知っていますが、私はこれに自分で立ち往生していました。上記のサムの投稿は私がそれを考えるのを助けました。
最後に、インターフェイスが初期化され、インターフェイスするメインアクティビティに実装されていることを確認するonAttachメソッドを追加しました。テストするメインアクティビティ内にLog.iを追加しました。

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
        mainActivityCallback = (OnSomethingSelectedListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement OnSomethingSelectedListener");
    }
}
于 2014-08-17T09:51:44.927 に答える
0

コードのどこにもオブジェクトが作成されていないか、既存のオブジェクトがその属性に割り当てられている場合TouchReaderに定義します。TouchHelperしたがって、使用しようとしてもnullのままです。

于 2012-07-21T17:37:40.750 に答える
0

helperあなたのでnullですTouchReader

これを修正するには、次のTouchReaderようにしTouchHelperます。

public TouchReader(View view, TouchHelper helper) {
    ...
    this.helper = helper;   
    ...
}

それからあなたの活動で:

touchReader = new TouchReader(textView, this);
于 2012-07-21T17:39:16.857 に答える
0

コンストラクターで初期化してみてください。初期化されていないすべての参照はnullに設定されます。

// I see no reason why this should be a member variable; make it local
StringBuilder builder = new StringBuilder();
TextView textView;
TouchReader touchReader;
List<TouchTable> touchTablesArray;
TouchTable touchTable;
public TouchReader(View view)
{
    // textView is null
    // touchReader is null
    view.setOnTouchListener(this);
    // why "10"?  why a List of touchTables and a touchTable member variable?  why both?
    touchTables = new ArrayList<TouchTable>(10);
    Log.d(Tag, "TouchReader initialized");
    // touchTable is null;
}
于 2012-07-21T17:39:42.260 に答える