【问题标题】:How do you keep the fragment webview from reloading every time?你如何防止片段 webview 每次都重新加载?
【发布时间】:2017-05-09 01:47:32
【问题描述】:

我是 Android 应用开发新手,需要一些帮助。我注意到当我尝试使用导航选项卡尝试我的片段WebView 时,它们的状态保持良好,但是当我切换到使用导航抽屉时,每次我单击抽屉项目,然后通过单击抽屉项目返回那个我已经加载,它只是重新加载WebView

MainActivity 代码:

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {

    NavigationView navigationView = null;
    Toolbar toolbar = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Set the fragment initially
        MainFragment fragment = new MainFragment();
        android.support.v4.app.FragmentTransaction fragmentTransaction =
                getSupportFragmentManager().beginTransaction();
        fragmentTransaction.replace(R.id.fragment_container, fragment);
        fragmentTransaction.commit();

        toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);


        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);

        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.addDrawerListener(toggle);
        toggle.syncState();

        navigationView = (NavigationView) findViewById(R.id.nav_view);

        //How to change elements in the header programatically
        View headerView = navigationView.getHeaderView(0);

        navigationView.setNavigationItemSelectedListener(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement


        return super.onOptionsItemSelected(item);
    }

    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();

        if (id == R.id.nav_home) {
            //Set the fragment initially
            MainFragment fragment = new MainFragment();
            android.support.v4.app.FragmentTransaction fragmentTransaction =
                    getSupportFragmentManager().beginTransaction();
            fragmentTransaction.replace(R.id.fragment_container, fragment);
            fragmentTransaction.commit();
            // Handle the camera action
        } else if (id == R.id.nav_store) {
            //Set the fragment initially
            MyStoreFragment fragment = new MyStoreFragment();
            android.support.v4.app.FragmentTransaction fragmentTransaction =
                    getSupportFragmentManager().beginTransaction();
            fragmentTransaction.replace(R.id.fragment_container, fragment);
            fragmentTransaction.commit();

        } else if (id == R.id.nav_blog) {
            //Set the fragment initially
            BlogFragment fragment = new BlogFragment();
            android.support.v4.app.FragmentTransaction fragmentTransaction =
                    getSupportFragmentManager().beginTransaction();
            fragmentTransaction.replace(R.id.fragment_container, fragment);
            fragmentTransaction.commit();

        } else if (id == R.id.nav_billing) {
            //Set the fragment initially
            MyBillingFragment fragment = new MyBillingFragment();
            android.support.v4.app.FragmentTransaction fragmentTransaction =
                    getSupportFragmentManager().beginTransaction();
            fragmentTransaction.replace(R.id.fragment_container, fragment);
            fragmentTransaction.commit();

        } else if (id == R.id.nav_data) {
            //Set the fragment initially
            MyDataFragment fragment = new MyDataFragment();
            android.support.v4.app.FragmentTransaction fragmentTransaction =
                    getSupportFragmentManager().beginTransaction();
            fragmentTransaction.replace(R.id.fragment_container, fragment);
            fragmentTransaction.commit();
        }

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }


}

MainFragment(我还有其他设置相同的片段):

public class MainFragment extends Fragment {


    public MainFragment() {
        // Required empty public constructor
    }

    private static ProgressBar progressBar;
    private static WebView webView;
    private static View v;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        super.onCreate(savedInstanceState);
        v = inflater.inflate(R.layout.fragment_main, container, false);
        progressBar = (ProgressBar) v.findViewById(R.id.progressBar);
        progressBar.setMax(100);
        webView = (WebView) v.findViewById(R.id.webView);

