0

我一直在为 Android 开发一个简单的触摸处理程序,它可以触发诸如 onUpdate(触摸屏幕时)之类的回调,而无需设置线程。我的问题是我对 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);
}

我希望这个问题不会太无聊,不能在这里发布:)

编辑:感谢大家的帮助,最后我遵循了 Bughi 的解决方案。

4

6 回答 6

4

TouchHelper helper;是空的,它需要一个接口实例才能调用它的方法 - 在你的情况下,实现你的接口的主要活动类 -

为监听器做一个 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);
        ...
    }
}

还要为您的 on touch 方法添加一个空检查:

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);

那么简单helper就是null,在哪里初始化呢?

我看到你定义它:

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但没有在代码中创建对象或将现有对象分配给该属性的代码中。所以当你尝试使用它时它仍然是空的。

于 2012-07-21T17:37:40.750 回答
0

helper在您的输入中为空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 回答