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

标签 android webview fragmentstatepageradapter

我正在研究带标签的滑动 View 。 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;
    }       
}

由于我正在进行的项目需要加载静态网页而不是文本。我将 TextView 替换为 WebView,以便在每次滑动时加载不同的网页。这非常好。来自 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;
    }       
} 

最佳答案

我可能是错的,但听起来您没有在 UIThread 上更新。

你可以尝试这样的事情。

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

关于android - 带有 FragmentStatePagerAdapter 的 WebView 在调用 setCurrentItem 时变为空白,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24505042/

相关文章:

android - Kotlin 懒惰使用

android - 如何对 Android 应用程序选项菜单中的菜单项进行排序?

ios - 是否可以在 Cordova 应用程序中将静态图像放在 webview 的顶部

android - 跳转到 FragmentStatePagerAdapter 中任意 fragment 上的下一个 fragment

android - ViewPager 中 Fragment 之间的通信

java - AlarmManager 重置显示错误 在 onCreate() 之前系统服务不可用于 Activity

android - 如何在 Flutter 中让 Android 状态栏变亮

android - 在android中的recyclerview中添加预加载 View

android - 如何在 Android 中播放 HLS 视频?

java - 当用户到达 ViewPager 的末尾时,如何动态地将 fragment 添加到 ViewPager 的开头?