I've stopped the crashing by making sure notifyDataSetChanged is called in a handler on the main thread. But the current web view doesn't go away. Other pages show up as their supposed to, but the current one is never replaced.
On Mar 9, 5:07 pm, tatebn <[email protected]> wrote: > I'm using a ViewPager with the android support library to load static > html pages into webviews > and flip through them similar to a magazine app. > > I can load the initial page fine, which is using loadContentId(). > When the user clicks on a link I'm calling the same loadContentId() > method. > When I call this, 1 of 2 things happens. > > Either nothing happens at all. The method runs and my log statements > print, but the views > do not redraw/change. Or, the app crashes with the "Only the original > thread that created a view hierarchy > can touch its views." error. > > I can not seem to find a way to do this without the app crashing. How > do I reset the adapter on this ViewPager and > show new views? I've tried invalidating the view pager. I've tried > invalidating the view pager. I've tried using notifyDataSetChanged() > in various places. I've tried using a handler to remove the webView > from the view pager. > > Here is the pertinent code. > > /** > * Loads the internalContentPager with the swipe navigation set > for the given content id. > * @param contentId > */ > public void loadContentId(String contentId){ > //this.internalContentAdapter.loadContentWithId(contentId); > this.currentContentId = contentId; > > Log.i(TAG, "in load content id " + contentId); > > //this.internalContentPager.removeAllViews(); > > if(this.internalContentAdapter == null){ > InternalContentAdapter adapter = new InternalContentAdapter(); > adapter.loadContentWithId(contentId); > this.internalContentAdapter = adapter; > > this.internalContentPager.setAdapter(this.internalContentAdapter); > } > else{ > this.internalContentAdapter.loadContentWithId(contentId); > // > this.internalContentAdapter.startUpdate(this.internalContentPager); > //this.internalContentAdapter.notifyDataSetChanged(); > } > > this.navigationStack.push(contentId); > > } > > /** > * Pager Adapter to handle internal web view pages. This drives > the swipe navigation for the internal content. > * > * @author btate > * > */ > private class InternalContentAdapter extends PagerAdapter{ > > /** The content objects represented by this pager. */ > private List<Content> contents; > > /** The starting position. */ > private int startPosition = 0; > > /** The starting content id. */ > private String startContentId = null; > > /** Flag for whether or not to set the starting position. */ > private boolean setPrimary = true; > > @Override > public int getCount() { > // Send back the contents size > return this.contents.size(); > } > > /** > * Create the page for the given position. The adapter is > responsible > * for adding the view to the container given here, although it > only > * must ensure this is done by the time it returns from > * {@link #finishUpdate()}. > * > * @param container The containing View in which the page will be > shown. > * @param position The page position to be instantiated. > * @return Returns an Object representing the new page. This > does not > * need to be a View, but can be some other container of the > page. > */ > @Override > public Object instantiateItem(ViewGroup container, int > position) { > > // Load up the page > InternalWebView page = new InternalWebView(ctx, repo); > > page.loadInternalPage(this.contents.get(position).getContentId()); > page.setInternalWebViewListener(getListener()); > > //this.parentActivity.registerForContextMenu(page); > > // Need to add this without the position > container.addView(page); > > // I would like this to work, but it doesn't > if(this.startPosition == position){ > Log.i(TAG, "setting primary item with position " + > position); > this.setPrimaryItem(internalContentPager, position, > page); > } > > return page; > } > > /** > * Remove a page for the given position. The adapter is > responsible > * for removing the view from its container, although it only > must ensure > * this is done by the time it returns from {@link > #finishUpdate()}. > * > * @param container The containing View from which the page will > be removed. > * @param position The page position to be removed. > * @param object The same object that was returned by > * {@link #instantiateItem(View, int)}. > */ > @Override > public void destroyItem(View container, int position, Object > view) { > ((ViewPager) container).removeView((InternalWebView) > view); > > /*Message msg = new Message(); > msg.obj = (InternalWebView) view; > mRemovePageHandler.sendMessage(msg);*/ > > } > > @Override > public boolean isViewFromObject(View view, Object object) { > return view==((InternalWebView)object); > } > > /** > * Called when the a change in the shown pages has been > completed. At this > * point you must ensure that all of the pages have actually been > added or > * removed from the container as appropriate. > * @param container The containing View which is displaying this > adapter's > * page views. > */ > @Override > public void finishUpdate(ViewGroup container) { > > if(this.setPrimary) > // Set the current item > > internalContentPager.setCurrentItem(this.startPosition); > > this.setPrimary = false; > > } > > @Override > public void restoreState(Parcelable arg0, ClassLoader arg1) {} > > @Override > public Parcelable saveState() { > return null; > } > > @Override > public void startUpdate(ViewGroup container) { > > } > > /** > * Set the contents for the view pager. > * > * @param contents A List of Content objects to be > loaded. > * @param startPosition The starting position > */ > public void setContents(List<Content> contents, int > startPosition){ > this.setPrimary = true; > > for(Content tmp : contents){ > Log.i(TAG, "in set contents " + > tmp.getContentId() + " has order > in level " + tmp.getOrderInLevel()); > } > > this.contents = contents; > > // This is a temp solution > if(this.startContentId != null){ > for(Content tmp : this.contents){ > Log.i(TAG, "start content " + > startContentId + " this content > " + tmp.getContentId()); > if(this.startContentId != null && > this.startContentId.equals(tmp.getContentId())) > this.startPosition = > this.contents.indexOf(tmp); > } > } > > Log.i(TAG, "notifying data set change"); > this.notifyDataSetChanged(); > > } > > /** > * Loads the view pager with the navigation set for the given > content id. > * @param contentId > */ > public void loadContentWithId(String contentId){ > > // Get the content > Content content = > repo.Contents.getContentById(contentId); > > // Set my starting content > this.startContentId = contentId; > > Log.i(TAG, "Got content in loadcontentwithid " + > content); > > // Set the contents and start position > > this.setContents(repo.Contents.getSwipeNavigationSetForContent(content), > content.getOrderInLevel() - 1); > > } > > /** > * Grabs the currently loaded content. > * @return Content > */ > public Content getCurrentContent(){ > return > this.contents.get(internalContentPager.getCurrentItem()); > } > > /* > @Override > public int getItemPosition(Object object) { > return POSITION_NONE; > }*/ > > } -- You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/android-developers?hl=en

