2012-07-21 81 views
-1

我一直在为Android开发一个简单的触摸处理程序,可以像onUpdate(当触摸屏幕时)触发回调,而无需设置线程。我的问题是,我对Java的知识是相当有限的,我不能这样做,因为我对如何使用接口知之甚少。我敢肯定,我的问题可能是一个简单的错字或什么的,但我得到一个NullPointerException当我从触摸处理程序(处理触摸信息)执行该方法,以便我可以做我需要的主要活动类。Java,使用接口作为回调

这是主类代码(剪切从无关紧要的东西):

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

我希望这个问题不是太noobish它张贴在这里:)

编辑:感谢所有的帮助,在最后我跟着布吉的解决方案。

回答

3

TouchHelper helper;为null,它需要的接口的实例能够调用的方法就可以了-in的情况下实现的主要活动类的界面 -

制作的一套方法听众

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

同时添加一个空检查您的触摸方法:

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; 
} 
+0

谢谢,这工作像一个魅力。显然这个错误是愚蠢的,但是因为我知道“实例化”,一个接口的工作方式与我失去的普通课程不同。 – Lama 2012-07-21 19:17:18

2

如果NullPointerException异常是在这里:

helper.onTouchUpdate(pointerId); 

然后简单helper为空,你在哪里初始化?

我看到你定义它:

TouchHelper helper; 

但你曾经有?

helper = ... 
0

TouchReader定义中创建一个对象的代码一个TouchHelper但不通或现有对象被分配给该属性。所以当你尝试使用它时它仍然是空的。

0

helper为null,在你的TouchReader

为了解决这个问题使TouchReader采取TouchHelper

​​

然后在您的活动:

touchReader = new TouchReader(textView, this); 
0

尝试在你的构造函数初始化它;所有未初始化的引用都设置为空。

// 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; 
} 
+0

10,因为我尝试了一下用ArrayList中,我选择了价值,因为......嗯,尽量把超过10个手指在手机上:/的touchTable成员变量是一个缓冲区上,我写入数据,然后将其保存到ArrayList。可能不是最有效的方式,但它是迄今为止最简单的 – Lama 2012-07-21 19:19:41

+0

正如我所指出的,您还有很多其他问题。你会很好地解决这些问题。你是新人,所以你应该知道这对你和那些为捐助有用答案并且接受回答你问题的最好答案而献出时间的人是有益的。 – duffymo 2012-07-21 19:21:54

+0

如果你的意思是你的其他评论,我给这些变量在构造函数或代码的其他部分的值。 完成听众功能后代码完美工作 – Lama 2012-07-21 19:27:09

1

我知道这是老了,但我被困在这个自己。上面的Sam的帖子帮助我想起了它。
我最终添加了一个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"); 
    } 
}