在调用setCurrentItem时,带有FragmentStatePagerAdapter的WebView变为空白

时间:2014-07-01 07:48:40

标签: android webview fragmentstatepageradapter

我正在使用标签滑动视图。 Creating Swipe Views with Tabs页面的“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端的Click事件由我实现的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 个答案:

答案 0 :(得分:2)

我可能错了,但听起来你没有在UIThread上更新。

你可以尝试这样的事情。

getActivity().runOnUiThread(new Runnable(){
            @Override
            public void run() {
                ((CollectionDemoActivity) getActivity()).setCurrentPagerItem(4);
            }
        });