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