viewFlipper.getDisplayedChild null对象引用

时间:2015-10-09 15:28:03

标签: java android webview

所以,我有一个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>

1 个答案:

答案 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
 }