I am new to Android App Development and need some assistance. I notice when I tried my fragment WebView
with navigation tabs they hold their state fine, but when I switched to using Navigation Drawers, every time I click on a drawer item, and go back to the one by clicking on the drawer item I loaded already, it just reloads the WebView
.
MainActivity code:
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 (I have other fragments that have the same setup):
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);
}
}
Do like this
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;
}
And cache your views use non-static instance
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;
}
If you use viewpager
after the declaration of viewpager like this line :
ViewPager viewpager = (ViewPager) findViewById(R.id.pager);
add this line :
viewpager.setOffscreenPageLimit(2);
This will prevent your fragment from recreated upto swipe of two screens,so when you will return from 3rd page to 1st page in viewpager,your webview will not reload.
credit to : https://stackoverflow.com/a/16456455/3380537
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With