Cannot move map in webview - android

One activity (MainActivity) calls a fragment(MainPage). The fragment is designed to open a local asset webview file, Map.html. It works as intended, with the exception that the map cannot be moved by fingertip. This function is available when the Map.html is opened a broswer. However, the zoom in zoom out tap button in the top left does work.
Is something overlaying the webview such that it can be seen but not swiped?
The initial AppCompatActivity (to support ActionBar) is given by MainActivity:
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
//list of private declarations
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// a lot of other stuff relating to navigation drawer
// calls MainPage Fragment
android.support.v4.app.Fragment fragment = new MainPage();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment)
.addToBackStack("tag")
.commit();
}
}
where the xml for this is given as:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_centerVertical="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/content_frame">
</WebView>
<ListView
android:id="#+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#111">
</ListView>
</android.support.v4.widget.DrawerLayout>
</LinearLayout>
Eventually calls MainPage, given as:
public class MainPage extends android.support.v4.app.Fragment implements GeolocationPermissions.Callback {
public MainPage() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_main, container, false);
WebView webview = (WebView) rootView.findViewById(R.id.content_frame);
webview.getSettings().setJavaScriptEnabled(true);
webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
webview.getSettings().setGeolocationEnabled(true);
GeoClient geo = new GeoClient();
webview.setWebChromeClient(geo);
String origin = "";
geo.onGeolocationPermissionsShowPrompt(origin, this);
webview.loadUrl("file:///android_asset/Map.html");
return rootView;
}

You may need to set an onclicklistener. For Google Maps, this is how I did it. Its probably similar.
Add the implements, #override function, and set the onclick listener. I'm not sure if this will work since you are using HTML at some point.
public class MainActivity extends FragmentActivity implements View.OnClickListener,
GoogleMap.OnMapClickListener {
Then when you initiate it set the onmap click listener.
gMap.setOnMapClickListener(this);// add the listener for click on gmap object
Finally, add this #override:
#Override
public void onMapClick(LatLng point) {
//What code if any happens when user clicks on map
}

Related

Android - search tool bar in MapActivity

I need a search toolbar on Google Map.
I display the map with the use of MapActivity.
The way I did is via the create project wizard, when you a create a new project, you can choose from basic activity, empty activity, map activity.
I selected MapActivity.
In XML file I had only this:
<resources>
<string name="google_maps_key" templateMergeStrategy="preserve"
translatable="false">AIzaSyCx3iR5fkeWr2LUf6JBHwGLEEkeghL3snk
</string>
</resources>
So what is the way to insert that search toolbar on the map?
Then how to add that search tool bar. If I add a layout then an error it is shown.
The way I would do it is the following:
I would have an activity which has a fragment that contain the map inside.
Inside the activity I would have a method that display the fragment with the map:
public void showMap() {
MapLocationFragment locationFragment = MapLocationFragment.newInstance();
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container, locationFragment)
.addToBackStack(null)
.commit();
}
activity xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="#+id/app_bar_include"
layout="#layout/app_bar_layout_device" />
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize" />
</RelativeLayout>
Now, inside the MapLocationFragment you need to have something like that:
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.maps_layout, container, false);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initializeMapIfNeeded();
}
private void initializeMapIfNeeded() {
if (googleMap == null) {
loadMapAsync();
}
}
private void loadMapAsync() {
((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.location_map)).getMapAsync(getOnMapReadyCallback());
}
public OnMapReadyCallback getOnMapReadyCallback() {
return new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap map) {
googleMap = map;
if (googleMap == null) {
return;
}
googleMap.setIndoorEnabled(true);
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
googleMap.setOnMyLocationButtonClickListener(getMapMpOnMyLocationClickListener());
googleMap.setLocationSource(getNewLocationSource());
googleMap.setOnCameraChangeListener(getCameraChangeListener());
//do other stuff too
}
};
}
xml:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<fragment
android:id="#+id/location_map"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:clickable="true"
android:src="#android:drawable/ic_menu_set_as"
app:layout_anchorGravity="bottom|right|end"
android:layout_gravity="bottom|end"/>
</android.support.design.widget.CoordinatorLayout>
For more details look at this project:
Sunshine app
You can try it.
public class MapsActivity extends FragementActivity implements OnMapReadyCallback,LocationListener in here, Put the AppCompatActivity instead of the FragementActivity.