        if(savedInstanceState != null){
            webView.restoreState(savedInstanceState);
        }else{
            webView.getSettings().setJavaScriptEnabled(true);
            webView.getSettings().setSupportZoom(false);
            webView.getSettings().setBuiltInZoomControls(false);
            webView.getSettings().setLoadWithOverviewMode(true);
            webView.getSettings().setUseWideViewPort(true);
            webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
            webView.setBackgroundColor(Color.WHITE);

            webView.setWebViewClient(new ourViewClient());

            webView.setWebChromeClient(new WebChromeClient(){
                public void onProgressChanged(WebView view, int progress){
                    progressBar.setProgress(progress);
                    if(progress < 100 && progressBar.getVisibility() == ProgressBar.GONE){
                        progressBar.setVisibility(ProgressBar.VISIBLE);
                        webView.setVisibility(View.GONE);
                    }

                    if(progress == 100){
                        progressBar.setVisibility(ProgressBar.GONE);
                        webView.setVisibility(View.VISIBLE);
                    }
                }
            });

            webView.setOnKeyListener(new OnKeyListener(){
                @Override
                public boolean onKey(View v, int keyCode, KeyEvent event)
                {
                    if(event.getAction() == KeyEvent.ACTION_DOWN)
                    {
                        WebView webView = (WebView) v;

                        switch(keyCode)
                        {
                            case KeyEvent.KEYCODE_BACK:
                                if(webView.canGoBack())
                                {
                                    webView.goBack();
                                    return true;
                                }
                                break;
                        }
                    }

                    return false;
                }
            });

            String data = getActivity().getIntent().getDataString();

            if(Intent.ACTION_VIEW.equals(getActivity().getIntent().getAction())){
                webView.loadUrl(data);
            }else{
                webView.loadUrl("https://someurl");
            }

        }

        return v;
    }

    public class ourViewClient extends WebViewClient {
        @Override
        public void onPageFinished(WebView view, String url){
            super.onPageFinished(view, url);
            view.setVisibility(View.VISIBLE);
            view.bringToFront();
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon){
            view.setVisibility(View.GONE);

        }

    }



    @Override
    public void onSaveInstanceState(Bundle outState){
        super.onSaveInstanceState(outState);
        webView.saveState(outState);
    }



}   

