How to integrate shouldOverrideUrlLoading in my Activity - android

I have 6 tabs and 6 webviews i want to add this
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith("tel:")) {
Intent intent = new Intent(Intent.ACTION_DIAL,
Uri.parse(url));
startActivity(intent);
}else if(url.startsWith("http:") || url.startsWith("https:")) {
view.loadUrl(url);
}
return true;
}
only for tab 6 in my MainActivity.java to handle the tel: links how can i make it work with my code ?
import android.app.ActionBar;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.WebSettings;
public class MainActivity extends FragmentActivity implements
ActionBar.TabListener {
/**
* The {#link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the three primary sections of the app. We use a
* {#link android.support.v4.app.FragmentPagerAdapter} derivative, which
* will keep every loaded fragment in memory. If this becomes too memory
* intensive, it may be best to switch to a
* {#link android.support.v4.app.FragmentStatePagerAdapter}.
*/
CollectionPagerAdapter mCollectionPagerAdapter;
/**
* The {#link android.support.v4.view.ViewPager} that will display the
* object collection.
*/
ViewPager mViewPager;
WebView myWebView;
WebView tab1;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 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.
mCollectionPagerAdapter = new CollectionPagerAdapter(
getSupportFragmentManager());
// Set up action bar.
final ActionBar actionBar = getActionBar();
// Specify that the Home/Up button should not be enabled, since there is
// no hierarchical
// parent.
actionBar.setHomeButtonEnabled(false);
// Specify that we will be displaying tabs in the action bar.
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Set up the ViewPager, attaching the adapter and setting up a listener
// for when the
// user swipes between sections.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setOffscreenPageLimit(6);
mViewPager.setAdapter(mCollectionPagerAdapter);
mViewPager
.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// When swiping between different app sections, select
// the corresponding tab.
// We can also use ActionBar.Tab#select() to do this if
// we have a reference to the
// Tab.
actionBar.setSelectedNavigationItem(position);
}
});
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mCollectionPagerAdapter.getCount(); i++) {
// Create a tab with text corresponding to the page title defined by
// the adapter.
// Also specify this Activity object, which implements the
// TabListener interface, as the
// listener for when this tab is selected.
actionBar.addTab(actionBar.newTab()
.setText(mCollectionPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
public void onTabUnselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
public void onTabSelected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in
// the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onBackPressed(){
// Rezolvarea butonului back
WebView webViewa = (WebView) findViewById(R.id.webView1);
WebView webViewb = (WebView) findViewById(R.id.webView2);
WebView webViewc = (WebView) findViewById(R.id.webView3);
WebView webViewd = (WebView) findViewById(R.id.webView4);
if ( webViewa.canGoBack()) {
webViewa.goBack();
}
if ( webViewb.canGoBack()) {
webViewb.goBack();
}
if ( webViewc.canGoBack()) {
webViewc.goBack();
}
if ( webViewd.canGoBack()) {
webViewd.goBack();
}
}
public void onTabReselected(ActionBar.Tab tab,
FragmentTransaction fragmentTransaction) {
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the primary sections of the app.
*/
public class CollectionPagerAdapter extends FragmentPagerAdapter {
final int NUM_ITEMS = 6; // number of tabs
public CollectionPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
Fragment fragment = new TabFragment();
Bundle args = new Bundle();
args.putInt(TabFragment.ARG_OBJECT, i);
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
return NUM_ITEMS;
}
#Override
public CharSequence getPageTitle(int position) {
String tabLabel = null;
switch (position) {
case 0:
tabLabel = getString(R.string.label1);
break;
case 1:
tabLabel = getString(R.string.label2);
break;
case 2:
tabLabel = getString(R.string.label3);
break;
case 3:
tabLabel = getString(R.string.label4);
break;
case 5:
tabLabel = getString(R.string.label6);
break;
case 4:
tabLabel = getString(R.string.label5);
break;
}
return tabLabel;
}
}
/**
* A fragment that launches other parts of the demo application.
*/
public static class TabFragment extends Fragment {
public static final String ARG_OBJECT = "object";
private WebView webView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Bundle args = getArguments();
int position = args.getInt(ARG_OBJECT);
int tabLayout = 0;
switch (position) {
case 0:
tabLayout = R.layout.tab1;
break;
case 1:
tabLayout = R.layout.tab2;
break;
case 2:
tabLayout = R.layout.tab3;
break;
case 3:
tabLayout = R.layout.tab4;
break;
case 5:
tabLayout = R.layout.tab6;
break;
case 4:
tabLayout = R.layout.tab5;
break;
}
View rootView = inflater.inflate(tabLayout, container, false);
webView = (WebView) rootView.findViewById(R.id.webView1);
WebView tab2 = (WebView) rootView.findViewById(R.id.webView2);
WebView tab3 = (WebView) rootView.findViewById(R.id.webView3);
WebView tab4 = (WebView) rootView.findViewById(R.id.webView4);
WebView tab5 = (WebView) rootView.findViewById(R.id.webView5);
WebView tab6 = (WebView) rootView.findViewById(R.id.webView6);
if (webView != null) {
webView.setWebViewClient(new WebViewClient());
webView.loadUrl("file:///android_asset/tab1.html");
}
if (tab2 != null) {
tab2.setWebViewClient(new WebViewClient());
tab2.loadUrl("file:///android_asset/tab2.html");
}
if (tab3 != null) {
tab3.setWebViewClient(new WebViewClient());
tab3.loadUrl("file:///android_asset/tab3.html");
}
if (tab4 != null) {
tab4.setWebViewClient(new WebViewClient());
tab4.loadUrl("file:///android_asset/tab4.html");
}
if (tab5 != null) {
tab5.setWebViewClient(new WebViewClient());
WebSettings tb5 = tab5.getSettings();
tb5.setJavaScriptEnabled(true);
tab5.loadUrl("http://fbhostinger.com/po/map.html");
}
if (tab6 != null) {
tab6.setWebViewClient(new WebViewClient());
tab6.loadUrl("file:///android_asset/tab5.html");
}
return rootView;
}
}
}
also my tab6 loads a html file from assets with this
if (tab6 != null) {
tab6.setWebViewClient(new WebViewClient());
tab6.loadUrl("file:///android_asset/tab5.html");
}

