2

In my app I have a navigation drawer with different options for different websites. These are coded in strings:

<string name="title_section1">Google</string>
<string name="title_section2">Stackoverflow</string>
<string name="title_section3">Twitter</string>
<string name="title_section4">Facebook</string>

I also - obviously - have a webview in place in a file called activity_app.xml:

<WebView  xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/main_webview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    />

When the app opens this webview defaults to a dutch news site called Nu.nl:

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

    mNavigationDrawerFragment = (NavigationDrawerFragment)
            getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
    mTitle = getTitle();

    WebView myWebView = (WebView) findViewById(R.id.main_webview);
    String pageUrl = "http://www.nu.nl";
    myWebView.getSettings().setJavaScriptEnabled(true);
    myWebView.loadUrl(pageUrl);
    myWebView.setWebViewClient(new WebViewClient());

    // Set up the drawer.
    mNavigationDrawerFragment.setUp(
        R.id.navigation_drawer,
        (DrawerLayout) findViewById(R.id.drawer_layout));
}

Now, ideally if I click on 'Google' for example, I want the webview to change to google.com. I started building the code for this but got stuck. My app keeps on crashing and I think it has something to do with findViewById.

@Override
public void onNavigationDrawerItemSelected(int position) {
    // update the main content by replacing fragments
    //FragmentManager fragmentManager = getSupportFragmentManager();
    //fragmentManager.beginTransaction()
            //.replace(R.id.container, PlaceholderFragment.newInstance(position + 1))
            //.commit();
    int id = position.getId ();
    if (id == 'title_section1') {
        String pageUrl = "http://www.google.com";
    } else if (id == 'title_section2') {
        String pageUrl = "http://www.stackoverflow.com";
    } else if (id == 'title_section3') {
        String pageUrl = "http://twitter.com";
    } else if (id == 'title_section4') {
        String pageUrl = "http://facebook.com";
    }
}

What do I need to add or change to my code to make it redirect to the actual URL? I should note that this is my first android app after 5 years PHP experience.

EDIT: I added the log of the crash. It states that the mistake is in the xml/layout files, but the error appears when I add findViewById to the file, so I think that is what must be causing it.

06-21 23:13:20.580  19172-19172/test.webviewdrawer E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: test.webviewdrawer, PID: 19172
java.lang.RuntimeException: Unable to start activity ComponentInfo{test.webviewdrawer/test.webviewdrawer.login}: android.view.InflateException: Binary XML file line #31: Error inflating class fragment
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2596)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2653)
        at android.app.ActivityThread.access$800(ActivityThread.java:156)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1355)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:157)
        at android.app.ActivityThread.main(ActivityThread.java:5872)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:852)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:668)
        at dalvik.system.NativeStart.main(Native Method)
 Caused by: android.view.InflateException: Binary XML file line #31: Error inflating class fragment
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:713)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
        at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:375)
        at android.app.Activity.setContentView(Activity.java:1997)
        at android.support.v7.app.ActionBarActivity.superSetContentView(ActionBarActivity.java:216)
        at android.support.v7.app.ActionBarActivityDelegateICS.setContentView(ActionBarActivityDelegateICS.java:110)
        at android.support.v7.app.ActionBarActivity.setContentView(ActionBarActivity.java:76)
        at test.webviewdrawer.login.onCreate(login.java:48)
        at android.app.Activity.performCreate(Activity.java:5312)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1111)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2552)

UPDATE 2: Might be of importance that the method onNavigationDrawerItemSelected() in the main.java file gets called from a fragment.java file...

private void selectItem(int position) {
    mCurrentSelectedPosition = position;
    if (mDrawerListView != null) {
        mDrawerListView.setItemChecked(position, true);
    }
    if (mDrawerLayout != null) {
        mDrawerLayout.closeDrawer(mFragmentContainerView);
    }
    if (mCallbacks != null) {
        mCallbacks.onNavigationDrawerItemSelected(position);
    }
}
user3740505
  • 141
  • 3
  • 13
  • Please add your logcat/stacktrace of the crash to your Question so we can see where things blow up on you. (Also indicate what line(s) of code are being referenced in the stacktrace in your above code) – indivisible Jun 21 '14 at 21:08
  • I added it in the question. – user3740505 Jun 21 '14 at 21:19
  • I think your issue is that you are trying to use a View that is in your Fragment's layout from your Activity. [Look at this Question](http://stackoverflow.com/questions/23653778/nullpointerexception-accessing-views-in-oncreate) and see if you can get it sorted. Come back and let me know how you got on so we can either keep troubleshooting or mark this as a duplicate of that. – indivisible Jun 21 '14 at 21:22
  • I think it's the other way around - if that's even possible. The navigation drawer is a fragment and the webview is in the activity. The fragment calls the method. Again, I don't know if it makes any sense what I'm saying.. – user3740505 Jun 21 '14 at 21:26
  • I added it to the question. – user3740505 Jun 21 '14 at 21:31
  • With all the to-and-fro you should probably be using callbacks and interfaces to communicate between your Activity/Fragments and to expose any Views you want to access directly from the other. [Here is a link to a previous answer of mine](http://stackoverflow.com/a/23998072/1590950) that explains how to implement such a thing. If you need anything explained we should probably move over to chat. – indivisible Jun 21 '14 at 21:36
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/56040/discussion-between-indivisible-and-user3740505). – indivisible Jun 21 '14 at 21:41
  • Thanks for the help so far. It's currently midnight over here, so I'm going to start fresh in the morning. I'll see if that question can help me. – user3740505 Jun 21 '14 at 21:41
  • Ok, take care and good luck – indivisible Jun 21 '14 at 21:43
  • I added some more information in the chat, if you're still willing to help please take a look at it. – user3740505 Jun 22 '14 at 09:26

1 Answers1

2

Myself and the OP debugged this in chat and through Github and I really should have come back before now to put the solution here as an answer and so here it is...

The issue you were having is one of variable scope. You defined your WebView and your pageUrls with method and block scope respectively. This meant that when you went to make use of them later they didn't exist any more.


The fix was to move the declarations to the class level and keep the assignments where they were previously declared.

public class MyActivity extends Activity
{
    private WebView myWebView;
    private String pageUrl;

    @Override
    public void onCreate(...)
    {
        ...
        myWebView = (WebView) findViewById(R.id.main_webview);
        pageUrl = "http://nu.nl";  // default page
        ...
    }

    ....
    @Override
    public void onNavigationDrawerItemSelected(int position) {
        switch (position)
        {
            case 0:
                pageUrl = "http://www.google.com";
                break;
            case 1:
                pageUrl = "http://www.stackoverflow.com";
                break;
            case 2:
                pageUrl = "http://twitter.com";
                break;
            case 3:
                pageUrl = "http://facebook.com";
                break;
            default:
                Log.e(TAG, "Unhandled navigation selection: " + position);
                break;
        }
        // preformed asynchronously but this here just for demonstrative purposes
        webView.loadUrl(pageUrl);
    }
    ...
}

The way we ended up solving it actually differs from what's above as there were better design decisions to be made but this solution fixes the stated Question. If anyone's interested it's on this Github repo

indivisible
  • 4,892
  • 4
  • 31
  • 50