Question

I know you'll have seen this question before. I know I have :-). But still, combing all the answers I have found I still get the inflating class error. My layout has an extended webView as I want to be able to swipe left and right in order to load previous and next html pages. I include the entire layout as I find that most of the answers I have found present a solution in a somewhat abstract manner dealing with just the webView and not as a part of a larger picture. Hopefully when this is answered it will help others to get the bigger picture as well.

The scrollview at the bottom wil contain buttons as an alternative means of navigating the html pages. The view imageView2 will contain a transparent header partly obscuring the underlying webView. The textView helloText will display the chapter titles. I had all of this working until I had to extend the webView to deal with the left right swipes.

Here's the layout xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <RelativeLayout
        android:id="@+id/relativeLayout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.8"
        android:orientation="vertical" >

        <com.example.test.MyWebView
            android:id="@+id/webView1"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true" />

        <View
            android:id="@+id/imageView2"
            android:layout_width="fill_parent"
            android:layout_height="50dp"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true" 
            android:background="#88FF0000"/>
    </RelativeLayout>

    <TextView
        android:id="@+id/helloText"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.05"
        android:gravity="center_horizontal"
        android:text="Hello World" />

    <HorizontalScrollView
        android:id="@+id/horizontalScrollView1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.15"
            android:background="#0000FF" >

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="fill_parent"
            android:orientation="horizontal" >

             <Button
            android:id="@+id/button1"
            android:layout_width="110dp"
            android:layout_height="45dp"
            android:background="#00FF00" />

        </LinearLayout>
    </HorizontalScrollView>

</LinearLayout>

and this is the code:

package com.example.test;

import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.Menu;
import android.view.MotionEvent;
import android.webkit.WebView;
import android.widget.Toast;

public class MainActivity extends Activity {

int currentPage = 2; // page number for current html file

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //get a pointer to the webview
    MyWebView webview = (MyWebView) findViewById(R.id.webView1);

    webview.getSettings().setUseWideViewPort(true); 
    webview.getSettings().setSupportZoom(true);
    webview.getSettings().setBuiltInZoomControls(true);

    // put html page in the webView
    webview.loadUrl("file:///android_asset/chapter" + currentPage + ".html");
}

public void changePage(int page) {

    Log.v("test", "change page to " + page);

    //get a pointer to the webview
    MyWebView webview = (MyWebView)findViewById(R.id.webView1);

    // put html page in the webView
    webview.loadUrl("file:///android_asset/chapter" + page + ".html");

    }

class MyWebView extends WebView {
     Context context;
     GestureDetector gd;

    public MyWebView(Context context, AttributeSet attrs) {
    super(context, attrs);

    this.context = context;
         gd = new GestureDetector(context, sogl);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return (gd.onTouchEvent(event) 
                || super.onTouchEvent(event));
    }

     GestureDetector.SimpleOnGestureListener sogl = new GestureDetector.SimpleOnGestureListener() {
      public boolean onDown(MotionEvent event) {
       return false;
      }
      public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) {
       if (event1.getRawX() > event2.getRawX() && StrictMath.abs(event1.getRawY()-event2.getRawY())<100) {
        show_toast("swipe left");
        currentPage += 1;
        if (currentPage >= 19) currentPage = 19;
        changePage(currentPage);
       } else if(event1.getRawX() < event2.getRawX() && StrictMath.abs(event1.getRawY()-event2.getRawY())<100){
        show_toast("swipe right");
        currentPage -= 1;
        if (currentPage <= 1) currentPage = 1;
        changePage(currentPage);
       } else {
         return false;
       }
    return true;
      }
     };

     void show_toast(final String text) {
      Toast t = Toast.makeText(context, text, Toast.LENGTH_SHORT);
      t.show();
     }
    }
}

The actual error reads:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.test/com.example.test.MainActivity}: android.view.InflateException: Binary XML file line #15: Error inflating class com.example.test.MyWebView

Thanks in advance for your help. Much appreciated.

Mr. Jigs

As requested the full error trace:

