使用FragmentStatePagerAdapter的WebView在调用setCurrentItem后变空白

3
我正在使用选项卡和滑动视图。在创建带有选项卡的滑动视图页面提供的"EffectiveNavigation"项目中提供的代码为一个很好的起点。进行了更多的实验后,我给给定的TextView添加了OnClickListener,并在onClick方法中添加了setCurrentItem。这便如预期一样运作,ViewPager跳转到所需页面。
/**
 * A dummy fragment representing a section of the app, but that simply displays dummy text.
 */
public static class DemoObjectFragment extends Fragment {

    public static final String ARG_OBJECT = "object";

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_collection_object, container, false);
        Bundle args = getArguments();
        ((TextView) rootView.findViewById(android.R.id.text1)).setText(
                Integer.toString(args.getInt(ARG_OBJECT)));

        ((TextView) rootView.findViewById(android.R.id.text1)).setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
              /*
               *setCurrentPagerItem(5); -> omitted here to reduce complexity              
              */
              mViewPager.setCurrentItem(5); 
            }
        });
        return rootView;
    }       
}

作为我正在处理的项目需要加载静态网页而不是文本。我用WebView替换了TextView以在每次滑动时加载不同的网页。这个非常完美地工作。来自HTML侧的点击事件由我实现的JavascriptInterface处理。
问题出现在这里。当在JavascriptInterface之外调用setCurrentPagerItem方法时,它完美地工作。当从JavascriptInterface内部调用时,WebView显示一个空白屏幕,并保持不变,直到向右或向左滑动。向右滑动显示比所请求的下一页,向左滑动显示所请求的页。LogCat没有显示任何错误,并且此行为在基于4.3的模拟器和运行4.4.4的Nexus 7上是一致的。我将在下面提供整个代码。
public class CollectionDemoActivity extends FragmentActivity {

/**
 * The {@link android.support.v4.view.PagerAdapter} that will provide fragments representing
 * each object in a collection. We use a {@link android.support.v4.app.FragmentStatePagerAdapter}
 * derivative, which will destroy and re-create fragments as needed, saving and restoring their
 * state in the process. This is important to conserve memory and is a best practice when
 * allowing navigation between objects in a potentially large collection.
 */
DemoCollectionPagerAdapter mDemoCollectionPagerAdapter;   


/**
 * The {@link android.support.v4.view.ViewPager} that will display the object collection.
 */
ViewPager mViewPager;

private static Context context;  

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_collection_demo);

    context = this;

    // Create an adapter that when requested, will return a fragment representing an object in
    // the collection.
    // 
    // ViewPager and its adapters use support library fragments, so we must use
    // getSupportFragmentManager.
    mDemoCollectionPagerAdapter = new DemoCollectionPagerAdapter(getSupportFragmentManager());

    // Set up action bar.
    final ActionBar actionBar = getActionBar();

    // Specify that the Home button should show an "Up" caret, indicating that touching the
    // button will take the user one step up in the application's hierarchy.
    actionBar.setDisplayHomeAsUpEnabled(true);

    final OnPageChangeListener mPageChangeListener = new OnPageChangeListener() {

        @Override
        public void onPageScrollStateChanged(int arg0) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onPageSelected(int pos) {

            final Toast pageNo;
            pageNo = Toast.makeText(context,"PAGE "+(Integer.toString(pos+1))+"/100",Toast.LENGTH_SHORT);
              pageNo.show();
              Handler handler = new Handler();
              handler.postDelayed(new Runnable() {
                 @Override
                 public void run() {
                   pageNo.cancel(); 
                 }
              }, 100);  

        }

    };

    // Set up the ViewPager, attaching the adapter.
    mViewPager = (ViewPager) findViewById(R.id.pager);        
    mViewPager.setAdapter(mDemoCollectionPagerAdapter);
    mViewPager.setOnPageChangeListener(mPageChangeListener);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            // This is called when the Home (Up) button is pressed in the action bar.
            // Create a simple intent that starts the hierarchical parent activity and
            // use NavUtils in the Support Package to ensure proper handling of Up.
            Intent upIntent = new Intent(this, MainActivity.class);
            if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
                // This activity is not part of the application's task, so create a new task
                // with a synthesized back stack.
                TaskStackBuilder.from(this)
                        // If there are ancestor activities, they should be added here.
                        .addNextIntent(upIntent)
                        .startActivities();
                finish();
            } else {
                // This activity is part of the application's task, so simply
                // navigate up to the hierarchical parent activity.
                NavUtils.navigateUpTo(this, upIntent);
            }
            return true;
    }
    return super.onOptionsItemSelected(item);
}

private void setCurrentPagerItem(int item) { 

    mViewPager.setCurrentItem(item);
}


/**
 * A {@link android.support.v4.app.FragmentStatePagerAdapter} that returns a fragment
 * representing an object in the collection.
 */
public static class DemoCollectionPagerAdapter extends FragmentStatePagerAdapter {

    public DemoCollectionPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int i) {
        Fragment fragment = new DemoObjectFragment();
        Bundle args = new Bundle();
        args.putInt(DemoObjectFragment.ARG_OBJECT, i + 1); // Our object is just an integer :-P
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public int getCount() {
        // For this contrived example, we have a 100-object collection.
        return 100;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return "OBJECT " + (position + 1);
    }

}

/**
 * A dummy fragment representing a section of the app, but that simply displays dummy text.
 */
public static class DemoObjectFragment extends Fragment {

    public static final String ARG_OBJECT = "object";

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_collection_object, container, false);
        Bundle args = getArguments();

        final WebView webView = (WebView) rootView.findViewById(R.id.webView);             

        switch(args.getInt(ARG_OBJECT)) {

            case 1   :  
                    webView.loadUrl("file:///android_asset/html/index.html");  
                    break;

            default  :
                    webView.loadUrl("file:///android_asset/html/page_"+(Integer.toString(args.getInt(ARG_OBJECT)-1))+".html");
                    break;              
        }    

        WebSettings ws = webView.getSettings();        
        ws.setJavaScriptEnabled(true);              

        webView.addJavascriptInterface(new Object()
        {

          @JavascriptInterface
          public void toPage(String pageNo) {                 

              ((CollectionDemoActivity) getActivity()).setCurrentPagerItem(4);

          }
        }, "external");

        return rootView;
    }       
} 

}

1个回答

3
我可能说错了,但听起来你没有在UIThread上更新。你可以尝试类似以下的方式。
getActivity().runOnUiThread(new Runnable(){
            @Override
            public void run() {
                ((CollectionDemoActivity) getActivity()).setCurrentPagerItem(4);
            }
        });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接