I have started building an application but I think I'm might be doing something wrong in the main structure. My application is 3 fragments, communicating with each other. The first fragment is about settings, the second one is an exandable array list. The third is a Gmap.
Clicking on a specific setting in the first fragment (that is a location) would make the gmap opens at the good spot... Same thing for child item in the second fragment.
I also would like to have a thread that update the current location of all fragments.
The this is, I don't know how I should structure my app. Is it good to have 3 fragments, should I use 3 activities? And how the communication should be made within fragments? I read that fragments should not communicate directly together, but in my case I don't see how the child of an exandable array list can not directly open the fragment containing GMap...
Here is a picture, just to figure out what my app would look like:
http://s14.postimg.org/ywj7yu8qp/Untitled.png
Here's the code so far:
MainActivity:
package com.stylingandroid.basicactionbar;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends Activity
{
private class MyTabListener implements ActionBar.TabListener
{
private Fragment mFragment;
private final Activity mActivity;
private final String mFragName;
public MyTabListener( Activity activity, String fragName )
{
mActivity = activity;
mFragName = fragName;
}
#Override
public void onTabReselected( Tab tab, FragmentTransaction ft )
{
// TODO Auto-generated method stub
}
#Override
public void onTabSelected( Tab tab, FragmentTransaction ft )
{
mFragment = Fragment.instantiate( mActivity, mFragName );
ft.add( android.R.id.content, mFragment );
}
#Override
public void onTabUnselected( Tab tab, FragmentTransaction ft )
{
ft.remove( mFragment );
mFragment = null;
}
}
#Override
public void onCreate( Bundle savedInstanceState )
{
super.onCreate( savedInstanceState );
// Intent intent;
ActionBar ab = getActionBar();
ab.setNavigationMode( ActionBar.NAVIGATION_MODE_TABS );
Tab tab = ab.newTab()
.setText( R.string.title_param )
.setTabListener(
new MyTabListener( this,
Param.class.getName() ) );
ab.addTab( tab );
// intent = new Intent().setClass(this, Friends.class);
tab = ab.newTab()
.setText( R.string.title_friends )
.setTabListener(
new MyTabListener( this,
Friends.class.getName() ) );
ab.addTab( tab );
tab = ab.newTab()
.setText( R.string.title_maps )
.setTabListener(
new MyTabListener( this,
Maps.class.getName() ) );
ab.addTab( tab );
}
#Override
public boolean onCreateOptionsMenu( Menu menu )
{
getMenuInflater().inflate( R.menu.main, menu );
return true;
}
#Override
public boolean onOptionsItemSelected( MenuItem item )
{
boolean ret;
if (item.getItemId() == R.id.menu_settings)
{
// Handle Settings
ret = true;
} else
{
ret = super.onOptionsItemSelected( item );
}
return ret;
}
}
Tab1:
package com.stylingandroid.basicactionbar;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import android.app.Fragment;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class Param extends Fragment
{
Button btnShowLocation;
private View V;
TextView text;
public static double latitude;
public static double longitude;
// GPSTracker class
GPSTracker gps;
#Override
public View onCreateView( LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState )
{
V = inflater.inflate( R.layout.param, container, false );
gps = new GPSTracker(getActivity());
if(gps.canGetLocation()){
text = (TextView) V.findViewById(R.id.widget35);
latitude = gps.getLatitude();
longitude = gps.getLongitude();
String cityName=null;
Geocoder gcd = new Geocoder(getActivity(), Locale.getDefault());
List<Address> addresses;
try {
addresses = gcd.getFromLocation(latitude, longitude, 1);
if (addresses.size() > 0)
System.out.println(addresses.get(0).getLocality());
cityName=addresses.get(0).getLocality();
} catch (IOException e) {
e.printStackTrace();
}
// create class object
// check if GPS enabled
text.setText(cityName);
}else{
// can't get location
// GPS or Network is not enabled
// Ask user to enable GPS/network in settings
gps.showSettingsAlert();
}
return V;
}
}
Tab2:
package com.stylingandroid.basicactionbar;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import android.app.Fragment;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.Toast;
public class Friends extends Fragment implements OnChildClickListener
{
private static List<Country> Countries;
private ExpandableListView expandableListView;
private CountryAdapter adapter;
private View V;
#Override
public View onCreateView( LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState )
{
V = inflater.inflate( R.layout.frag2, container, false );
expandableListView = (ExpandableListView) V.findViewById(R.id.expandableListView);
expandableListView.setOnChildClickListener(this);
LoadCountries();
return V;
}
private void LoadCountries() {
Countries = new ArrayList<Country>();
ArrayList<String> citiesAustralia = new ArrayList<String>(
Arrays.asList("Brisbanea", "Hobart", "Melbourne", "Sydney"));
Countries.add(new Country("Australia", citiesAustralia));
ArrayList<String> citiesChina = new ArrayList<String>(
Arrays.asList("Beijing", "Chuzhou", "Dongguan", "Shangzhou"));
Countries.add(new Country("China", citiesChina));
adapter = new CountryAdapter(getActivity(), Countries);
expandableListView.setAdapter(adapter);
}
#Override
public boolean onChildClick(ExpandableListView arg0, View arg1, int arg2,
int arg3, long arg4) {
/* Fragment param = new Param();
android.app.FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.frag2, param);
ft.addToBackStack(null);
ft.commit();
*/
Toast.makeText(getActivity(), "Clicked on Detail " , Toast.LENGTH_LONG).show();
return true;
}
}
Tab3:
package com.stylingandroid.basicactionbar;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import android.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Maps extends Fragment
{
static final LatLng HAMBURG = new LatLng(Param.latitude, Param.longitude);
static final LatLng KIEL = new LatLng(53.551, 9.993);
private GoogleMap map;
View V;
#Override
public View onCreateView( LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState )
{
V = inflater.inflate( R.layout.frag1, container, false );
map = ((MapFragment) getActivity().getFragmentManager().findFragmentById(R.id.map))
.getMap();
Marker hamburg = map.addMarker(new MarkerOptions().position(HAMBURG)
.title("Hamburg"));
// Move the camera instantly to hamburg with a zoom of 15.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15));
// Zoom in, animating the camera.
map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
GoogleMap gMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
gMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
gMap.setMyLocationEnabled(true);
gMap.getUiSettings().setCompassEnabled(true);
Log.e("Maps", "------EOC-------");
return V;
}
}
param.xml (tab1):
<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout
android:id="#+id/widget0"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<ToggleButton
android:id="#+id/widget33"
android:layout_width="125dp"
android:layout_height="59dp"
android:textOn="I'm free!"
android:textOff="I'm free!"
android:layout_x="78dp"
android:layout_y="29dp" />
<TextView
android:id="#+id/widget34"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Lieu actuel"
android:layout_x="87dp"
android:layout_y="196dp" />
<TextView
android:id="#+id/widget35"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Indisponible"
android:layout_x="101dp"
android:layout_y="247dp" />
<TextView
android:id="#+id/widget36"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="GPS"
android:layout_x="89dp"
android:layout_y="108dp" />
<ToggleButton
android:id="#+id/widget37"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOn="On"
android:textOff="Off"
android:layout_x="158dp"
android:layout_y="99dp" />
</AbsoluteLayout>
frag2.xml (tab2):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ExpandableListView
android:id="#+id/expandableListView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
frag1.xml (tab3):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.MapFragment" />
</RelativeLayout>
Here are only the principal fragments, I can also provide the full code of all classes if needed...
Questions:
Is it okay of what I began to do about how fragments work? Should I instead use activities? Is it okay how I proceeded to create fragment? Do I respect programming standard?
How to communicate from fragments to another? I use global variables so when something is updated, gmap (tab3) is also updated, but I don't see how to open the gmap fragment on a click.
The gmap is making the app crashing when I click two times on the gmap tab...?
Thanks a lot guys.
You can use all the fragments you want :)
I think the best way i to make an abstract Class to save and handle all you data and events.
In an abstract Class declare the method Static so you can call them directly on the Class.
Related
I have a problem integrating google map in fragment in android. I know how to do it in activity but fragment reference on this site are very old and not working in 2018. I don't have any error.below is fragment file. Any help will be highly appreciated. I have added API key and proper manifest file.
package com.example.narmail.truck30mint.Api.Fragments;
import android.Manifest;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.example.narmail.truck30mint.R;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.MapsInitializer;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import java.util.ArrayList;
public class ViewTrucksFragment extends Fragment {
TextView pageTitle;
MapView mMapView;
private GoogleMap googleMap;
public ViewTrucksFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_view_trucks, container, false);
pageTitle = rootView.findViewById(R.id.view_trucks_title);
String load_id = getArguments().getString("load_id");
String load_from = getArguments().getString("load_from");
String load_to = getArguments().getString("load_to");
if (load_id != null && load_from != null && load_to != null) {
pageTitle.setText("Matching Trucks for "+load_from+" to "+load_to);
}
mMapView= rootView.findViewById(R.id.view_trucks_map);
mMapView.onCreate(savedInstanceState);
mMapView.onResume();
try {
MapsInitializer.initialize(getActivity().getApplicationContext());
} catch (Exception e) {
e.printStackTrace();
}
mMapView.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap mMap) {
googleMap = mMap;
googleMap.getUiSettings().setCompassEnabled(true);
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
googleMap.getUiSettings().setRotateGesturesEnabled(true);
// For dropping a marker at a point on the Map
LatLng sydney = new LatLng(30.374219,76.782055);
googleMap.addMarker(new MarkerOptions().position(sydney).
title("Title").snippet("TitleName"));
// For zooming automatically to the location of the marker
CameraPosition cameraPosition = new CameraPosition.Builder().target(sydney).zoom(12).build();
googleMap.animateCamera(CameraUpdateFactory.newCameraPosition
(cameraPosition ));
}
});
/*----------------*/
return rootView;
}
}
and below is my layout file
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorWhite"
tools:context=".Api.Fragments.ViewTrucksFragment">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/view_trucks_title"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textAlignment="center"
android:layout_marginRight="10dp"
android:layout_marginLeft="10dp"
android:padding="10dp"
android:textColor="#color/colorPrimary"
android:textSize="15sp"
android:text="#string/hello_blank_fragment" />
<com.google.android.gms.maps.MapView
android:id="#+id/view_trucks_map"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.google.android.gms.maps.MapView>
</LinearLayout>
</FrameLayout>
Please follow below step to finish your task. Just need to create 3 files
(1) Create XML layout for map inside your fragment layout fragment_map.xml
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
(2) Create Fragment to load MAP MapFragment.Java
public class MapFragment extends Fragment implements OnMapReadyCallback {
private GoogleMap mMap;
public MapFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_map, container, false);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
if(getActivity()!=null) {
SupportMapFragment mapFragment = (SupportMapFragment) getActivity().getSupportFragmentManager()
.findFragmentById(R.id.map);
if (mapFragment != null) {
mapFragment.getMapAsync(this);
}
}
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
//Do your stuff here
}
}
(3) Create Activity to load MAP fragment MapsActivity.java
public class MapsActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.content,new MapFragment());
fragmentTransaction.commit();
}
}
For MAP key you need to follow same step you have done in your project. Hope this step will help you.
Inside Gradle please use below gradle
implementation 'com.google.android.gms:play-services-maps:15.0.1'
AndroidManifest.xml define below things.
<uses-permission android:name="android.permission.INTERNET"/>
Inside Application Tag.
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="YOUR MAP KEY" />
I'm trying to show list view on the bottom side of the google maps activity (only when the button is clicked), but it doesn't work, just showing app stop message. How can I show listview on google maps activity?
Here is my java and xml code
package com.example.dong_gyo.project;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import java.util.ArrayList;
public class MapFind extends ActionBarActivity {
GoogleMap mMap; // Might be null if Google Play services APK is not available.
LocationManager lm;
String locationProvider;
Location location;
Button mapListbut;
ListView mapList;
ArrayList list;
ButtonListener listener;
ArrayAdapter mapadapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map_find);
setUpMapIfNeeded();
mapListbut = (Button)findViewById(R.id.showMapList);
mapadapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, list);
mapList = (ListView)findViewById(R.id.mapList);
mapList.setAdapter(mapadapter);
mapList.setVisibility(View.INVISIBLE);
mapListbut.setOnClickListener(listener);
}
#Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
locationProvider = lm.getBestProvider(new Criteria(), true);
location = lm.getLastKnownLocation(locationProvider);
double latitude = location.getLatitude();
double longitude = location.getLongitude();
final LatLng LOC = new LatLng(latitude, longitude);
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(LOC, 16));
// Check if we were successful in obtaining the map.
if (mMap != null) {
setUpMap(LOC);
}
}
}
private void setUpMap(LatLng LOC) {
mMap.addMarker(new MarkerOptions().position(LOC));
}
class ButtonListener implements View.OnClickListener {
#Override
public void onClick(View v) { // 목록 토글 버튼 리스너
// TODO Auto-generated method stub
switch (v.getId()) { //
case R.id.showMapList:
if (!mapList.isShown()) {
mapList.setVisibility(View.VISIBLE);
mapadapter.notifyDataSetChanged();
mapListbut.setSelected(true);
} else {
mapList.setVisibility(View.INVISIBLE);
mapListbut.setSelected(false);
}
break;
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_activity_actions, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.action_search:
startActivity(new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
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"
android:weightSum="1">
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/map"
tools:context=".MapsActivity"
android:name="com.google.android.gms.maps.SupportMapFragment"/>
<Button
android:id="#+id/showMapList"
android:text = "목록보기"
android:layout_width="100dp"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
android:layout_marginBottom="20dp"
android:layout_marginLeft="20dp"/>
<ListView
android:id="#+id/mapList"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:background="#eeeeee" >
</ListView>
</RelativeLayout>
I ran your code and it said it gets a null pointer. Looking at your code, location = lm.getLastKnownLocation(locationProvider); makes location to be null. So, instead of the getBestProvider, try:
location = lm.getLastKnownLocation(LocationManager.PASSIVE_PROVIDER);
I tried it and the maps load.
i have been using the navigation drawer and in case 1 i would like to run a google maps API inside a fragment.
but i get the following error:
'replace(int, android.app.Fragment)' in 'android.app.FragmentTransaction' cannot be applied to '(int, com.example.matant.test.MapFragment)'
this is the mainactivity:
package com.example.matant.test;
import android.app.ActionBar;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Adapter;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {
private ActionBarDrawerToggle actbartoggle;
private android.support.v7.app.ActionBar actionbar;
private DrawerLayout drawer;
private ListView navlist;
private FragmentTransaction frmt;
private FragmentManager frm;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
drawer = (DrawerLayout)findViewById(R.id.drawer);
navlist = (ListView)findViewById(R.id.navlist);
ArrayList<String> navArr = new ArrayList<String>();
navArr.add("Home");
navArr.add("Playing List");
navArr.add("Manage List");
navArr.add("Logout");
navlist.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,navArr);
navlist.setAdapter(adapter);
navlist.setOnItemClickListener(this);
actbartoggle = new ActionBarDrawerToggle(this,drawer,R.string.opendrawer,R.string.closedrawer);
drawer.setDrawerListener(actbartoggle);
actionbar = getSupportActionBar();
actionbar.setDisplayShowHomeEnabled(true);
actionbar.setDisplayHomeAsUpEnabled(true);
frm = getFragmentManager();
loadDefFrag(0);
}
private void loadDefFrag(int i){
navlist.setItemChecked(i,true);
if(i==1){
MapFragment mapf = new MapFragment();
frmt = frm.beginTransaction();
frmt.replace(R.id.fragmentholder, mapf);
frmt.commit();
}else if (i==2){
Fragment2 fr2 = new Fragment2();
frmt = frm.beginTransaction();
frmt.replace(R.id.fragmentholder, fr2);
frmt.commit();
}
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
actbartoggle.syncState();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.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
if (id == R.id.action_settings) {
return true;
}else if (id == android.R.id.home){
if(drawer.isDrawerOpen(navlist)){
drawer.closeDrawer(navlist);
}else{
drawer.openDrawer(navlist);
}
}
return super.onOptionsItemSelected(item);
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
switch(position){
case 0:
break;
case 1:
loadDefFrag(position);
break;
case 2:
loadDefFrag(position);
break;
case 3:
break;
}
drawer.closeDrawer(navlist);
}
}
here you can see the mapactivity:
package com.example.matant.test;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import com.example.matant.test.R;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
public class MapFragment extends FragmentActivity implements OnMapReadyCallback {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_map);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap map) {
// Add a marker in Sydney, Australia, and move the camera.
LatLng sydney = new LatLng(-34, 151);
map.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
map.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}
}
main layout:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/drawer"
>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fragmentholder">
</FrameLayout>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/navlist"
android:background="#dedede"
android:layout_gravity="start">
</ListView>
</android.support.v4.widget.DrawerLayout>
map layout:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" tools:context="com.example.matant.test.MapFragment">
<!-- TODO: Update blank fragment layout -->
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/map"
tools:context=".MapsActivity"
android:name="com.google.android.gms.maps.SupportMapFragment" />
</FrameLayout>
You are trying to replace an Activity using FragmentManager. Only a Fragment can be used here.
Either start you MapFragment using startActivity() or extend MapFragment from a Fragment like this
public class MapFragment extends Fragment implements OnMapReadyCallback {
If you follow the second approach you will have to change few other lines in code too where you need context using getActivity()
I have a problem with passing a number from one fragment to another in the same activity , I got that number to Activity, but when I try to pass it to 2nd fragment it gives me null.
Any help is appreciated
Here is the code for the Passing and a bit more, there maybe typos as i wanted to put as little of code as I could
MainActivity
package com.example.design.ex;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import example.test.R;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.example.design.ex.fragments.ReceiptItemsFragment;
public class NewReceiptActivity extends SherlockFragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int num = 0;
Intent intent = getIntent();
int Broj = intent.getIntExtra("Num", num);
Bundle bundle=new Bundle();
bundle.putInt("Broj", Broj);
setContentView(R.layout.activity_test);
ReceiptItemsFragment frag = (ReceiptItemsFragment)
getSupportFragmentManager().findFragmentById(R.id.receipt);
frag.setArguments(bundle);
}
}
Fragment 1
package com.example.design.ex.fragments;
import example.test.R;
import java.util.ArrayList;
import java.util.List;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.GridView;
import com.actionbarsherlock.app.SherlockFragment;
public class CategoriesItemsFragment extends SherlockFragment {
int num = 0;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_categories_items,
container, false);
return view;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
init();
}
private void init() {
itemsGrid.setOnItemClickListener(new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> arg0, final View itemView, int
arg2, long arg3)
{
num = arg2 + 1;
Intent intent = new Intent(getActivity().getBaseContext(),NewReceiptActivity.class);
intent.putExtra("Num", num);
startActivity(new Intent(getActivity(), NewReceiptActivity.class));
getActivity().startActivity(intent);
}
});
}
}
Fragment 2
package example.design.ex.fragments;
import example.test.R;
import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.actionbarsherlock.app.SherlockFragment;
public class ReceiptItemsFragment extends SherlockFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setHasOptionsMenu(true);
Bundle arguments = getArguments();
if (arguments != null)
{
Log.d("ISnull","no!");
} else {
Log.d("ISnull","yes!");
}
int num=getArguments().getInt("Num");
return inflater.inflate(R.layout.fragment_receipt_items, container,
false);
}
Main Activity XML
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
android:orientation="horizontal" >
<fragment
android:id="#+id/titles"
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_weight="1.5"
class="example.ex.fragments.CategoriesItemsFragment" />
<LinearLayout
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#color/sun_flower" >
</LinearLayout>
<fragment
android:id="#+id/receipt"
android:name="example.ex.fragments.ReceiptItemsFragment"
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_weight="1"
class="example.ex.fragments.ReceiptItemsFragment" />
</LinearLayout>
Here is the Error
06-11 07:41:00.419: E/AndroidRuntime(2801): at
com.example.NewReceiptActivity.onCreate(NewReceiptActivity.java:60)
which is this line or the next if i put log (tried to get it to show me the id)
ReceiptItemsFragment frag = (ReceiptItemsFragment)
getSupportFragmentManager().findFragmentById(R.id.receipt);
Verify if frag in NewReceiptActivity is different null. Verify if Numt is 2.
Move the line in ReceiptItemsFragment:
int num=getArguments().getInt("Num"); //this should get number 2 from Frist Fragment but it gives null
from method onCreateView to onActivityCreated:
public void onActivityCreated (Bundle savedInstanceState) {
int num=getArguments().getInt("Num"); //this should get number 2 from Frist Fragment but it gives null
I think the problem is here :
ReceiptItemsFragment frag=new ReceiptItemsFragment(); //2nd fragment
frag.setArguments(bundle);
You're creating a new fragment but its not the one you've got in your layout.
try this instead :
setContentView(R.layout.activity_test); // Here is where that 2 fragments are Located
ReceiptItemsFragment frag = getFragmentManager().findFragmentById(...) //your fragment id
frag.setArguments(bundle);
so you don't create a new fragment but reference the one you've got in your layout.
Hope that helps.
You can create a subclass of Application and store the object there. Check this.
Or you can use static variables in the activity class.
I went on different approach using Interface on passing data,As explained here
https://stackoverflow.com/a/12311939/1393695
And got it working, I want to thank everybody here for the help.
The problem was that I was looking at fragments as they where activities.
I have two fragments, each fragment contains a view pager, where I currently am using this library in order to use different colored tabs for my view pager. Now I have an action bar action that when clicked basically leads to fragment2. But when I do that fragment1 is not removed and is on top of the fragment2 that the user just switched into, like this. Now, I tried to do what the answer said, and add the fragments programmatically, but that isn't possible (I think) since I'm using the custom PagerSlidingTabStrip. Now is there anyway to change fragments on the click of a button, while still using the custom library? Additionally, I'd just like to add that I'm somewhat new to Android.
Fragment1
import java.lang.reflect.Field;
import android.app.AlertDialog;
import android.app.FragmentTransaction;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.LayoutParams;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.RelativeLayout;
import com.actionbarsherlock.app.SherlockFragment;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.astuetz.PagerSlidingTabStrip;
import com.bernard.beaconportal.R.layout;
public class FragmentsView extends SherlockFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setHasOptionsMenu(true);
View view = inflater.inflate(R.layout.viewpager_schedule, container, false);
ViewPager pager = (ViewPager) view.findViewById(R.id.viewPager1);
pager.setAdapter(new ViewPagerAdapterScheduleView(getChildFragmentManager()));
PagerSlidingTabStrip tabs = (PagerSlidingTabStrip) view.findViewById(R.id.pagerTabStrip1);
tabs.setViewPager(pager);
return view;
}
#Override
public void onDetach() {
super.onDetach();
try {
Field childFragmentManager = Fragment.class
.getDeclaredField("mChildFragmentManager");
childFragmentManager.setAccessible(true);
childFragmentManager.set(this, null);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
#Override
public void onCreateOptionsMenu(
Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.android_edit, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// handle item selection
switch (item.getItemId()) {
case R.id.edit:
alert_dialog();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void alert_dialog() {
{
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Edit Bands")
.setItems(R.array.edit_mode, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Fragment newFragment = new FragmentsLinked();
android.support.v4.app.FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.view_container, newFragment);
transaction.addToBackStack(null);
transaction.commit();
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
}
}
}
Fragment 2
import java.lang.reflect.Field;
import com.actionbarsherlock.app.SherlockFragment;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.astuetz.PagerSlidingTabStrip;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class FragmentsLinked extends SherlockFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setHasOptionsMenu(true);
View view = inflater.inflate(R.layout.viewpager_schedule_linked, container, false);
// Locate the ViewPager in viewpager_main.xml
ViewPager pager = (ViewPager) view.findViewById(R.id.viewPager2);
// Set the ViewPagerAdapter into ViewPager
pager.setAdapter(new ViewPagerAdapterScheduleLinked(getChildFragmentManager()));
return view;
}
#Override
public void onDetach() {
super.onDetach();
try {
Field childFragmentManager = Fragment.class
.getDeclaredField("mChildFragmentManager");
childFragmentManager.setAccessible(true);
childFragmentManager.set(this, null);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
#Override
public void onCreateOptionsMenu(
Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.android_apply, menu);
inflater.inflate(R.menu.android_help, menu);
}
}
xml used for Fragment 1
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/view_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.astuetz.PagerSlidingTabStrip
android:id="#+id/pagerTabStrip1"
android:layout_width="match_parent"
android:layout_height="48dip"
app:pstsIndicatorColor="#3498DB"
app:pstsUnderlineColor="#3498DB"
/>
<android.support.v4.view.ViewPager
android:id="#+id/viewPager1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/pagerTabStrip1" />
</RelativeLayout>
xml used for fragment 2
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="#+id/linked_container"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<android.support.v4.view.ViewPager
android:id="#+id/viewPager2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="50dp"/>
<View
android:id="#+id/View2"
android:layout_width="fill_parent"
android:layout_height="8dp"
android:layout_alignBottom="#+id/textView2"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:background="#3498DB" />
<TextView
android:id="#+id/textView2"
android:layout_width="match_parent"
android:layout_height="48dip"
android:layout_alignParentTop="true"
android:gravity="center"
android:text="Edits Will be Applied to All of the Same Band"
android:textAlignment="gravity"
android:textAppearance="?android:attr/textAppearanceSmall" />
</RelativeLayout>
If you have any questions or I didn't explain something well enough or something like that just say something and I'll add it or explain it better
You cannot remove fragment that is declared in xml layout file. remove your fragment from xml and add it from code (ie in activity's onCreate()) and you will be then able to remove it later.