【问题讨论】:

    标签: android android-fragments android-webview


    【解决方案1】:

    这样做

     final   HashMap<String,Fragment> fragment_container = new HashMap<>();
        @SuppressWarnings("StatementWithEmptyBody")
        @Override
        public boolean onNavigationItemSelected(MenuItem item) {
            // Handle navigation view item clicks here.
            int id = item.getItemId();
    
            if (id == R.id.nav_home) {
                //Set the fragment initially
                MainFragment fragment =fragment_container.get("home");
                if(fragment == null){
                    fragment = new MainFragment();
                    fragment_container.put("home",fragment);
                }
                android.support.v4.app.FragmentTransaction fragmentTransaction =
                        getSupportFragmentManager().beginTransaction();
                fragmentTransaction.replace(R.id.fragment_container, fragment);
                fragmentTransaction.commit();
                // Handle the camera action
            } else if (id == R.id.nav_store) {
                //Set the fragment initially
                MyStoreFragment fragment =fragment_container.get("store");
                if(fragment == null){
                    fragment = new MyStoreFragment();
                    fragment_container.put("store",fragment);
                }
                android.support.v4.app.FragmentTransaction fragmentTransaction =
                        getSupportFragmentManager().beginTransaction();
                fragmentTransaction.replace(R.id.fragment_container, fragment);
                fragmentTransaction.commit();
    
            } else if (id == R.id.nav_blog) {
                //Set the fragment initially
    
                BlogFragment fragment =fragment_container.get("blog");
                if(fragment == null){
                    fragment = new BlogFragment();
                    fragment_container.put("blog",fragment);
                }
                android.support.v4.app.FragmentTransaction fragmentTransaction =
                        getSupportFragmentManager().beginTransaction();
                fragmentTransaction.replace(R.id.fragment_container, fragment);
                fragmentTransaction.commit();
    
            } else if (id == R.id.nav_billing) {
                //Set the fragment initially
                MyBillingFragment fragment = new MyBillingFragment();//finish it yourself like above
                android.support.v4.app.FragmentTransaction fragmentTransaction =
                        getSupportFragmentManager().beginTransaction();
                fragmentTransaction.replace(R.id.fragment_container, fragment);
                fragmentTransaction.commit();
    
            } else if (id == R.id.nav_data) {
                //Set the fragment initially
                MyDataFragment fragment = new MyDataFragment();//finish it yourself like above
                android.support.v4.app.FragmentTransaction fragmentTransaction =
                        getSupportFragmentManager().beginTransaction();
                fragmentTransaction.replace(R.id.fragment_container, fragment);
                fragmentTransaction.commit();
            }
    
            DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
            drawer.closeDrawer(GravityCompat.START);
            return true;
        }
    

    并使用非静态实例缓存您的视图

      private  ProgressBar progressBar;
        private  WebView webView;
        private  View v;
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            super.onCreate(savedInstanceState);
            if(v == null) {
                v = inflater.inflate(R.layout.fragment_main, container, false);
                progressBar = (ProgressBar) v.findViewById(R.id.progressBar);
                progressBar.setMax(100);
                webView = (WebView) v.findViewById(R.id.webView);
    
                if (savedInstanceState != null) {
                    webView.restoreState(savedInstanceState);
                } else {
                    webView.getSettings().setJavaScriptEnabled(true);
                    webView.getSettings().setSupportZoom(false);
                    webView.getSettings().setBuiltInZoomControls(false);
                    webView.getSettings().setLoadWithOverviewMode(true);
                    webView.getSettings().setUseWideViewPort(true);
                    webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
                    webView.setBackgroundColor(Color.WHITE);
    
                    webView.setWebViewClient(new ourViewClient());
    
                    webView.setWebChromeClient(new WebChromeClient() {
                        public void onProgressChanged(WebView view, int progress) {
                            progressBar.setProgress(progress);
                            if (progress < 100 && progressBar.getVisibility() == ProgressBar.GONE) {
                                progressBar.setVisibility(ProgressBar.VISIBLE);
                                webView.setVisibility(View.GONE);
                            }
    
                            if (progress == 100) {
                                progressBar.setVisibility(ProgressBar.GONE);
                                webView.setVisibility(View.VISIBLE);
                            }
                        }
                    });
    
                    webView.setOnKeyListener(new OnKeyListener() {
                        @Override
                        public boolean onKey(View v, int keyCode, KeyEvent event) {
                            if (event.getAction() == KeyEvent.ACTION_DOWN) {
                                WebView webView = (WebView) v;
    
                                switch (keyCode) {
                                    case KeyEvent.KEYCODE_BACK:
                                        if (webView.canGoBack()) {
                                            webView.goBack();
                                            return true;
                                        }
                                        break;
                                }
                            }
    
                            return false;
                        }
                    });
    
                    String data = getActivity().getIntent().getDataString();
    
                    if (Intent.ACTION_VIEW.equals(getActivity().getIntent().getAction())) {
                        webView.loadUrl(data);
                    } else {
                        webView.loadUrl("https://someurl");
                    }
    
                }
            }
    
            return v;
        }
    

    【讨论】:

    • 我收到不兼容类型错误:MainFragment fragment = fragment_container.get("home"); MyStoreFragment 片段 = fragment_container.get("store");和 BlogFragment 片段 = fragment_container.get("blog");
    • final HashMap fragment_container = new HashMap();更改 Fragment 以支持 Fragment。
    【解决方案2】:

    如果你使用 viewpager

    在 viewpager 声明之后像这行:

    ViewPager viewpager = (ViewPager) findViewById(R.id.pager);
    

    添加这一行:

    viewpager.setOffscreenPageLimit(2);
    

    这将防止您的片段重新创建以滑动两个屏幕,因此当您在 viewpager 中从第 3 页返回到第 1 页时,您的 webview 将不会重新加载。

    感谢:https://stackoverflow.com/a/16456455/3380537

    【讨论】:

      【解决方案3】:

      您可以允许 Activity 自行处理配置更改。您可以通过将 android:configChanges 属性添加到您的活动来做到这一点。

      【讨论】:

      • 这是一个很好的补充,但我正在寻找在加载 web 视图后单击导航抽屉链接时实际保存状态。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-16
      • 2015-12-05
      • 2020-06-06
      • 2015-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多