I think you just need to do:
if (tab6 != null) {
tab6.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith("tel:")) {
Intent intent = new Intent(Intent.ACTION_DIAL,
Uri.parse(url));
startActivity(intent);
return false;
}
return true;
}
});
tab6.loadUrl("file:///android_asset/tab5.html");
}
Please note the adaption of no longer calling view.loadUrl('...'); <- if you return true in shouldOverrideURLLoading, it will load the url into the WebView.

Related

Menu Button on ViewPager toasts wrong position

I am loading local htmls in webview using Viewpager. This works fine and the right page is loaded from the WebViewFragment into viewpager activity. Scroll or swipe works fine, but I added a menu button to get the title of the current webview, and to toast it. This menu button returns the webview title of the next 2 webview pages in the viewpager.
Reducing the setOfScreenLimit to 1 toasts the webview title of the next webview page in the viewpager. I cant setOfScreenLimit to 0. What is the most probable way to get the current item's webview title when the menu button is clicked. I need to get this and save to a DB.
Code:
ViewPager
ViewPager pager = (ViewPager) findViewById(R.id.pager);
TabsPagerAdapterEnglish pageAdapter = new TabsPagerAdapterEnglish(getSupportFragmentManager());
Bundle extras = getIntent().getExtras();
int value = 0;
if (extras != null) {
value = extras.getInt("keyHTML");
}
pager.setAdapter(pageAdapter);
pager.setCurrentItem(value);
pager.setOffscreenPageLimit(1);
Adapter
public class TabsPagerAdapterEnglish extends FragmentPagerAdapter {
private static int NUM_ITEMS = 3
public TabsPagerAdapterEnglish(FragmentManager fragmentManager) {
super(fragmentManager);
}
// Returns total number of pages
#Override
public int getCount() {
return NUM_ITEMS;
}
// Returns the fragment to display for that page
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return WebFragmentEnglish.newInstance(0, "file:///android_asset/page1.html");
case 1:
return WebFragmentEnglish.newInstance(1, "file:///android_asset/page2.html");
case 2:
return WebFragmentEnglish.newInstance(2, "file:///android_asset/page3.html");
default:
return null;
}
}
#Override
public CharSequence getPageTitle(int position) {
}
}
WebFragment
public class WebFragmentEnglish extends Fragment {
// newInstance constructor for creating fragment with arguments
public static WebFragmentEnglish newInstance(int position, String url) {
WebFragmentEnglish fragmentFirst = new WebFragmentEnglish();
Bundle args = new Bundle();
args.putInt("page_position", position);
args.putString("keyHTML", url);
fragmentFirst.setArguments(args);
return fragmentFirst;
}
// Store instance variables based on arguments passed
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
Toolbar toolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);
if (null != toolbar) {
toolbar.setNavigationIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
}
position = getArguments().getInt("page_position", 0);
url = getArguments().getString("keyHTML");
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
getActivity().finish();
case R.id.action_addtofav:
webView = (WebView) getActivity().findViewById(R.id.webView1);
htitle = webView.getTitle();
saveData();
Toast.makeText(getActivity(), htitle + " added to favorite",
Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
});
}
// Inflate the view for the fragment based on layout XML
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.webview, container, false);
webView = (WebView) view.findViewById(R.id.webView1);
progressBar = (ProgressBar) view.findViewById(R.id.progressBar);
progressBar.setMax(100);
webView.setWebViewClient(new WebViewClientDemo());
webView.setWebChromeClient(new WebChromeClientDemo());
webView.setInitialScale(1);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setLoadWithOverviewMode(true);
webView.getSettings().setUseWideViewPort(true);
webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
webView.getSettings().setPluginState(WebSettings.PluginState.ON);
webView.getSettings().setLoadsImagesAutomatically(true);
webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
webView.setScrollbarFadingEnabled(false);
webView.getSettings().setBuiltInZoomControls(true);
webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
webView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View arg0) {
// TODO Auto-generated method stub
return true;
}
});
webView.setLongClickable(false);
webView.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress) {
progressBar.setProgress(progress);
}
});
webView.loadUrl(url);
return view;
}
ViewPager will load the current page and the next page(s) up to the offScreenLimit. To get the name of the current page you need to get the current position of the adapter.
It's hard to give more specific help without having code posted. But you can use the ViewPager getCurrentItem method to get the visible index. From there you can either compare it to the index of the page you're displaying (this works if the view pager is static and pages are known in advance), or you can use that index to get the Fragment from the PagerAdapter and call a method on it to save the name.
I was able to solve the problem with the ViewPager.
I removed the toolbar instance from the fragment to use the one in the viewpager's activity. Then in my options menu, you would notice I used
webView = (WebView) **getActivity().**findViewById(R.id.webView1);
I removed the this completely, since i have already defined it in the onCreateView, I think maybe its because of the getActivity field I added to locate the webview ID.
I was updating an old code, I'm glad I was able to solve this. Thank you #Chisko and #Ben

