所以,我有一个viewflipper,里面装满了几个webview。然后,我扩展了WebView类,以便捕获viewflipper的动作。
问题是,当我滑动时,应用程序崩溃并给我以下错误:
10-09 17:23:14.443: E/MessageQueue-JNI(21126): java.lang.NullPointerException: Attempt to invoke virtual method 'int android.widget.ViewFlipper.getDisplayedChild()' on a null object reference
10-09 17:23:14.443: E/MessageQueue-JNI(21126): at com.test.hamnarbetare.CustomWebView.onTouchEvent(CustomWebView.java:55)
可在此处查看代码:
package com.test.hamnarbetare;
import android.content.Context;
import android.util.Log;
import android.view.MotionEvent;
import android.webkit.WebView;
import android.widget.ViewFlipper;
public class CustomWebView extends WebView {
private float lastX;
private ViewFlipper viewFlipper;
float downXValue;
long downTime;
private float lastTouchX, lastTouchY;
private boolean hasMoved = false;
public CustomWebView(Context context) {
super(context);
viewFlipper = (ViewFlipper) findViewById(R.id.viewFlipper);
}
public boolean onTouchEvent(MotionEvent evt) {
boolean consumed = super.onTouchEvent(evt);
if (isClickable()) {
switch (evt.getAction()) {
case MotionEvent.ACTION_DOWN:
lastTouchX = evt.getX();
lastTouchY = evt.getY();
downXValue = evt.getX();
downTime = evt.getEventTime();
hasMoved = false;
break;
case MotionEvent.ACTION_MOVE:
hasMoved = moved(evt);
break;
case MotionEvent.ACTION_UP:
float currentX = evt.getX();
long currentTime = evt.getEventTime();
float difference = Math.abs(downXValue - currentX);
long time = currentTime - downTime;
if ( (downXValue < currentX) && (time < 220) && (difference > 100) ) {
if (viewFlipper.getDisplayedChild() == 1)
break;
viewFlipper.setInAnimation(getContext(), R.anim.slide_in_from_right); // Next screen comes in from right.
viewFlipper.setOutAnimation(getContext(), R.anim.slide_out_to_left); // Current screen goes out from left.
// Display previous screen.
viewFlipper.showPrevious();
}
if ( (downXValue > currentX) && (time < 220) && (difference > 100) ) {
if (viewFlipper.getDisplayedChild() == 0)
break;
viewFlipper.setInAnimation(getContext(), R.anim.slide_in_from_left); // Next screen comes in from left.
viewFlipper.setOutAnimation(getContext(), R.anim.slide_out_to_right); // Current screen goes out from right.
// Display next screen.
viewFlipper.showNext();
}
//if (!moved(evt)) performClick();
break;
}
}
return consumed || isClickable();
}
private boolean moved(MotionEvent evt) {
return hasMoved || Math.abs(evt.getX() - lastTouchX) > 10.0 || Math.abs(evt.getY() - lastTouchY) > 10.0;
}
/*public boolean onTouchEvent(MotionEvent touchevent) {
switch (touchevent.getAction()) {
case MotionEvent.ACTION_DOWN:
lastX = touchevent.getX();
break;
case MotionEvent.ACTION_UP:
float currentX = touchevent.getX();
// Handling left to right screen swap.
if (lastX < currentX) {
// If there aren't any other children, just break.
if (viewFlipper.getDisplayedChild() == 0)
break;
viewFlipper.setInAnimation(getContext(), R.anim.slide_in_from_left); // Next screen comes in from left.
viewFlipper.setOutAnimation(getContext(), R.anim.slide_out_to_right); // Current screen goes out from right.
// Display next screen.
viewFlipper.showNext();
}
// Handling right to left screen swap.
if (lastX > currentX) {
// If there is a child (to the left), just break.
if (viewFlipper.getDisplayedChild() == 1)
break;
viewFlipper.setInAnimation(getContext(), R.anim.slide_in_from_right); // Next screen comes in from right.
viewFlipper.setOutAnimation(getContext(), R.anim.slide_out_to_left); // Current screen goes out from left.
// Display previous screen.
viewFlipper.showPrevious();
}
break;
}
return false;
}*/
}
出于某种原因,此时viewFlipper未知。但是,如果我将onTouchEvent替换为位于底部的先前onTouchEvent,它一切正常,我无法理解为什么!有什么想法吗?
编辑:布局xml文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:paddingTop="10dp" >
<ViewFlipper
android:id="@+id/viewFlipper"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.70" />
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/actionbar_bg" >
<Button
android:id="@+id/btn_left"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_weight="0.23"
android:text="@string/previous" />
<TextView
android:id="@+id/page_counter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.23"
android:gravity="center"
android:text=""
android:textColor="#FFFFFF" />
<Button
android:id="@+id/btn_right"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_weight="0.35"
android:text="@string/next" />
</LinearLayout>
</LinearLayout>
答案 0 :(得分:1)
问题是CustomWebView无法使用findViewById找到R.id.viewFlipper。
您需要做的是在ParentActivity中查找R.id.viewFlipper并在CustomWebView构造函数中传递ViewFlipper。
下面的示例代码,未编译/测试。
CustomWebView.java
public CustomWebView(Context context, ViewFlipper viewFlipper) {
super(context);
this.viewFlipper = viewFlipper;
}
ParentActivity.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout_xml);
ViewFlipper viewFlipper = (ViewFlipper) findViewById(R.id.viewFlipper);
CustomWebView webView = new CustomWebView(this, viewFlipper);
// TODO: Add webView to viewFlipper
}