3

EDIT: tl;dr: WebView appears as white box, even though I appear to be setting it up correctly, and indeed it does work the first two times, but fails subsequently)

EDIT: Video showing the problem in action...

I have the following bit of code which inflates a view (Which contains a WebView) from the xml which defines it:

private void createCard(ViewGroup cvFrame, Card card) {

    //... setup vairables...

    cvFrame.clearDisappearingChildren();
    cvFrame.clearAnimation();


    try {
        View cv = LayoutInflater.from(getBaseContext()).inflate(R.layout.card_back_view,
                cvFrame, true);
        cv.setBackgroundDrawable(Drawable.createFromStream(mngr.open(deckName + "_Card_back.png"), deckName));

        TextView suit = (TextView)cv.findViewWithTag("card_back_suit");
        //...setup text view for suit, this code works fine every time...

        WebView title = (WebView)cv.findViewWithTag("card_back_title");
        //This WebView doesn't appear to be the one which actually appears on screen (I can change settings till I'm blue in the face, with no effect)
        if (title != null) {
            title.setBackgroundColor(0x00000000);
            title.loadData(titleText, "text/html", "UTF-8");
        } else {
            Log.e("CardView", "Error can't find title WebView");
        }
    } catch (IOException e) {
        Log.e("CardView", "Error making cards: ", e);
    }
}

When this method is called as part of the onCreate method in my Activity, the WebView contains the correct code, and is suitably transparent.

I have a gesture listener which replaces the contents of the ViewGroup with different content (It animates the top card off to the left, replaces the contents of the top card with card 2, puts the top card back, then replaces card 2 with card 3)

//Gesture listener event
ViewGroup cvFrame = (ViewGroup)findViewById(R.id.firstCard);
cardLoc++
cvFrame.startAnimation(slideLeft);

(onAnimationEnd code)

public void onAnimationEnd(Animation animation) {
    if (animation == slideLeft) {
        ViewGroup cvFrameOldFront = (ViewGroup)findViewById(R.id.firstCard);
        ViewGroup cvFrameNewFront = (ViewGroup)findViewById(R.id.secondCard);

        createCard(cvFrameOldFront, cards.get((cardLoc)%cards.size()));
        createCard(cvFrameNewFront, cards.get((cardLoc+1)%cards.size()));

        TranslateAnimation slideBack = new TranslateAnimation(0,0,0,0);
        slideBack.setDuration(1);
        slideBack.setFillAfter(true);
        cvFrameOldFront.startAnimation(slideBack);

    } 
}

When the animation has happened and I replace the contents of the cards, the TextView suit is replaced fine and the code definitely passes through the code to replace the WebView contents, but for some reason I end up with a white rectangle the size and shape of the WebView, no content, no transparency.

If I change the WebView to a TextView, it's contents is replaced fine, so it's an issue that occurs only with the WebView control :S

Can anyone tell me why / suggest a fix?

Matt Fellows
  • 6,512
  • 4
  • 35
  • 57
  • what is in titleText? I am assuming its html code. – JoxTraex Feb 25 '13 at 08:31
  • It is just simple html fragments - it just needs to be rich text capable, so bold, italics etc. – Matt Fellows Feb 25 '13 at 08:38
  • If you just need to use simple tags, why not use just a `TextView` with HTML like this: `textView.setText(Html.fromHtml("Title")`? Check [this article](http://commonsware.com/blog/Android/2010/05/26/html-tags-supported-by-textview.html) for the list of HTML tags supported by TextView. – Dheeraj Vepakomma Feb 25 '13 at 09:17
  • Can a TextView be scrollable? If so then that looks like a good idea anyway (Although I've managed to solve my issue now, this still looks like a better plan) – Matt Fellows Feb 25 '13 at 09:19
  • Sure, just wrap it in a `ScrollView`. – Dheeraj Vepakomma Feb 25 '13 at 09:21
  • Did you 'removeAllsViews' from this viewgroup before to call 'createCard' ? – Guian Mar 03 '13 at 10:29

4 Answers4

3

It turns out the WebView doesn't get cleared down when using the LayoutInflater to replace the contents of a ViewGroup. The other controls all seem to get removed (or at least the findViewWithTag() returns the right reference for every other control). I've just added in the line cvFrame.removeAllViews() immediately before the LayoutInflater does it's stuff and that fixed the issue. If anyone has any better explanation for this I'll throw the points their way otherwise they will just go into the ether...

Matt Fellows
  • 6,512
  • 4
  • 35
  • 57
1

I had a similar problem loading several WebViews content. It was because of a misusing of the pauseTimers function

The situation was : the first webView weren't needed anymore, conscientiously I wanted to pause it before to release it. Calling onPause() and pauseTimers()

pauseTimers being common to any web views, it broke every use of webviews occuring after that, there were displaying only white rectangles.

Maybe its not your problem here, but it's worth checking your not calling WebView.pauseTimers() somewhere.

Guian
  • 4,563
  • 4
  • 34
  • 54
1

By calling findViewById, you are getting a reference on the previously loaded webview do you ?

so the loadData call that fails is the second one you make on a single webview instance.

you may want to check this : Android WebView - 1st LoadData() works fine, subsequent calls do not update display

It appears that loadData() won't load data twice... you may want to try WebView.loadDataWithBaseUri()

Hope that helps.

Community
  • 1
  • 1
Guian
  • 4,563
  • 4
  • 34
  • 54
  • hmm that doesn't seem to be the case, since your inflate call should create new views in your 'cvFrame' viewGroup. Did you 'removeAllsViews' from this viewgroup before to call 'createCard' ? – Guian Feb 28 '13 at 14:05
1

To confirm your answer, the source code for LayoutInflater.inflate(int resource, ViewGroup root, boolean attachToRoot) does in fact internally calls root.addView() which attaches the newly inflated view at the end of the root's children instead of replacing them.

So the mystery now is why did your call to findViewWithTag() is returning the expected objects for your other widgets (which would be the top, most recently created instances), but for your WebView it was returning something else.

Is it possible that there is another object in your layout XML which shares the same "card_back_title" tag?

I was also wondering why you didn't use the more common findViewById() instead, but I am not sure whether it would make a difference.

Joe
  • 14,039
  • 2
  • 39
  • 49
  • I have multiple instances of the same view. I guess I wasn't certain if multiple sub-views could share the same Id if they had different parent views? So I went with tags instead (I guess I'm thinking of tags like classes in HTML and Ids like Ids, not sure if that's valid or not) – Matt Fellows Mar 04 '13 at 09:52