Fragment with Webview utilize harware back button to go to previous webpage

This appears to have been asked a lot on stack overflow, but with answers which appear to no longer be implementable with changes to the SDK (I may be wrong!).
I have been trying to allow a fragment inside my MainActivity to use the hardware button to go back to the previous page inside a webview in the fragment.
I have tried using return super.onKeyDown(keyCode, event);
as part of a function but onKeyDown does not come up as valid in my project.
This is my BlogFragment containing the webview:
public class BlogFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
WebView wv;
private OnFragmentInteractionListener mListener;
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment blog.
*/
// TODO: Rename and change types and number of parameters
public static BlogFragment newInstance(String param1, String param2) {
BlogFragment fragment = new BlogFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
public static boolean canGoBack(){
return wv.canGoBack();
}
public static void goBack(){
wv.goBack();
}
public BlogFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view=inflater.inflate(R.layout.fragment_blog, null);
wv = (WebView) view.findViewById(R.id.webview);
WebSettings settings = wv.getSettings();
wv.setWebChromeClient(new WebChromeClient() {
});
final String mimeType = "text/html";
final String encoding = "UTF-8";
String html = getHTML();
settings.setJavaScriptEnabled(true);
wv.loadDataWithBaseURL("http://www.bbc.co.uk", html, mimeType, encoding, "");
return view;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public String getHTML() {
String html = "<iframe width=\"100%\" height=\"100%\" src=\"http://blog.mrgyro.co.uk\" frameborder=\"0\" allowfullscreen></iframe>";
return html;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p/>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
public void onFragmentInteraction(Uri uri);
}
}
Activity:
public class MainActivity extends ActionBarActivity
implements NavigationDrawerFragment.NavigationDrawerCallbacks, BlogFragment.OnFragmentInteractionListener, HomeFragment.OnFragmentInteractionListener {
/**
* Fragment managing the behaviors, interactions and presentation of the navigation drawer.
*/
private NavigationDrawerFragment mNavigationDrawerFragment;
/**
* Used to store the last screen title. For use in {#link #restoreActionBar()}.
*/
private CharSequence mTitle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mNavigationDrawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
}
#Override
public void onBackPressed() {
if(BlogFragment.canGoBack()){
BlogFragment.goBack();
}else{
super.onBackPressed();
}
}
#Override
public void onNavigationDrawerItemSelected(int position) {
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
android.support.v4.app.FragmentTransaction transaction = fragmentManager.beginTransaction();
switch (position) {
case 0:
HomeFragment homeFragment = new HomeFragment();
transaction.replace(R.id.container, homeFragment);
break;
case 1:
BlogFragment blogFragment = new BlogFragment();
transaction.replace(R.id.container, blogFragment);
break;
}
transaction.commit();
}
public void onSectionAttached(int number) {
switch (number) {
case 1:
mTitle = getString(R.string.title_section1);
break;
case 2:
mTitle = getString(R.string.title_section2);
break;
case 3:
mTitle = getString(R.string.title_section3);
break;
case 4:
mTitle = getString(R.string.title_section4);
break;
}
}
public void restoreActionBar() {
ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(mTitle);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
getMenuInflater().inflate(R.menu.main, menu);
restoreActionBar();
return true;
}
return super.onCreateOptionsMenu(menu);
}
#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
//if (id == R.id.action_settings) {
// return true;
// }
return super.onOptionsItemSelected(item);
}
#Override
public void onFragmentInteraction(Uri uri) {
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = null;
rootView = inflater.inflate(R.layout.fragment_home, container, false);
switch(getArguments().getInt(ARG_SECTION_NUMBER)) {
case 1:
rootView = inflater.inflate(R.layout.fragment_home, container, false);
break;
case 2:
rootView = inflater.inflate(R.layout.fragment_blog, container, false);
break;
case 3:
// rootView = inflater.inflate(R.layout.fragment_test, container, false);
break;
case 4:
//rootView = inflater.inflate(R.layout.fragment_info, container, false);
break;
default:
Log.e("TAG", "Unrecognized section: " + getArguments().getInt(ARG_SECTION_NUMBER));
}
return rootView;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((MainActivity) activity).onSectionAttached(
getArguments().getInt(ARG_SECTION_NUMBER));
}
}
}
Thanks in advance.
EDIT: I have updated the blog fragment with my most recent attempt, however when trying to static wv.canGoBack() and wv.goBack() both return the error "Non-Static field 'wv' cannot be referenced from a static context
Try overriding onBackPressed() in your Activity and make it poke the WebView.
BTW - you could post the piece of Activity containing the onKeyDown method as well.
EDIT: Instead of making your methods static and accessing them the way you do now (BlogFragment.canGoBack()), first instantiate the fragment:
BlogFragment blogFragment = new BlogFragment();
blogFragment.canGoBack();
and then just remove the static from your methods. :)
OPs implementation (with thanks to Klotor)
At the head of MainActivity implement:
BlogFragment blogFragment = new BlogFragment();
Then implement:
public void onBackPressed() {
blogFragment.canGoBack();
if(blogFragment.canGoBack()){
blogFragment.goBack();
}else{
super.onBackPressed();
}
}
The fragment is instantiated outside of the onBackPressed in order to prevent crashing when using a method to navigate between fragments.
In this case you need to instantiate a newinstance of the fragment, rather than a whole new fragment.
** In your Fragment Class Inside OnCreateView put below code**
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.your_layout, container, false);
mWebView = (WebView) view.findViewById(R.id.webView);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setWebViewClient(new MyWebViewClient());
mWebView.loadUrl(expertsUrl);
return view;
}
private class MyWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
**In MainActivity class put below code **
#Override
public void onBackPressed() {
if (WebViewFragment.mWebView!=null) {
if (WebViewFragment.mWebView.canGoBack()) {
WebViewFragment.mWebView.goBack();
}
else {
super.onBackPressed();
}
}
}
Replace WebViewFragment -> with your Fragment
mWebView -> with your webview
Hope this will help you!!!!