01-23 10:21:51.980: E/AndroidRuntime(29514): FATAL EXCEPTION: main
01-23 10:21:51.980: E/AndroidRuntime(29514): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.test/com.example.test.MainActivity}: android.view.InflateException: Binary XML file line #15: Error inflating class com.example.test.MyWebView
01-23 10:21:51.980: E/AndroidRuntime(29514):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2100)
01-23 10:21:51.980: E/AndroidRuntime(29514):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2125)
01-23 10:21:51.980: E/AndroidRuntime(29514):    at android.app.ActivityThread.access$600(ActivityThread.java:140)
01-23 10:21:51.980: E/AndroidRuntime(29514):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1227)
01-23 10:21:51.980: E/AndroidRuntime(29514):    at android.os.Handler.dispatchMessage(Handler.java:99)
01-23 10:21:51.980: E/AndroidRuntime(29514):    at android.os.Looper.loop(Looper.java:137)
01-23 10:21:51.980: E/AndroidRuntime(29514):    at android.app.ActivityThread.main(ActivityThread.java:4898)
01-23 10:21:51.980: E/AndroidRuntime(29514):    at java.lang.reflect.Method.invokeNative(Native Method)
01-23 10:21:51.980: E/AndroidRuntime(29514):    at java.lang.reflect.Method.invoke(Method.java:511)
01-23 10:21:51.980: E/AndroidRuntime(29514):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
01-23 10:21:51.980: E/AndroidRuntime(29514):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
01-23 10:21:51.980: E/AndroidRuntime(29514):    at dalvik.system.NativeStart.main(Native Method)
01-23 10:21:51.980: E/AndroidRuntime(29514): Caused by: android.view.InflateException: Binary XML file line #15: Error inflating class com.example.test.MyWebView
01-23 10:21:51.980: E/AndroidRuntime(29514):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:698)
01-23 10:21:51.980: E/AndroidRuntime(29514):    at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
01-23 10:21:51.980: E/AndroidRuntime(29514):    at android.view.LayoutInflater.rInflate(LayoutInflater.java:749)
01-23 10:21:51.980: E/AndroidRuntime(29514):    at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
01-23 10:21:51.980: E/AndroidRuntime(29514):    at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
01-23 10:21:51.980: E/AndroidRuntime(29514):    at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
01-23 10:21:51.980: E/AndroidRuntime(29514):    at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:308)
01-23 10:21:51.980: E/AndroidRuntime(29514):    at android.app.Activity.setContentView(Activity.java:1924)
01-23 10:21:51.980: E/AndroidRuntime(29514):    at com.example.test.MainActivity.onCreate(MainActivity.java:21)
01-23 10:21:51.980: E/AndroidRuntime(29514):    at android.app.Activity.performCreate(Activity.java:5206)
01-23 10:21:51.980: E/AndroidRuntime(29514):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1083)
01-23 10:21:51.980: E/AndroidRuntime(29514):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2064)
01-23 10:21:51.980: E/AndroidRuntime(29514):    ... 11 more
01-23 10:21:51.980: E/AndroidRuntime(29514): Caused by: java.lang.ClassNotFoundException: com.example.test.MyWebView
01-23 10:21:51.980: E/AndroidRuntime(29514):    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
01-23 10:21:51.980: E/AndroidRuntime(29514):    at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
01-23 10:21:51.980: E/AndroidRuntime(29514):    at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
01-23 10:21:51.980: E/AndroidRuntime(29514):    at android.view.LayoutInflater.createView(LayoutInflater.java:552)
01-23 10:21:51.980: E/AndroidRuntime(29514):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:687)
01-23 10:21:51.980: E/AndroidRuntime(29514):    ... 22 more
Était-ce utile?

La solution 2

MyWebView class is internal of MainActivity class. Inflater does not see this class. Make your WebView in defferent .java file.

Also you can try to use that name in your layout file <com.example.test.MainActivity.MyWebView/>, but i'm not sure about it.

Autres conseils

Make sure you add all these constructors in your custom webview class.

    public CustomWebView(Context context) {
        super(context);
    }

    public CustomWebView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomWebView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public CustomWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

And also don't forget to use this CustomWebView class in xml layout file with your complete package name.

 <com.kittykitty.meowmeow.CustomWebView
                android:id="@+id/my_webview"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                />
// try this way
1. Custom WebView Class
public class MyWebView extends WebView {
    Context context;
    GestureDetector gd;
    OnPageChangleListener listener;
    private int currentPage=1;
    private int startPageIndex;
    private int lastPageIndex;

    public MyWebView(Context context) {
        super(context);
       init(context);
    }

    public MyWebView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public MyWebView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    private void init(Context context){
        this.context = context;
        gd = new GestureDetector(context, sogl);
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return (gd.onTouchEvent(event)
                || super.onTouchEvent(event));
    }

    public void setOnPageChangeListener(OnPageChangleListener listener){
        this.listener = listener;
    }

    public void setStartPageIndex(int startPageIndex){
        this.startPageIndex = startPageIndex;
    }

    public int getStartPageIndex(){
        currentPage = startPageIndex;
        return startPageIndex;
    }

    public int getLastPageIndex(){
        return lastPageIndex;
    }

    public void setLastPageIndex(int lastPageIndex){
        this.lastPageIndex = lastPageIndex;
    }
    GestureDetector.SimpleOnGestureListener sogl = new GestureDetector.SimpleOnGestureListener() {
        public boolean onDown(MotionEvent event) {
            return false;
        }
        public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) {
            if (event1.getRawX() > event2.getRawX() && StrictMath.abs(event1.getRawY()-event2.getRawY())<100) {
                currentPage += 1;
                if (currentPage > lastPageIndex){
                    currentPage = lastPageIndex;
                    show_toast("Last Page");
                }else{
                    show_toast("swipe left");
                    listener.onPageChange(currentPage);
                }
            } else if(event1.getRawX() < event2.getRawX() && StrictMath.abs(event1.getRawY()-event2.getRawY())<100){
                currentPage -= 1;
                if (currentPage < startPageIndex) {
                    currentPage = startPageIndex;
                    show_toast("First Page");
                }else{
                    show_toast("swipe right");
                    listener.onPageChange(currentPage);
                }
            } else {
                return false;
            }
            return true;
        }
    };

    void show_toast(final String text) {
        Toast t = Toast.makeText(context, text, Toast.LENGTH_SHORT);
        t.show();
    }

}

2. Custom Interface for you Custom WebView page change listener.
public interface OnPageChangleListener {
    public void onPageChange(int pageNo);
}

3. Use Custom WebView in your Activity.
 MyWebView myWebView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        myWebView = (MyWebView) findViewById(R.id.myWebView);
        myWebView.getSettings().setUseWideViewPort(true);
        myWebView.getSettings().setSupportZoom(true);
        myWebView.getSettings().setBuiltInZoomControls(true);
        myWebView.setStartPageIndex(2);
        myWebView.setLastPageIndex(4);
        myWebView.setOnPageChangeListener(new OnPageChangleListener() {
            @Override
            public void onPageChange(int pageNo) {
                System.out.println(String.valueOf(pageNo));
                myWebView.loadUrl("file:///android_asset/" + pageNo + ".html");
            }
        });

        myWebView.loadUrl("file:///android_asset/" + myWebView.getStartPageIndex() + ".html");

}
4.main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <com.example.Demo.MyWebView
        android:id="@+id/myWebView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top