IllegalArgumentException:No view found for id

I get the following exception:
java.lang.IllegalArgumentException:
No view found for id 0x7f04001a (com.whatever:layout/fragment_main)
Looking at similar questions on SO:
One answer suggests using getChildFragmentManager() instead of getSupportFragmentManager().
This is not an option since MainActivity is not a Fragment.
Another answer suggests that fragment_main is not a child of activity_main, but I think I have that setup in activity_main.xml with tools:layout="#layout/fragment_main
Another suggests that setContent() has not been called, but I have that in onCreate()
What am I missing?
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public void onStart() {
super.onStart();
// create fragment immediately
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.layout.fragment_main, new MainActivityFragment());
fragmentTransaction.commit();
boolean wereThereWereAnyPendingTransactions = fragmentManager.executePendingTransactions();
}
}
MainActivityFragment.java
public class MainActivityFragment extends Fragment implements Observer<String> {
public MainActivityFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_main, container, false);
}
activity_main.xml
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/fragment"
android:name="com.whatever.MainActivityFragment"
tools:layout="#layout/fragment_main"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
fragment_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/fragment_main_table"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MainActivityFragment">
<TextView
android:text="#string/fragment_main_xml"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
The answer with respect to code:
actvity_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_frame_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context=".MainActivity" >
</FrameLayout>
MainActivity.java:
...
fragmentTransaction.add(R.id.activity_frame_layout, new MainActivityFragment());
...
If you embed a Fragment inside of an Activity XML layout, you do not create it dynamically. The system does it for you. So there is no need to create the transaction and commit it, the Fragment will be created and added when you called setContentView().
Note that the tools:layout= line does not do anything at runtime. It is strictly for the tools to better link layouts and components together.

FragmentManager gives me NPE

I'm checking fragments for the first time and I created a LinearLayout with a FrameLayout within and for my layout-sw600dp a LinearLayout with 2 FrameLayouts.
The one has an id of "main" and the other is "details".
The error I get is :
Caused by: java.lang.NullPointerException
at android.app.BackStackRecord.doAddOp(BackStackRecord.java:395)
at android.app.BackStackRecord.add(BackStackRecord.java:385)
at mes.fallstudio.tvfall.MainActivity.onCreate(MainActivity.java:28)
where line 28 is the last line here:
public class MainActivity extends AppCompatActivity {
private android.support.v4.app.Fragment mainFragment;
private android.app.Fragment detailsFragment;
private Boolean isDualPane = false;
private android.support.v4.app.FragmentManager fm;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
mainFragment = fragmentManager.findFragmentById(R.id.main);
android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.main, mainFragment).commit();
}
}
XML layout files :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
<FrameLayout
android:id="#+id/details"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
this is for layout-sw600dp and the same without the 2nd FrameLayout ( details) for the xml file for the layout folder.
I'm extending AppCompatActivity if this helps.
Thanks you
AppCompatActivity uses getSupportFragmentManager() instead of getFragmentManager().
Reference: https://developer.android.com/reference/android/support/v7/app/AppCompatActivity.html
EDIT:
In your code you try to get mainFragment from the XML layout. However, you do not define it there. You can either instantiate mainFragment in your code:
mainFragment = new MainFragment();
Or define it in your XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment android:name="mes.fallstudio.tvfall.MainFragment"
android:id="#+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<FrameLayout
android:id="#+id/details"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
In the latter case you don't need to use the FragmentManager at all in your code unless you need to manipulate the fragments at run time.
In both cases you also need the actual fragment:
public class MainFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.main_fragment, container, false);
}
}

Android fragment transaction with SlidingTabLayout not working in API level < 21