android navigation drawer fragment and ActionBarActivity

I have a navigation drawer and in one of the fragments, I'm trying to add a tab swipe layout. However I am unable to extend both ActionBarActivity and Fragment. Everything I've found online talks about FragmentActivity and not Fragment.
Is their a way to accomplish this?
This is my MainActivity :
public class MainActivity extends ActionBarActivity implements NavigationDrawerFragment.NavigationDrawerCallbacks {
/**
* Fragment managing the behaviors, interactions and presentation of the navigation drawer.
*/
private NavigationDrawerFragment mNavigationDrawerFragment;
/**
* Used to store the last screen title. For use in {#link #restoreActionBar()}.
*/
private CharSequence mTitle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mNavigationDrawerFragment = (NavigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
}
#Override
public void onNavigationDrawerItemSelected(int position) {
Fragment objFragment = null;
switch(position){
case 0:
objFragment = new myPantry_fragment();
break;
case 1:
objFragment = new myRecipes_fragment();
break;
case 2:
objFragment = new wheel_fragment();
break;
case 3:
objFragment = new addRecipes_fragment();//this causes errors
//when I change extends Fragment to extends ActionBarActivity
break;
}
// update the main content by replacing fragments
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, objFragment)
.commit();
}
public void onSectionAttached(int number) {
switch (number) {
case 1:
mTitle = getString(R.string.title_section1);
break;
case 2:
mTitle = getString(R.string.title_section2);
break;
case 3:
mTitle = getString(R.string.title_section3);
break;
case 4: //added this
mTitle = getString(R.string.title_section4);
}
}
public void restoreActionBar() {
ActionBar actionBar = getSupportActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(mTitle);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
getMenuInflater().inflate(R.menu.main, menu);
restoreActionBar();
return true;
}
return super.onCreateOptionsMenu(menu);
}
#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
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((MainActivity) activity).onSectionAttached(
getArguments().getInt(ARG_SECTION_NUMBER));
}
}
}
This is my fragment I access from the navigation drawer.
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class addRecipes_fragment extends ActionBarActivity {
View rootview;
ViewPager Tab;
TabPagerAdapter TabAdapter;
ActionBar actionBar;
#Nullable
//#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootview = inflater.inflate(R.layout.addrecipes_layout, container, false); //error shows in video too
//getWindow().requestFeature(Window.FEATURE_ACTION_BAR); //
// setContentView(R.layout.activity_main);
TabAdapter = new TabPagerAdapter(getSupportFragmentManager());
Tab = (ViewPager) rootview.findViewById(R.id.pager);
Tab.setOnPageChangeListener(
new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar = getSupportActionBar();
actionBar.setSelectedNavigationItem(position);
}
});
Tab.setAdapter(TabAdapter);
actionBar = getSupportActionBar();
//Enable Tabs on Action Bar
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ActionBar.TabListener tabListener = new ActionBar.TabListener(){
#Override
public void onTabSelected(ActionBar.Tab tab, android.support.v4.app.FragmentTransaction fragmentTransaction) {
Log.d("selected: ", "onTabSelected at" + "position" + tab.getPosition() + " " + tab.getText());
Tab.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab, android.support.v4.app.FragmentTransaction fragmentTransaction) {
Log.d("Unselected: ", "onTabSelected at" + "position" + tab.getPosition() + " " + tab.getText());
}
#Override
public void onTabReselected(ActionBar.Tab tab, android.support.v4.app.FragmentTransaction fragmentTransaction) {
Log.d("Reselected: ", "onTabSelected at" + "position" + tab.getPosition() + " " + tab.getText());
}
};
//Add New Tab
actionBar.addTab(actionBar.newTab().setText("General").setTabListener(tabListener)); //Android
actionBar.addTab(actionBar.newTab().setText("Add Ingredients").setTabListener(tabListener)); //IOS
actionBar.addTab(actionBar.newTab().setText("Add steps").setTabListener(tabListener)); //Windows
return rootview;
}
}
Keep your addRecipes_fragment extending the Fragment from support lib. Use a Viewpager in the Fragment layout to display the tabs and a custom PagerAdapter to load them using childfragment manager. Check this link.

Change fragment on click

I have to implement an application in which the user can click through a bottom_bar between 5 pages (although google does not recommend it in recent documents, the customer is always right).
So I created a swipe activity with automatic tool android study.
Question: how do I start the transation, after the click on the button, and change fragment??
Here is the code (at the time the activity change with the swipe)
public class Home extends ActionBarActivity {
SectionsPagerAdapter mSectionsPagerAdapter;
ImageView home, ospitalita,multimedia,territoro, prodotti;
ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
home = (ImageView) findViewById(R.id.ibHome);
ospitalita = (ImageView) findViewById(R.id.ibOspitalita);
multimedia = (ImageView) findViewById(R.id.ibMultimedia);
territoro = (ImageView) findViewById(R.id.ibTerritorio);
prodotti = (ImageView) findViewById(R.id.ibProdotti);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
View.OnClickListener gestore = new View.OnClickListener() {
#Override
public void onClick(View v) {
//this is the bottom bar, on click, change icon color
switch (v.getId()){
case R.id.ibHome:
changeBottomIcon("home");
mSectionsPagerAdapter.getItem(0); //do nothing
break;
case R.id.ibOspitalita:
changeBottomIcon("ospitalita");
mSectionsPagerAdapter.getItem(1);
break;
case R.id.ibMultimedia:
changeBottomIcon("multimedia");
mSectionsPagerAdapter.getItem(2);
break;
case R.id.ibTerritorio:
changeBottomIcon("territorio");
mSectionsPagerAdapter.getItem(3);
break;
case R.id.ibProdotti:
changeBottomIcon("prodotti");
mSectionsPagerAdapter.getItem(4);
break;
}
}
};
home.setOnClickListener(gestore);
ospitalita.setOnClickListener(gestore);
multimedia.setOnClickListener(gestore);
territoro.setOnClickListener(gestore);
prodotti.setOnClickListener(gestore);
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
switch (position) {
// change bottom doesn't work here
case 0:
// changeBottomIcon("home");
return new fragment_home();
case 1:
//changeBottomIcon("territorio");
return new fragment_territorio();
case 2:
//changeBottomIcon("ospitalita");
return new fragment_ospitalita();
case 3:
//changeBottomIcon("multimedia");
return new fragment_multimedia();
case 4:
//changeBottomIcon("prodotti");
return new fragment_prodotti();
}
return null;
}
#Override
public int getCount() {
//num pagine
return 5;
}
#Override
public CharSequence getPageTitle(int position) {
//Not visible, no nav bar
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.home);
case 1:
return getString(R.string.territorio);
case 2:
return getString(R.string.ospitalita);
case 3:
return getString(R.string.multimedia);
case 4:
return getString(R.string.prodotti);
}
return null;
}
}
//simple method to change icon color
public void changeBottomIcon(String tipo){
.
.
.
//lo ometto perchè inutile
}
}
You can achieve this by calling:
mViewPager.setCurrentItem(index);
(see the android dev docs for further information)