in my app I have an ActionBarActivity (I'm using support library with AppCompat) that uses the SlidingTabLayout class from Google (taken from here). So this is the XML code of the activity's layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_series_details"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".SeriesDetailsActivity">
<com.my.package.SlidingTabLayout
android:id="#+id/series_details_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="2dp"
android:background="#color/primary_material_dark" />
<android.support.v4.view.ViewPager
android:id="#+id/series_details_pager"
android:layout_height="0dp"
android:layout_width="match_parent"
android:layout_weight="1" />
</LinearLayout>
In this activty, when user press an option in the action bar, I want to add a Fragment with a custom animation. This is the code that handle menu click:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
/* ... OTHER CASES ... */
case R.id.menu_voption:
newFragment = MyNewFragment.newInstance();
getSupportFragmentManager().beginTransaction()
.setCustomAnimations(
R.anim.slide_up,
R.anim.slide_down
)
.add(R.id.activity_series_details, newFragment)
.commit();
editing = true;
break;
default:
return super.onOptionsItemSelected(item);
}
return true;
Doing this, my new fragment is correctly added to the activty and replace the currente fragment but not tab layout, tha remains visible. So I've tryed to add this line before start transaction:
tabsHost.setVisibility(View.GONE);
where tabsHost is the SlidingTabLayout. With this modification, the tabs layout disappear and the new fragment is correctly shown, but only in the API Level >= 21. In my Samsung Galaxy S4 (that runs API 19) and in all other emulators with lesser API level than 21 (my target is 11+), the tabs layout disappear but new fragment is not visible. I'm pretty sure is my fault, but I can't figure why. Thanks all for attention.
Since the SlidingTabLayout is not a fragment, it cannot be managed by the FragmentManager. You would have to make it part of a fragment and add it to your Activity. This is possible with getChildFragmentManager.
Move your activity layout to a fragment:
activity_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_series_details"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
fragment_sliding_tab.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_series_details"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.my.package.SlidingTabLayout
android:id="#+id/series_details_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="2dp"
android:background="#color/primary_material_dark" />
<android.support.v4.view.ViewPager
android:id="#+id/series_details_pager"
android:layout_height="0dp"
android:layout_width="match_parent"
android:layout_weight="1" />
</LinearLayout>
SlidingTabFragment.java
public class SlidingTabFragment extends Fragment {
private PagerAdapter mPagerAdapter;
private ViewPager mViewPager;
public static SlidingTabFragment newInstance() {
SlidingTabFragment fragment = new SlidingTabFragment();
return fragment;
}
public SlidingTabFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mPagerAdapter = new PagerAdapter(getChildFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) view.findViewById(R.id.series_details_pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
SlidingTabLayout tabs = (SlidingTabLayout) view.findViewById(R.id.series_details_tabs);
tabs.setViewPager(mViewPager);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_sliding_tab, container, false);
}
}
Add your fragment in your Activity's onCreate:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Fragment slidingTabFragment = SlidingTabFragment.newInstance();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.activity_series_details, slidingTabFragment).commit();
}

Extend MapFragment Android

I have an activity that hosts two fragments. One fragment provides some info to the user in various fields. The other fragment should show a Map.
For the fragment hosting the map I need to be able to add custom logic for displaying markers and several other things that I would like to reuse in other places in the app. What is the best way to create a map without defining the fragment in xml like:
<fragment
class="com.google.android.gms.maps.MapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Thanks,
Nathan
Edit:
I am now using nested fragments, not sure if that is the best way to handle this? My mapfragment is now:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.MapFragment" />
</LinearLayout>
and the Fragments code is:
public class ViewCurrentMapFragment extends Fragment implements View.OnClickListener {
public static final String TAG = "MAP_FRAGMENT";
private GoogleMap map;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_view_current_map, container, false);
return rootView;
}
private void getCurrentMarkers() {
// Getting reference to the SupportMapFragment of activity_main.xml
SupportMapFragment smf = ((SupportMapFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.map));
map = smf.getMap();
}
#Override
public void onClick(View v) {
}
#Override
public void onResume() {
super.onResume();
getCurrentMarkers();
}
}
The problem I am having now is that smf.getMap() is returning null. Any ideas?
Edit2:
Got it to work by changing:
com.google.android.gms.maps.MapFragment
to
com.google.android.gms.maps.SupportMapFragment
Maybe:
<fragment
class="com.mycompany.MyCustomFragmentExtendingMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
or nest fragments like here: http://code.google.com/p/gmaps-api-issues/issues/detail?id=5064#c1

Categories

Resources