Strange onPause(), onResume() behaviour in fragments

The application has a main activity (MainActivity.java) with three tabs (fragments). I can navigate between them using the swipe left (riht) or clicking on a specific tab.
Upon starting the application, the 1st fragment is shown.
If I go to the 2nd fragment from the 1st fragment and then back to the 1st fragment, nothing happens (onResume() of the 1rd fragment isn't called), so it doesn't refresh it's content.
If I go to the 3rd fragment from the 1st fragment and then directly back to the 1st fragment, the onCreateView() of fragment1 is created and it's onResume() is called, which is correct.
If I go from the 3rd fragment to the 2nd fragment, the onCreateView() and onResume() of fragment1 are called, but not the onCreateView of fragment2.
I guess the logic in MainActivity isn't right, so I would kindly ask someone to take a look and tell me what could be wrong.
MainActivity.java:
public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
CollectionPagerAdapter mCollectionPagerAdapter;
public TTSocket socket;
DBHandler db;
public String logged_user;
private LogedinPerson person;
ViewPager mViewPager;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Bundle extras = getIntent().getExtras();
logged_user = extras.getString("logged_user");
socket = TTSocket.getInstance();
socket.currentRef = this;
db = new DBHandler(this);
person=db.getLogedInPerson();
socket.dbHandler=db;
socket.person=person;
if(!socket.isInit){
String typeInitStr = "{\"Type\":\"Init\", \"UserId\":\""+ person.getUserId() +"\"}";
socket.Send(typeInitStr);
}
mCollectionPagerAdapter = new CollectionPagerAdapter(getSupportFragmentManager());
// Set up action bar.
final ActionBar actionBar = getActionBar();
// Specify that we will be displaying tabs in the action bar.
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Set up the ViewPager, attaching the adapter and setting up a listener
// for when the
// user swipes between sections.
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mCollectionPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
Log.d("TEST",position+"");
// the corresponding tab.
// We can also use ActionBar.Tab#select() to do this if
// we have a reference to the Tab
actionBar.setSelectedNavigationItem(position);
}
});
// For each of the sections in the app, add a tab to the action bar.
for (int i = 0; i < mCollectionPagerAdapter.getCount(); i++) {
// Create a tab with text corresponding to the page title defined by
// the adapter.
// Also specify this Activity object, which implements the
// TabListener interface, as the
// listener for when this tab is selected.
if(i == 0){
actionBar.addTab(actionBar.newTab()
.setIcon(R.drawable.messages)
.setTabListener(this));
}else if(i == 1){
actionBar.addTab(actionBar.newTab()
.setIcon(R.drawable.contacts)
.setTabListener(this));
}else{
actionBar.addTab(actionBar.newTab()
.setIcon(R.drawable.history)
.setTabListener(this));
}
}
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
socket.currentRef = this;
socket.dbHandler=db;
socket.person=person;
//mCollectionPagerAdapter.notifyDataSetChanged();
}
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
// When the given tab is selected, switch to the corresponding page in
// the ViewPager.
mViewPager.setCurrentItem(tab.getPosition());
}
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the primary sections of the app.
*/
public class CollectionPagerAdapter extends FragmentPagerAdapter {
final int NUM_ITEMS = 3; // number of tabs
public CollectionPagerAdapter(FragmentManager fm) {
super(fm);
}
/*
#Override
public Fragment getItem(int i) {
Fragment fragment = new TabFragment();
Bundle args = new Bundle();
args.putInt(TabFragment.ARG_OBJECT, i);
fragment.setArguments(args);
return fragment;
}
*/
#Override
public Fragment getItem(int position) {
Fragment fragment = new Fragment();
Bundle args = new Bundle();
args.putInt(TabFragment.ARG_OBJECT, position);
switch (position) {
case 0:
Log.i("Fragment", "0");
fragment = new Tab1Fragment();
fragment.setArguments(args);
return fragment;
case 1:
Log.i("Fragment", "1");
fragment = new Tab2Fragment();
fragment.setArguments(args);
return fragment;
case 2:
Log.i("Fragment", "2");
fragment = new Tab3Fragment();
fragment.setArguments(args);
return fragment;
default:
break;
}
return fragment;
}
#Override
public int getCount() {
return NUM_ITEMS;
}
#Override
public CharSequence getPageTitle(int position) {
String tabLabel = null;
switch (position) {
case 0:
tabLabel = getString(R.string.label1);
break;
case 1:
tabLabel = getString(R.string.label2);
break;
case 2:
tabLabel = getString(R.string.label3);
break;
}
return tabLabel;
}
}
/**
* A fragment that launches other parts of the demo application.
*/
public static class TabFragment extends Fragment {
public static final String ARG_OBJECT = "object";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Bundle args = getArguments();
int position = args.getInt(ARG_OBJECT);
int tabLayout = 0;
switch (position) {
case 0:
tabLayout = R.layout.tab1;
break;
case 1:
tabLayout = R.layout.tab2;
break;
case 2:
tabLayout = R.layout.tab3;
break;
}
View rootView = inflater.inflate(tabLayout, container, false);
return rootView;
}
}
}
Strange onPause(), onResume() behaviour() in fragments
It's not strange behaviour but native behaviour of ActionSherlock. This kind of behaviour is used for caching -> optimalisation for older devices with lower RAM this is reason why fragments are cached.
If you need to update content of fragment don't try to replace its layout or something similar. If you want to update fragment when scrolling between pages, you need to use method of FragmentPagerAdapter:
#Override
public int getItemPosition(Object object) {
// implementation
return super.getItemPosition(object);
}
This method is called when you will call
notifyDataSetChanged();
on your FragmentPagerAdapter. It's handy method for make updates of your fragments. There are more ways how to do it but here i'll show you how I'm doing it.
Let your fragments implement interface for example called Updateable:
interface Updateable {
public void update();
}
public class MyFragment extends SherlockFragment implements Updateable {
#Override
public void update() {
// perform Fragment updates
}
}
And in this method you will perform updates. Now back to getItemPosition() method. This method will be used for invoking update() method from Fragment i.e:
#Override
public int getItemPosition(Object object) {
Fragment f = (Fragment) object;
// determine which fragment
if (f instanceof MyFragment) {
((MyFragment) f).update(); // invokes update() method
}
return super.getItemPosition(object);
}
Now whenever you scroll page or tap on some tab (you need also call notifyDataSetChanged()) you are able to make Fragment updates. This way is more efficient against destroying and recreating fragment(s) each time you scrolling or clicking on tabs. But how i said this is not only solution there are more possible solutions.
Note: getItemPosition() can return two values: POSITION_NONE and UNCHANGED. Difference between both is that first indicates that Fragment will be always destroyed and recreated that is not very efficient and second indicates that Fragment won't be changed (is in on right place).
For more detailed explanation look here.
That is because ViewPager doesn't hide all fragments you switch.
You can control this behaviour by setOffscreenPageLimit

Categories

Resources